Skip to content

Commit 311e5ce

Browse files
committed
Fix multiversal equality checks for pattern matching
Equality checks against constants in patterns were usually suppressed since they were only issued if the GADT constrainer return false. We now drop this as a condition. This uncovered a missing position error, where we did a resolveOverloading when unpickling some Scala 2 code in Pattern mode. The missing position was the tree in the equality check, which is not surprising since was an annotation argument. The fix here was to make sure that we do overloading resolution only in expression mode.
1 parent b22331e commit 311e5ce

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,9 @@ object Trees {
15941594

15951595
def resolveConstructor(atp: Type, args: List[Tree])(using Context): tpd.Tree = {
15961596
val targs = atp.argTypes
1597-
applyOverloaded(tpd.New(atp.typeConstructor), nme.CONSTRUCTOR, args, targs, atp)
1597+
withoutMode(Mode.PatternOrTypeBits) {
1598+
applyOverloaded(tpd.New(atp.typeConstructor), nme.CONSTRUCTOR, args, targs, atp)
1599+
}
15981600
}
15991601
}
16001602
}

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,20 +3608,18 @@ class Typer extends Namer
36083608
* Overwritten to no-op in ReTyper.
36093609
*/
36103610
protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(using Context) : Unit =
3611-
tree match {
3611+
tree match
36123612
case _: RefTree | _: Literal
3613-
if !isVarPattern(tree)
3614-
&& !(pt <:< tree.tpe)
3615-
&& !withMode(Mode.GadtConstraintInference) {
3616-
TypeComparer.constrainPatternType(tree.tpe, pt)
3617-
} =>
3613+
if !isVarPattern(tree) && !(pt <:< tree.tpe) =>
3614+
withMode(Mode.GadtConstraintInference) {
3615+
TypeComparer.constrainPatternType(tree.tpe, pt)
3616+
}
36183617
val cmp =
36193618
untpd.Apply(
36203619
untpd.Select(untpd.TypedSplice(tree), nme.EQ),
36213620
untpd.TypedSplice(dummyTreeOfType(pt)))
36223621
typedExpr(cmp, defn.BooleanType)
36233622
case _ =>
3624-
}
36253623

36263624
private def checkStatementPurity(tree: tpd.Tree)(original: untpd.Tree, exprOwner: Symbol)(using Context): Unit =
36273625
if !tree.tpe.isErroneous

tests/neg/eql.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
object lst:
2+
opaque type Lst[+T] = Any
3+
object Lst:
4+
given lstEql[T, U] as Eql[Lst[T], Lst[U]] = Eql.derived
5+
val Empty: Lst[Nothing] = ???
6+
end lst
7+
8+
import lst.Lst
9+
10+
val xs: Lst[Int] = ???
11+
val ys: List[Int] = ???
12+
13+
def test =
14+
xs == ys // error: cannot be compared
15+
ys == xs // error
16+
xs == Nil // error
17+
Nil == xs // error
18+
ys == Lst.Empty // error
19+
Lst.Empty == ys // error
20+
xs match
21+
case Nil => ??? // error, used to pass
22+
ys match
23+
case Lst.Empty => ??? // error, used to pass
24+
25+

0 commit comments

Comments
 (0)