Skip to content

Fix #5044: guard against forward references in the TypeTree of New trees #5178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1010,9 +1010,14 @@ class RefChecks extends MiniPhase { thisPhase =>
}

override def transformNew(tree: New)(implicit ctx: Context) = {
val sym = tree.tpe.typeSymbol
val tpe = tree.tpe
val sym = tpe.typeSymbol
checkUndesiredProperties(sym, tree.pos)
currentLevel.enterReference(sym, tree.pos)
tpe.dealias.foreachPart {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is dealias required?

Copy link
Contributor Author

@Jasper-M Jasper-M Sep 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without it the second test still fails (crashes). If you would dealias a bit sooner I think def foo = { type T = Foo; val a = new T; class Foo } would also emit an error, like in scalac.

case TermRef(_, s: Symbol) => currentLevel.enterReference(s, tree.pos)
case _ =>
}
tree
}
}
Expand Down Expand Up @@ -1643,4 +1648,3 @@ class RefChecks extends MiniPhase { thisPhase =>
}
}
*/

26 changes: 26 additions & 0 deletions tests/neg/i5044.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class I0 {
class I1
def test0 = {
val x = new y.I1 // error: `y` is a forward reference extending over the definition of `x`
val y = new I0
}

def test1 = {
type T = y.I1
val x = new T // error: `y` is a forward reference extending over the definition of `x`
val y = new I0
}

class I2[T1, T2]
def test2 = {
type A[T] = y.I2[T, String]
val x = new A[Int] // error: `y` is a forward reference extending over the definition of `x`
val y = new I0
}

def test3 = {
val x = new T // error: `T` is a forward reference extending over the definition of `x`
val y = new I0
type T = y.I1
}
}