Skip to content

Commit 5477afa

Browse files
committed
Fix #3083: Check that all named parts of locally inferred types are defined.
1 parent dc1bf9f commit 5477afa

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
@@ -722,6 +722,22 @@ trait Checking {
722722
checkNoForwardDependencies(vparams1)
723723
case Nil =>
724724
}
725+
726+
/** Check that all named type that form part of this type have a denotation.
727+
* Called on inferred (result) types of ValDefs and DefDefs.
728+
* This could fail for types where the member was originally available as part
729+
* of the self type, yet is no longer visible once the `this` has been replaced
730+
* by some other prefix. See neg/i3083.scala
731+
*/
732+
def checkMembersOK(tp: Type, pos: Position)(implicit ctx: Context): Type = {
733+
val check: Type => Unit = {
734+
case ref: NamedType if !ref.denot.exists =>
735+
ctx.error(em"$ref is not defined in inferred type $tp", pos)
736+
case _ =>
737+
}
738+
tp.foreachPart(check, stopAtStatic = true)
739+
tp
740+
}
725741
}
726742

727743
trait NoChecking extends Checking {
@@ -741,4 +757,5 @@ trait NoChecking extends Checking {
741757
override def checkTraitInheritance(parentSym: Symbol, cls: ClassSymbol, pos: Position)(implicit ctx: Context) = ()
742758
override def checkCaseInheritance(parentSym: Symbol, caseCls: ClassSymbol, pos: Position)(implicit ctx: Context) = ()
743759
override def checkNoForwardDependencies(vparams: List[ValDef])(implicit ctx: Context): Unit = ()
760+
override def checkMembersOK(tp: Type, pos: Position)(implicit ctx: Context): Type = tp
744761
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ class Namer { typer: Typer =>
10981098
case _: untpd.DerivedTypeTree =>
10991099
WildcardType
11001100
case TypeTree() =>
1101-
inferredType
1101+
checkMembersOK(inferredType, mdef.pos)
11021102
case DependentTypeTree(tpFun) =>
11031103
tpFun(paramss.head)
11041104
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)