Skip to content

Fix #4060 by marking ghost symbols as unstable #4071

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
Mar 9, 2018
Merged
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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
@@ -600,7 +600,7 @@ object SymDenotations {

/** Is this a denotation of a stable term (or an arbitrary type)? */
final def isStable(implicit ctx: Context) =
isType || is(Stable) || !(is(UnstableValue) || info.isInstanceOf[ExprType])
isType || !is(Erased) && (is(Stable) || !(is(UnstableValue) || info.isInstanceOf[ExprType]))

/** Is this a "real" method? A real method is a method which is:
* - not an accessor
25 changes: 25 additions & 0 deletions tests/neg/erased-24.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Could become a run test if we had totality checking for erased arguments

object Test {

def main(args: Array[String]): Unit = {
println(fun(new Bar))
}

def fun(erased foo: Foo): foo.X = { // error
null.asInstanceOf[foo.X] // error
}

def fun2(erased foo: Foo)(erased bar: foo.B): bar.X = { // error // error
null.asInstanceOf[bar.X] // error
}
}

class Foo {
type X
type B <: Bar
}

class Bar extends Foo {
type X = String
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Could become a neg test if we had totality checking for erased arguments

object Test {

fun1(new Bar)
fun2(new Bar)
fun3(new Bar)

def fun1[F >: Bar <: Foo](erased f: F): f.X = null.asInstanceOf[f.X]
def fun2[F >: Bar <: Foo](erased f: F)(erased bar: f.B): f.B = null.asInstanceOf[f.B]
def fun3[F >: Bar <: Foo](erased f: F)(erased b: f.B): b.X = null.asInstanceOf[b.X]
def fun1[F >: Bar <: Foo](erased f: F): f.X = null.asInstanceOf[f.X] // error // error
def fun2[F >: Bar <: Foo](erased f: F)(erased bar: f.B): f.B = null.asInstanceOf[f.B] // error // error // error
def fun3[F >: Bar <: Foo](erased f: F)(erased b: f.B): b.X = null.asInstanceOf[b.X] // error // error // error
}

class Foo {
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Could become a neg test if we had totality checking for erased arguments

object Test {

type F >: Bar <: Foo

class A(erased val f: F) {
type F1 <: f.X
type F2[Z <: f.X]
type F1 <: f.X // error
type F2[Z <: f.X] // error
}

}
22 changes: 22 additions & 0 deletions tests/neg/i4060.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class X { type R }
class T(erased val a: X)(val value: a.R) // error

object App {
def coerce[U, V](u: U): V = {
trait X { type R >: U }
trait Y { type R = V }

class T[A <: X](erased val a: A)(val value: a.R) // error

object O { lazy val x : Y & X = ??? } // warning

val a = new T[Y & X](O.x)(u)
a.value
}

def main(args: Array[String]): Unit = {
val x: Int = coerce[String, Int]("a")
println(x + 1)

}
}
1 change: 0 additions & 1 deletion tests/run/erased-24.check

This file was deleted.

23 changes: 0 additions & 23 deletions tests/run/erased-24.scala

This file was deleted.