-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #4880: always instantiate prefix tvar #4897
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
Conversation
tvar => !(ctx.typerState.constraint.entry(tvar.origin) eq tvar.origin.underlying), | ||
tvar => | ||
!(ctx.typerState.constraint.entry(tvar.origin) eq tvar.origin.underlying) || | ||
(tvar `eq` removeThisType.prefixTVar), |
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.
Why a backquoted eq
here (or elsewhere for that matter)?
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.
I should use it in both cases, just following a coding style experimented by Martin in Dotty.
So I've pushed a couple of examples, and a patch for them I'm not happy about. Below's why. Enabling sealed abstract class AbstractFile
class PlainFile(path: String) extends AbstractFile
class VirtualFile(name: String) extends AbstractFile
abstract class ZipArchive(path: String) extends AbstractFile {
sealed abstract class Entry(name: String) extends VirtualFile(name)
class DirEntry(path: String) extends Entry(path)
}
object Test {
def foo(file: AbstractFile) = file match {
case a: PlainFile =>
case b: ZipArchive =>
case c1: ZipArchive#Entry => // marked as unreachable, incorrectly!
case c1: ZipArchive#DirEntry => // accepted, correctly, even tho this is the instance of ZipArchive#Entry
case c: VirtualFile =>
}
} AnalysisOnce instantiate finds that I can add a special case for I suspect we should produce something else instead of
|
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.
A better way of handling the new examples is needed.
Also, have you already tried using EDIT: forcing Why is maximizing correct? The difference between this testcase and others seems the following. We're replacing EDIT2: looking into the failure, I suspect I should only maximize the prefix type variable, and not even force the other ones. I'll give this a try. |
@Blaisorblade The following change works for me locally: +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala
@@ -292,7 +292,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
private val nullType = ConstantType(Constant(null))
private val nullSpace = Typ(nullType)
override def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type) = {
val and = AndType(tp1, tp2)
// Precondition: !(tp1 <:< tp2) && !(tp2 <:< tp1)
// Then, no leaf of the and-type tree `and` is a subtype of `and`.
@@ -689,7 +689,8 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
tvar =>
!(ctx.typerState.constraint.entry(tvar.origin) `eq` tvar.origin.underlying) ||
(tvar `eq` removeThisType.prefixTVar),
- minimizeAll = false
+ minimizeAll = false,
+ allowBottom = false
)
--- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -115,7 +115,7 @@ object Inferencing {
val minimize =
force.minimizeAll ||
variance >= 0 && !(
- force == ForceDegree.noBottom &&
+ !force.allowBottom &&
defn.isBottomType(ctx.typeComparer.approximation(tvar.origin, fromBelow = true)))
if (minimize) instantiate(tvar, fromBelow = true)
else toMaximize = true
@@ -466,9 +466,9 @@ trait Inferencing { this: Typer =>
/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
@sharable object ForceDegree {
- class Value(val appliesTo: TypeVar => Boolean, val minimizeAll: Boolean)
+ class Value(val appliesTo: TypeVar => Boolean, val minimizeAll: Boolean, val allowBottom: Boolean = true)
val none = new Value(_ => false, minimizeAll = false)
val all = new Value(_ => true, minimizeAll = false)
- val noBottom = new Value(_ => true, minimizeAll = false)
+ val noBottom = new Value(_ => true, minimizeAll = false, allowBottom = false)
} If you play with reachability, you may want to incorperate the changes in #4869. |
Feel free to push your change. |
LGTM! This looks reasonable to me, and I'm pretty confident the changes to Plus, my idea about |
Fix #4880: always instantiate prefix tvar