-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #2104: Instantiate unapply result type variables #3905
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
Changes from all commits
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 |
---|---|---|
|
@@ -811,8 +811,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { | |
.expect { (ictx, messages) => | ||
implicit val ctx: Context = ictx | ||
|
||
assertMessageCount(1, messages) | ||
val AnonymousFunctionMissingParamType(param, args, _, pt) :: Nil = messages | ||
val AnonymousFunctionMissingParamType(param, args, _, pt) = messages.last | ||
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. This is very mysterious: If I copy out the code of the test I always see 4 messages - one "missing param type", followed by 3 "cannot resolve overloading". that happens no matter whether I am on master or this PR. On master the ErrorMessageTests succeeded, i.e. they report only one failure instead of the 4 we see in the terminal. On this PR this is no longer the case. Instead, it reports all 4 tests in I have no idea what could be the cause of these effects. 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 reporter for the error message tests is mixed in with 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 problem is that in master, there is no overlap in positions of the 4 errors, and this PR doesn't change positions of the errors, and the order doesn't change either. 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 root cause is the following line in val hasUnreportedErrors = ctx.typerState.reporter match {
case r: StoreReporter if r.hasErrors => true
case _ => false
}
// ....
if (!hasUnreportedErrors)
vs foreachBinding { (tvar, v) =>
if (v != 0 && ctx.typerState.constraint.contains(tvar)) {
// previous interpolations could have already instantiated `tvar`
// through unification, that's why we have to check again whether `tvar`
// is contained in the current constraint.
typr.println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}")
ensureConstrained()
tvar.instantiate(fromBelow = v == 1)
}
}
In normal command line compilation, we are using In the testing, we are using After the change in this PR, we are triggering early instantiation even for 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. Thanks for clearing this up, Fengyung! 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. Do we need to change or document |
||
assertEquals("x$1", param.show) | ||
assertEquals(s"List(ValDef(${param.show},TypeTree,EmptyTree))", args.toString) | ||
assertEquals("?", pt.show) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
case class Pair[A, B](_1: A, _2: B) | ||
|
||
trait Cons[+H, +T] | ||
|
||
object Cons { | ||
def apply[H, T](h: H, t: T): Cons[H, T] = ??? | ||
def unapply[H, T](t: Cons[H, T]): Option[Pair[H, T]] = ??? | ||
} | ||
|
||
|
||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
Cons(Option(1), None) match { | ||
case Cons(Some(i), None) => | ||
i: Int // error: found: Any(i), requires: Int | ||
assert(i == 1) | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.
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.
From the diagnosis, the type parameter could be further constrained by patterns, thus I'm not sure if this change is the right fix. However, given that there is no test case invalidated this change, maybe we can accept the fix for now.
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.
Yes, I think it is analogous to fully instantiating the match scrutinee. In pattern matching all information flows from the scrutinee via the expected type to the pattern, never the other way round.