diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 41d21d61cd12..e6886b99e431 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -177,12 +177,19 @@ class TreeChecker extends Phase with SymTransformer { res } + def withPatSyms[T](syms: List[Symbol])(op: => T)(implicit ctx: Context) = { + nowDefinedSyms ++= syms + val res = op + nowDefinedSyms --= syms + res + } + def assertDefined(tree: untpd.Tree)(implicit ctx: Context) = if ( tree.symbol.maybeOwner.isTerm && !(tree.symbol.is(Label) && !tree.symbol.owner.isClass && ctx.phase.labelsReordered) // labeldefs breaks scoping ) - assert(nowDefinedSyms contains tree.symbol, i"undefined symbol ${tree.symbol}") + assert(nowDefinedSyms contains tree.symbol, i"undefined symbol ${tree.symbol} at line " + tree.pos.line) /** assert Java classes are not used as objects */ def assertIdentNotJavaClass(tree: Tree)(implicit ctx: Context): Unit = tree match { @@ -400,7 +407,7 @@ class TreeChecker extends Phase with SymTransformer { } override def typedCase(tree: untpd.CaseDef, pt: Type, selType: Type, gadtSyms: Set[Symbol])(implicit ctx: Context): CaseDef = { - withDefinedSyms(tree.pat.asInstanceOf[tpd.Tree].filterSubTrees(_.isInstanceOf[ast.Trees.Bind[_]])) { + withPatSyms(tpd.patVars(tree.pat.asInstanceOf[tpd.Tree])) { super.typedCase(tree, pt, selType, gadtSyms) } } diff --git a/tests/pos/i4198.scala b/tests/pos/i4198.scala new file mode 100644 index 000000000000..667bd983fc9e --- /dev/null +++ b/tests/pos/i4198.scala @@ -0,0 +1,15 @@ +class Foo { + def foo(x: Any): Unit = { + x match { + case y: Bar[_] => + y.value match { + case value: Bar[_] => // here x is an instance of Bar[Bar[_]] + case _ => + } + } + } +} + +class Bar[T] { + def value: T = ??? +}