Skip to content

Commit 5b34415

Browse files
committed
Don't unsoundly maximise types to Any/Nothing
Also fix the span of the new pattern bound symbol, which was failing pickling tests.
1 parent 9be5a34 commit 5b34415

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ trait Applications extends Compatibility {
13411341
// Constraining only fails if the pattern cannot possibly match,
13421342
// but useless pattern checks detect more such cases, so we simply rely on them instead.
13431343
withMode(Mode.GadtConstraintInference)(TypeComparer.constrainPatternType(unapplyArgType, selType))
1344-
val patternBound = maximizeType(unapplyArgType, tree.span)
1344+
val patternBound = maximizeType(unapplyArgType, unapplyFn.span.endPos)
13451345
if (patternBound.nonEmpty) unapplyFn = addBinders(unapplyFn, patternBound)
13461346
unapp.println(i"case 2 $unapplyArgType ${ctx.typerState.constraint}")
13471347
unapplyArgType

compiler/src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,8 @@ object Inferencing {
405405
val patternBindings = new mutable.ListBuffer[(Symbol, TypeParamRef)]
406406
vs foreachBinding { (tvar, v) =>
407407
if !tvar.isInstantiated then
408-
if (v == 1) tvar.instantiate(fromBelow = false)
409-
else if (v == -1) tvar.instantiate(fromBelow = true)
408+
if (v == 1 && tvar.hasUpperBound) tvar.instantiate(fromBelow = false)
409+
else if (v == -1 && tvar.hasLowerBound) tvar.instantiate(fromBelow = true)
410410
else {
411411
val bounds = TypeComparer.fullBounds(tvar.origin)
412412
if bounds.hi <:< bounds.lo || bounds.hi.classSymbol.is(Final) then

tests/neg/i14983.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sealed trait Tree[+A]
2+
final case class Leaf[+B](v: B) extends Tree[B]
3+
final case class Node[+C](xs: List[C]) extends Tree[List[C]]
4+
5+
object Test:
6+
def meth[X](tree: Tree[X]): X = tree match
7+
case Leaf(v) => v
8+
case Node(x) => List("boom") // error
9+
10+
def main(args: Array[String]): Unit =
11+
val tree = Node(List(42))
12+
val res = meth(tree)
13+
assert(res.head == 42) // was: ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer

tests/run/i14983.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sealed trait Tree[+A]
2+
final case class Leaf[+B](v: B) extends Tree[B]
3+
final case class Node[+C](xs: List[C]) extends Tree[List[C]]
4+
5+
object Test:
6+
def meth[X](tree: Tree[X]): X = tree match
7+
case Leaf(v) => v
8+
case Node(x) => x // ok
9+
10+
def main(args: Array[String]): Unit =
11+
val tree = Node(List(42))
12+
val res = meth(tree)
13+
assert(res.head == 42) // ok

0 commit comments

Comments
 (0)