Skip to content

Commit ecb86b6

Browse files
committed
Fix scala#3208: Patterns gets the type of their scrutinee
For a pattern like `x @ P`, x get the type of the scrutinee and pattern. E.g: ``` (x: X) match case { y: Y => ... } ``` Above, `y` type to `X & Y`.
1 parent 0c21d4c commit ecb86b6

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,11 +1344,12 @@ class Typer extends Namer
13441344
case _ =>
13451345
if (tree.name == nme.WILDCARD) body1
13461346
else {
1347-
// for a singleton pattern like `x @ Nil`, `x` should get the type from the scrutinee
1347+
// For a pattern like `x @ P`, x gets the type of the scrutinee and pattern.
1348+
// For a singleton pattern like `x @ Nil`, `x` should get the type from the scrutinee
13481349
// see tests/neg/i3200b.scala and SI-1503
13491350
val symTp =
13501351
if (body1.tpe.isInstanceOf[TermRef]) pt1
1351-
else body1.tpe.underlyingIfRepeated(isJava = false)
1352+
else AndType.make(body1.tpe.underlyingIfRepeated(isJava = false), pt1)
13521353
val sym = ctx.newPatternBoundSymbol(tree.name, symTp, tree.pos)
13531354
if (pt == defn.ImplicitScrutineeTypeRef) sym.setFlag(Implicit)
13541355
if (ctx.mode.is(Mode.InPatternAlternative))

tests/pos/i3208.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
trait X
2+
trait Y
3+
4+
trait MyError
5+
6+
class Test {
7+
def test(xs: List[X]): List[X] = xs.collect { case y: Y => y }
8+
9+
def test2(x: X) = x match {
10+
case y: Y =>
11+
val b: X = y
12+
}
13+
14+
def test3 =
15+
try ???
16+
catch {
17+
case e: MyError =>
18+
throw e
19+
}
20+
}

0 commit comments

Comments
 (0)