// pattern matcher crashes here trying to synthesize an uneeded outer test. // no-symbol does not have an owner // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49) // at scala.tools.nsc.Global.abort(Global.scala:253) // at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248) // at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678) // at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664) // at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188) // at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124) // at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308) // at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209) class Crash { type Alias = C#T val c = new C val t = new c.T // Crash via a Typed Pattern... (t: Any) match { case e: Alias => } // ... or via a Typed Extractor Pattern. object Extractor { def unapply(a: Alias): Option[Any] = None } (t: Any) match { case Extractor(_) => case _ => } // checking that correct outer tests are applied when // aliases for path dependent types are involved. val c2 = new C type CdotT = c.T type C2dotT = c2.T val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get outerField.setAccessible(true) (t: Any) match { case _: C2dotT => println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0 case _: CdotT => case _ => println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c") } } class C { class T } object Test extends dotty.runtime.LegacyApp { new Crash }