Skip to content

Commit 70b6f64

Browse files
committed
Fix casting of generic tuple selection
Obviously, in hindsight, we can't use the types of the unapply arguments as the type for selecting the components of a (generic) tuple...
1 parent 5a4a571 commit 70b6f64

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ object PatternMatcher {
332332
ref(defn.RuntimeTuplesModule)
333333
.select(defn.RuntimeTuples_apply)
334334
.appliedTo(receiver, Literal(Constant(i)))
335-
.cast(args(i).tpe.widen)
335+
.cast(scrutinee.info.memberInfo(caseAccessors(i)).widen)
336336

337337
if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
338338
def tupleSel(sym: Symbol) = ref(scrutinee).select(sym)

tests/run/i14587.min.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Test:
2+
def test(cond: Boolean) =
3+
val tup: (String, Unit) | (Int, Unit) = if cond then ("", ()) else (1, ())
4+
tup match
5+
case (s: String, _) => s
6+
case _ => "n/a"
7+
8+
def main(args: Array[String]): Unit =
9+
test(true) // works
10+
test(false) // was: ClassCastException: class scala.None$ cannot be cast to class scala.Some

tests/run/i14587.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
def test(foo: String): Unit = {
2+
// Does not crash if the type is written explicitly as: Option[(Option[Int], String)]
3+
val bar = {
4+
if (foo.isEmpty) Some((Some(1), ""))
5+
else Some((None, ""))
6+
}
7+
8+
bar.foreach {
9+
case (Some(_), "") =>
10+
case _ =>
11+
}
12+
}
13+
14+
@main def Test() =
15+
test("") // works
16+
test("a")

0 commit comments

Comments
 (0)