diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index d9c7a94eead6..62c60fbf93c0 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -6,6 +6,7 @@ import Types._ import Contexts._ import Symbols._ import Decorators._ +import Flags._ import config.Config import config.Printers.{constr, typr} import dotty.tools.dotc.reporting.trace @@ -298,6 +299,9 @@ trait ConstraintHandling[AbstractContext] { * of all common base types, provied the result is a subtype of `bound`. * * Don't do these widenings if `bound` is a subtype of `scala.Singleton`. + * Also, if the result of these widenings is a TypeRef to a module class, + * and this type ref is different from `inst`, replace by a TermRef to + * its source module instead. * * At this point we also drop the @Repeated annotation to avoid inferring type arguments with it, * as those could leak the annotation to users (see run/inferred-repeated-result). @@ -314,7 +318,11 @@ trait ConstraintHandling[AbstractContext] { val wideInst = if (isSubTypeWhenFrozen(bound, defn.SingletonType)) inst else widenOr(widenSingle(inst)) - wideInst.dropRepeatedAnnot + wideInst match + case wideInst: TypeRef if wideInst.symbol.is(Module) => + TermRef(wideInst.prefix, wideInst.symbol.sourceModule) + case _ => + wideInst.dropRepeatedAnnot } /** The instance type of `param` in the current constraint (which contains `param`). diff --git a/tests/neg/module-class-name.check b/tests/neg/module-class-name.check index 37c511149638..a46c5382e65c 100644 --- a/tests/neg/module-class-name.check +++ b/tests/neg/module-class-name.check @@ -1,22 +1,22 @@ -- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:7:13 -------------------------------------------------- -7 | val x: C = C // error: Found: Test.C.type +7 | val x: C = C // error | ^ | Found: Test.C.type | Required: Test.C -- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:9:15 -------------------------------------------------- -9 | val y: C = f(C) // error: Found: Test.C.type +9 | val y: C = f(C) // error | ^ | Found: Test.C.type | Required: Test.C -- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:12:14 ------------------------------------------------- -12 | val z1: C = z // error: Found: object Test.C +12 | val z1: C = z // error | ^ - | Found: object Test.C + | Found: Test.C.type | Required: Test.C -- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:13:16 ------------------------------------------------- -13 | val z2: Int = z // error: Found: object Test.C +13 | val z2: Int = z // error | ^ - | Found: object Test.C + | Found: Test.C.type | Required: Int -- [E008] Member Not Found Error: tests/neg/module-class-name.scala:15:4 ----------------------------------------------- 15 | C.foo // error: value foo is not a member of object Test.C diff --git a/tests/neg/module-class-name.scala b/tests/neg/module-class-name.scala index e4bf6c0f4e98..07bb69fb402e 100644 --- a/tests/neg/module-class-name.scala +++ b/tests/neg/module-class-name.scala @@ -4,13 +4,13 @@ object Test { def f[T](x: T): T = x - val x: C = C // error: Found: Test.C.type + val x: C = C // error - val y: C = f(C) // error: Found: Test.C.type + val y: C = f(C) // error def z = f(C) - val z1: C = z // error: Found: object Test.C - val z2: Int = z // error: Found: object Test.C + val z1: C = z // error + val z2: Int = z // error C.foo // error: value foo is not a member of object Test.C } diff --git a/tests/pos/i4987.scala b/tests/pos/i4987.scala new file mode 100644 index 000000000000..e251c4091697 --- /dev/null +++ b/tests/pos/i4987.scala @@ -0,0 +1,18 @@ +object Foo { + + class Expr[T] + + abstract class Liftable[T] { + def toExpr(x: T): Expr[T] + } + + implicit class LiftExprOps[T](val x: T) extends AnyVal { + def toExpr(implicit ev: Liftable[T]): Expr[T] = ev.toExpr(x) + } + + implicit def NilIsLiftable: Liftable[Nil.type] = ??? + + Nil.toExpr(NilIsLiftable) + (Nil.toExpr: Expr[Nil.type]) + Nil.toExpr +} \ No newline at end of file