Skip to content

Commit 3c1bc32

Browse files
authored
Merge pull request #3386 from dotty-staging/fix-#3352
Fix #3352: Avoid widening method TermRefs in compatibility checks
2 parents 3eff831 + 0feef95 commit 3c1bc32

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ object ProtoTypes {
101101
val mbr = if (privateOK) tp1.member(name) else tp1.nonPrivateMember(name)
102102
def qualifies(m: SingleDenotation) =
103103
memberProto.isRef(defn.UnitClass) ||
104-
compat.normalizedCompatible(m.info, memberProto)
104+
compat.normalizedCompatible(NamedType(tp1, name, m), memberProto)
105+
// Note: can't use `m.info` here because if `m` is a method, `m.info`
106+
// loses knowledge about `m`'s default arguments.
105107
mbr match { // hasAltWith inlined for performance
106108
case mbr: SingleDenotation => mbr.exists && qualifies(mbr)
107109
case _ => mbr hasAltWith qualifies
@@ -431,6 +433,7 @@ object ProtoTypes {
431433
* - skips implicit parameters of methods and functions;
432434
* if result type depends on implicit parameter, replace with fresh type dependent parameter.
433435
* - converts non-dependent method types to the corresponding function types
436+
* unless the expected type is an ApplyingProto or IgnoredProto.
434437
* - dereferences parameterless method types
435438
* - dereferences nullary method types provided the corresponding function type
436439
* is not a subtype of the expected type.
@@ -451,8 +454,11 @@ object ProtoTypes {
451454
else {
452455
val rt = normalize(mt.resultType, pt)
453456
pt match {
454-
case pt: IgnoredProto => mt
455-
case pt: ApplyingProto => mt.derivedLambdaType(mt.paramNames, mt.paramInfos, rt)
457+
case pt: IgnoredProto =>
458+
tp
459+
case pt: ApplyingProto =>
460+
if (rt eq mt.resultType) tp
461+
else mt.derivedLambdaType(mt.paramNames, mt.paramInfos, rt)
456462
case _ =>
457463
val ft = defn.FunctionOf(mt.paramInfos, rt)
458464
if (mt.paramInfos.nonEmpty || ft <:< pt) ft else rt

tests/pending/neg/i3253.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Test.test
2+
3+
object Test {
4+
def test = " " * 10
5+
}

tests/pos/i3352.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Test {
2+
class Foo {
3+
def bar(x: String): Int = 1
4+
}
5+
6+
implicit class FooOps(foo: Foo) {
7+
def bar(x: Int, y: Int = 2): Int = 2 // compiles with no default argument
8+
}
9+
10+
def test(foo: Foo): Unit = {
11+
foo.bar(1)
12+
}
13+
}

0 commit comments

Comments
 (0)