@@ -131,6 +131,7 @@ class TreeChecker extends Phase with SymTransformer {
131131 class Checker (phasesToCheck : Seq [Phase ]) extends ReTyper with Checking {
132132
133133 private [this ] val nowDefinedSyms = new mutable.HashSet [Symbol ]
134+ private [this ] val patBoundSyms = new mutable.HashSet [Symbol ]
134135 private [this ] val everDefinedSyms = newMutableSymbolMap[untpd.Tree ]
135136
136137 // don't check value classes after typer, as the constraint about constructors doesn't hold after transform
@@ -171,10 +172,21 @@ class TreeChecker extends Phase with SymTransformer {
171172 res
172173 }
173174
175+ /** The following invariant holds:
176+ *
177+ * patBoundSyms.contains(sym) <=> sym.isPatternBound
178+ */
174179 def withPatSyms [T ](syms : List [Symbol ])(op : => T )(implicit ctx : Context ): T = {
175- nowDefinedSyms ++= syms
180+ syms.foreach { sym =>
181+ assert(
182+ sym.isPatternBound,
183+ " patBoundSyms.contains(sym) => sym.isPatternBound is broken." +
184+ i " Pattern bound symbol $sym has incorrect flags: " + sym.flagsString + " , line " + sym.sourcePos.line
185+ )
186+ }
187+ patBoundSyms ++= syms
176188 val res = op
177- nowDefinedSyms --= syms
189+ patBoundSyms --= syms
178190 res
179191 }
180192
@@ -189,8 +201,19 @@ class TreeChecker extends Phase with SymTransformer {
189201 }
190202
191203 def assertDefined (tree : untpd.Tree )(implicit ctx : Context ): Unit =
192- if (tree.symbol.maybeOwner.isTerm)
193- assert(nowDefinedSyms contains tree.symbol, i " undefined symbol ${tree.symbol} at line " + tree.sourcePos.line)
204+ if (tree.symbol.maybeOwner.isTerm) {
205+ val sym = tree.symbol
206+ assert(
207+ nowDefinedSyms.contains(sym) || patBoundSyms.contains(sym),
208+ i " undefined symbol ${sym} at line " + tree.sourcePos.line
209+ )
210+
211+ if (! ctx.phase.patternTranslated)
212+ assert(
213+ ! sym.isPatternBound || patBoundSyms.contains(sym),
214+ i " sym.isPatternBound => patBoundSyms.contains(sym) is broken, sym = $sym, line " + tree.sourcePos.line
215+ )
216+ }
194217
195218 /** assert Java classes are not used as objects */
196219 def assertIdentNotJavaClass (tree : Tree )(implicit ctx : Context ): Unit = tree match {
0 commit comments