Skip to content

Commit 889020d

Browse files
committed
Merge pull request scala#2199 from retronym/ticket/7214
SI-7214 outer check based on dealiased pattern type.
2 parents 93c2a5b + acd74ca commit 889020d

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5365,7 +5365,9 @@ trait Types extends api.Types { self: SymbolTable =>
53655365
case _ =>
53665366
NoType
53675367
}
5368-
patType match {
5368+
// See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest`
5369+
// generates an outer test based on `patType.prefix` with automatically dealises.
5370+
patType.dealias match {
53695371
case TypeRef(pre, sym, args) =>
53705372
val pre1 = maybeCreateDummyClone(pre, sym)
53715373
(pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType)

test/files/run/t7214.scala

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// pattern matcher crashes here trying to synthesize an uneeded outer test.
2+
// no-symbol does not have an owner
3+
// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
4+
// at scala.tools.nsc.Global.abort(Global.scala:253)
5+
// at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248)
6+
// at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678)
7+
// at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664)
8+
// at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188)
9+
// at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124)
10+
// at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308)
11+
// at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209)
12+
class Crash {
13+
type Alias = C#T
14+
15+
val c = new C
16+
val t = new c.T
17+
18+
// Crash via a Typed Pattern...
19+
(t: Any) match {
20+
case e: Alias =>
21+
}
22+
23+
// ... or via a Typed Extractor Pattern.
24+
object Extractor {
25+
def unapply(a: Alias): Option[Any] = None
26+
}
27+
(t: Any) match {
28+
case Extractor() =>
29+
case _ =>
30+
}
31+
32+
// checking that correct outer tests are applied when
33+
// aliases for path dependent types are involved.
34+
val c2 = new C
35+
type CdotT = c.T
36+
type C2dotT = c2.T
37+
38+
val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get
39+
outerField.setAccessible(true)
40+
41+
(t: Any) match {
42+
case _: C2dotT =>
43+
println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0
44+
case _: CdotT =>
45+
case _ =>
46+
println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c")
47+
}
48+
}
49+
50+
class C {
51+
class T
52+
}
53+
54+
object Test extends App {
55+
new Crash
56+
}
57+

0 commit comments

Comments
 (0)