Skip to content

Commit 0f7a02e

Browse files
committed
Fix #4987: Avoid widening instantiations to module classes
When instantiating a type variable, avoid widening to a module class reference. Widen to the source module instead.
1 parent e87397a commit 0f7a02e

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Types._
66
import Contexts._
77
import Symbols._
88
import Decorators._
9+
import Flags._
910
import config.Config
1011
import config.Printers.{constr, typr}
1112
import dotty.tools.dotc.reporting.trace
@@ -298,6 +299,9 @@ trait ConstraintHandling[AbstractContext] {
298299
* of all common base types, provied the result is a subtype of `bound`.
299300
*
300301
* Don't do these widenings if `bound` is a subtype of `scala.Singleton`.
302+
* Also, if the result of these widenings is a TypeRef to a module class,
303+
* and this type ref is different from `inst`, replace by a TermRef to
304+
* its source module instead.
301305
*
302306
* At this point we also drop the @Repeated annotation to avoid inferring type arguments with it,
303307
* as those could leak the annotation to users (see run/inferred-repeated-result).
@@ -314,7 +318,11 @@ trait ConstraintHandling[AbstractContext] {
314318
val wideInst =
315319
if (isSubTypeWhenFrozen(bound, defn.SingletonType)) inst
316320
else widenOr(widenSingle(inst))
317-
wideInst.dropRepeatedAnnot
321+
wideInst match
322+
case wideInst: TypeRef if wideInst.symbol.is(Module) =>
323+
TermRef(wideInst.prefix, wideInst.symbol.sourceModule)
324+
case _ =>
325+
wideInst.dropRepeatedAnnot
318326
}
319327

320328
/** The instance type of `param` in the current constraint (which contains `param`).

tests/neg/module-class-name.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
-- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:12:14 -------------------------------------------------
1212
12 | val z1: C = z // error: Found: object Test.C
1313
| ^
14-
| Found: object Test.C
14+
| Found: Test.C.type
1515
| Required: Test.C
1616
-- [E007] Type Mismatch Error: tests/neg/module-class-name.scala:13:16 -------------------------------------------------
1717
13 | val z2: Int = z // error: Found: object Test.C
1818
| ^
19-
| Found: object Test.C
19+
| Found: Test.C.type
2020
| Required: Int
2121
-- [E008] Member Not Found Error: tests/neg/module-class-name.scala:15:4 -----------------------------------------------
2222
15 | C.foo // error: value foo is not a member of object Test.C

tests/neg/module-class-name.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ object Test {
44

55
def f[T](x: T): T = x
66

7-
val x: C = C // error: Found: Test.C.type
7+
val x: C = C // error
88

9-
val y: C = f(C) // error: Found: Test.C.type
9+
val y: C = f(C) // error
1010

1111
def z = f(C)
12-
val z1: C = z // error: Found: object Test.C
13-
val z2: Int = z // error: Found: object Test.C
12+
val z1: C = z // error
13+
val z2: Int = z // error
1414

1515
C.foo // error: value foo is not a member of object Test.C
1616
}

tests/pos/i4987.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
object Foo {
2+
3+
class Expr[T]
4+
5+
abstract class Liftable[T] {
6+
def toExpr(x: T): Expr[T]
7+
}
8+
9+
implicit class LiftExprOps[T](val x: T) extends AnyVal {
10+
def toExpr(implicit ev: Liftable[T]): Expr[T] = ev.toExpr(x)
11+
}
12+
13+
implicit def NilIsLiftable: Liftable[Nil.type] = ???
14+
15+
Nil.toExpr(NilIsLiftable)
16+
(Nil.toExpr: Expr[Nil.type])
17+
Nil.toExpr
18+
}

0 commit comments

Comments
 (0)