Skip to content

Commit 1cfa018

Browse files
committed
Fix #3083: Check that all named parts of locally inferred types are defined.
1 parent 576f6c6 commit 1cfa018

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,22 @@ trait Checking {
719719
checkNoForwardDependencies(vparams1)
720720
case Nil =>
721721
}
722+
723+
/** Check that all named type that form part of this type have a denotation.
724+
* Called on inferred (result) types of ValDefs and DefDefs.
725+
* This could fail for types where the member was originally available as part
726+
* of the self type, yet is no longer visible once the `this` has been replaced
727+
* by some other prefix. See neg/i3083.scala
728+
*/
729+
def checkMembersOK(tp: Type, pos: Position)(implicit ctx: Context): Type = {
730+
val check: Type => Unit = {
731+
case ref: NamedType if !ref.denot.exists =>
732+
ctx.error(em"$ref is not defined in inferred type $tp", pos)
733+
case _ =>
734+
}
735+
tp.foreachPart(check, stopAtStatic = true)
736+
tp
737+
}
722738
}
723739

724740
trait NoChecking extends Checking {
@@ -738,4 +754,5 @@ trait NoChecking extends Checking {
738754
override def checkTraitInheritance(parentSym: Symbol, cls: ClassSymbol, pos: Position)(implicit ctx: Context) = ()
739755
override def checkCaseInheritance(parentSym: Symbol, caseCls: ClassSymbol, pos: Position)(implicit ctx: Context) = ()
740756
override def checkNoForwardDependencies(vparams: List[ValDef])(implicit ctx: Context): Unit = ()
757+
override def checkMembersOK(tp: Type, pos: Position)(implicit ctx: Context): Type = tp
741758
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ class Namer { typer: Typer =>
11031103
case _: untpd.DerivedTypeTree =>
11041104
WildcardType
11051105
case TypeTree() =>
1106-
inferredType
1106+
checkMembersOK(inferredType, mdef.pos)
11071107
case DependentTypeTree(tpFun) =>
11081108
tpFun(paramss.head)
11091109
case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) =>

tests/neg/i3083.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
object Main {
2+
3+
trait Literal {
4+
type F[T]
5+
def num(i: Int): F[Int]
6+
}
7+
8+
trait Addition { self: Literal =>
9+
def add(l: F[Int], r: F[Int]): F[Int]
10+
}
11+
12+
def expression(adder: Addition) = {
13+
import adder._
14+
add(num(1), num(2)) // error // error
15+
}
16+
}
17+
18+
object Minimized {
19+
trait Literal {
20+
type F[T]
21+
}
22+
23+
trait Addition { self: Literal =>
24+
def foo: F[Int]
25+
}
26+
27+
object Main {
28+
def expression(adder: Addition) = { // error (?)
29+
adder.foo
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)