-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix #4031: Check arguments of dependent methods for realizability #4036
Changes from all commits
63535f0
db552da
bd55b74
7659c11
9125f58
d1e5d40
ed51433
6e21f42
61d26b9
37b8720
9db4ab6
8ac0c6f
37e1a01
23e6beb
ad1167c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -302,7 +302,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
thirdTry | ||
case tp1: TypeParamRef => | ||
def flagNothingBound = { | ||
if (!frozenConstraint && tp2.isRef(defn.NothingClass) && state.isGlobalCommittable) { | ||
if (!frozenConstraint && tp2.isRef(NothingClass) && state.isGlobalCommittable) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. XXX This commit looks stale after the merge of kind-polymorphism, almost just a refactoring is left... |
||
def msg = s"!!! instantiated to Nothing: $tp1, constraint = ${constraint.show}" | ||
if (Config.failOnInstantiationToNothing) assert(false, msg) | ||
else ctx.log(msg) | ||
|
@@ -384,8 +384,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
if (cls2.isClass) { | ||
if (cls2.typeParams.isEmpty) { | ||
if (cls2 eq AnyKindClass) return true | ||
if (tp1.isRef(defn.NothingClass)) return true | ||
if (tp1.isRef(NothingClass)) return true | ||
if (tp1.isLambdaSub) return false | ||
if (cls2 eq AnyClass) return true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actual behavior change. But EDIT: This is still needed, otherwise we get
|
||
// Note: We would like to replace this by `if (tp1.hasHigherKind)` | ||
// but right now we cannot since some parts of the standard library rely on the | ||
// idiom that e.g. `List <: Any`. We have to bootstrap without scalac first. | ||
|
@@ -399,7 +400,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
val base = tp1.baseType(cls2) | ||
if (base.typeSymbol == cls2) return true | ||
} | ||
else if (tp1.isLambdaSub && !tp1.isRef(defn.AnyKindClass)) | ||
else if (tp1.isLambdaSub && !tp1.isRef(AnyKindClass)) | ||
return recur(tp1, EtaExpansion(cls2.typeRef)) | ||
} | ||
fourthTry | ||
|
@@ -1296,7 +1297,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
// at run time. It would not work to replace that with `Nothing`. | ||
// However, maybe we can still apply the replacement to | ||
// types which are not explicitly written. | ||
defn.NothingType | ||
NothingType | ||
case _ => andType(tp1, tp2) | ||
} | ||
case _ => andType(tp1, tp2) | ||
|
@@ -1307,8 +1308,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
} | ||
|
||
/** The greatest lower bound of a list types */ | ||
final def glb(tps: List[Type]): Type = | ||
((defn.AnyType: Type) /: tps)(glb) | ||
final def glb(tps: List[Type]): Type = ((AnyType: Type) /: tps)(glb) | ||
|
||
/** The least upper bound of two types | ||
* @param canConstrain If true, new constraints might be added to simplify the lub. | ||
|
@@ -1338,7 +1338,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
|
||
/** The least upper bound of a list of types */ | ||
final def lub(tps: List[Type]): Type = | ||
((defn.NothingType: Type) /: tps)(lub(_,_, canConstrain = false)) | ||
((NothingType: Type) /: tps)(lub(_,_, canConstrain = false)) | ||
|
||
/** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using | ||
* the following strategies: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
object App { | ||
trait A { type L >: Any} | ||
def upcast(a: A, x: Any): a.L = x | ||
lazy val p: A { type L <: Nothing } = p | ||
val q = new A { type L = Any } | ||
def coerce2(x: Any): Int = upcast(p, x): p.L // error: not a legal path | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
object App { | ||
trait A { type L >: Any} | ||
def upcast(a: A, x: Any): a.L = x | ||
lazy val p: A { type L <: Nothing } = p | ||
val q = new A { type L = Any } | ||
def coerce(x: Any): Int = upcast(p, x) // error: not a legal path | ||
|
||
def compare(x: A, y: x.L) = assert(x == y) | ||
def compare2(x: A)(y: x.type) = assert(x == y) | ||
|
||
|
||
def main(args: Array[String]): Unit = { | ||
println(coerce("Uh oh!")) | ||
compare(p, p) // error: not a legal path | ||
compare2(p)(p) // error: not a legal path | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,14 +12,21 @@ class Test { | |
|
||
class Client extends o.Inner // old-error // old-error | ||
|
||
def xToString(x: o.X): String = x // old-error | ||
def xToString(x: o.X): String = x // error | ||
|
||
def intToString(i: Int): String = xToString(i) | ||
} | ||
object Test2 { | ||
|
||
import Test.o._ // error | ||
object Test2 { | ||
trait A { | ||
type X = String | ||
} | ||
trait B { | ||
type X = Int | ||
} | ||
lazy val o: A & B = ??? | ||
|
||
def xToString(x: X): String = x | ||
def xToString(x: o.X): String = x // error | ||
|
||
def intToString(i: Int): String = xToString(i) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test did not break. It's masked by the other failures. Taken alone, it would be reported later. |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering why the prefix need not be checked here... EDIT: sorry remembered it, same reason as
patchRealizability
.