Skip to content

Commit 7f6638f

Browse files
committed
Fail fast in more cases
1 parent c7e3282 commit 7f6638f

File tree

1 file changed

+153
-146
lines changed

1 file changed

+153
-146
lines changed

compiler/src/scala/quoted/runtime/impl/QuoteMatcher.scala

Lines changed: 153 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ object QuoteMatcher {
189189

190190
/* Term hole */
191191
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
192-
case (scrutinee @ Typed(s, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
192+
case (Typed(s, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
193193
if patternHole.symbol.eq(defn.QuotedRuntimePatterns_patternHole) &&
194194
s.tpe <:< tpt.tpe &&
195195
tpt2.tpe.derivesFrom(defn.RepeatedParamClass) =>
@@ -204,7 +204,7 @@ object QuoteMatcher {
204204

205205
/* Higher order term hole */
206206
// Matches an open term and wraps it into a lambda that provides the free variables
207-
case (scrutinee, pattern @ Apply(TypeApply(Ident(_), List(TypeTree())), SeqLiteral(args, _) :: Nil))
207+
case (_, pattern @ Apply(TypeApply(Ident(_), List(TypeTree())), SeqLiteral(args, _) :: Nil))
208208
if pattern.symbol.eq(defn.QuotedRuntimePatterns_higherOrderHole) =>
209209
val names: List[TermName] = args.map {
210210
case Block(List(DefDef(nme.ANON_FUN, _, _, Apply(Ident(name), _))), _) => name.asTermName
@@ -229,154 +229,161 @@ object QuoteMatcher {
229229
// Match two equivalent trees
230230
//
231231

232-
/* Match literal */
233-
case (Literal(constant1), Literal(constant2)) if constant1 == constant2 =>
234-
matched
235-
236-
/* Match type ascription (a) */
237-
case (Typed(expr1, _), pattern) =>
238-
expr1 =?= pattern
239-
240232
/* Match type ascription (b) */
241-
case (scrutinee, Typed(expr2, _)) =>
233+
case (_, Typed(expr2, _)) =>
242234
scrutinee =?= expr2
243235

244-
/* Match selection */
245-
case (ref: RefTree, Select(qual2, _)) if symbolMatch(scrutinee, pattern) =>
246-
ref match
247-
case Select(qual1, _) => qual1 =?= qual2
248-
case ref: Ident =>
249-
ref.tpe match
250-
case TermRef(qual: TermRef, _) => tpd.ref(qual) =?= qual2
251-
case _ => matched
252-
253-
/* Match reference */
254-
case (_: RefTree, _: Ident) if symbolMatch(scrutinee, pattern) =>
255-
matched
256-
257-
/* Match application */
258-
case (Apply(fn1, args1), _) =>
259-
pattern match
260-
case Apply(fn2, args2) =>
261-
fn1 =?= fn2 &&& args1 =?= args2
262-
case _ => notMatched
263-
264-
/* Match type application */
265-
case (TypeApply(fn1, args1), _) =>
266-
pattern match
267-
case TypeApply(fn2, args2) =>
268-
fn1 =?= fn2 &&& args1 =?= args2
269-
case _ => notMatched
270-
271-
/* Match block */
272-
case (Block(stat1 :: stats1, expr1), _) =>
273-
pattern match
274-
case Block(stat2 :: stats2, expr2) =>
275-
val newEnv = (stat1, stat2) match {
276-
case (stat1: MemberDef, stat2: MemberDef) =>
277-
summon[Env] + (stat1.symbol -> stat2.symbol)
278-
case _ =>
279-
summon[Env]
280-
}
281-
withEnv(newEnv) {
282-
stat1 =?= stat2 &&& Block(stats1, expr1) =?= Block(stats2, expr2)
283-
}
284-
case _ => notMatched
285-
286-
/* Match if */
287-
case (If(cond1, thenp1, elsep1), _) =>
288-
pattern match
289-
case If(cond2, thenp2, elsep2) =>
290-
cond1 =?= cond2 &&& thenp1 =?= thenp2 &&& elsep1 =?= elsep2
291-
case _ => notMatched
292-
293-
/* Match while */
294-
case (WhileDo(cond1, body1), _) =>
295-
pattern match
296-
case WhileDo(cond2, body2) => cond1 =?= cond2 &&& body1 =?= body2
297-
case _ => notMatched
298-
299-
/* Match assign */
300-
case (Assign(lhs1, rhs1), _) =>
301-
pattern match
302-
case Assign(lhs2, rhs2) => lhs1 =?= lhs2 &&& rhs1 =?= rhs2
303-
case _ => notMatched
304-
305-
/* Match new */
306-
case (New(tpt1), _) =>
307-
pattern match
308-
case New(tpt2) if tpt1.tpe.typeSymbol == tpt2.tpe.typeSymbol => matched
309-
case _ => notMatched
310-
311-
/* Match this */
312-
case (This(_), _) =>
313-
pattern match
314-
case This(_) if scrutinee.symbol == pattern.symbol => matched
315-
case _ => notMatched
316-
317-
/* Match super */
318-
case (Super(qual1, mix1), _) =>
319-
pattern match
320-
case Super(qual2, mix2) if mix1 == mix2 => qual1 =?= qual2
321-
case _ => notMatched
322-
323-
/* Match varargs */
324-
case (SeqLiteral(elems1, _), _) =>
325-
pattern match
326-
case SeqLiteral(elems2, _) if elems1.size == elems2.size => elems1 =?= elems2
327-
case _ => notMatched
328-
329-
/* Match type */
330-
// TODO remove this?
331-
case (TypeTreeTypeTest(scrutinee), _) =>
332-
pattern match
333-
case TypeTreeTypeTest(pattern) if scrutinee.tpe <:< pattern.tpe => matched
334-
case _ => notMatched
335-
336-
/* Match val */
337-
case (scrutinee @ ValDef(_, tpt1, _), _) =>
338-
pattern match
339-
case pattern @ ValDef(_, tpt2, _) if checkValFlags() =>
340-
def rhsEnv = summon[Env] + (scrutinee.symbol -> pattern.symbol)
341-
tpt1 =?= tpt2 &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
342-
case _ => notMatched
343-
344-
/* Match def */
345-
case (scrutinee @ DefDef(_, paramss1, tpt1, _), _) =>
346-
pattern match
347-
case pattern @ DefDef(_, paramss2, tpt2, _) =>
348-
def rhsEnv: Env =
349-
val paramSyms: List[(Symbol, Symbol)] =
350-
for
351-
(clause1, clause2) <- paramss1.zip(paramss2)
352-
(param1, param2) <- clause1.zip(clause2)
353-
yield
354-
param1.symbol -> param2.symbol
355-
val oldEnv: Env = summon[Env]
356-
val newEnv: List[(Symbol, Symbol)] = (scrutinee.symbol -> pattern.symbol) :: paramSyms
357-
oldEnv ++ newEnv
358-
matchLists(paramss1, paramss2)(_ =?= _)
359-
&&& tpt1 =?= tpt2
360-
&&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
361-
case _ => notMatched
362-
363-
case (Closure(_, _, tpt1), _) =>
364-
pattern match
365-
case Closure(_, _, tpt2) => matched // TODO match tpt1 with tpt2?
366-
case _ => notMatched
367-
368-
case (NamedArg(name1, arg1), _) =>
369-
pattern match
370-
case NamedArg(name2, arg2) if name1 == name2 => arg1 =?= arg2
371-
case _ => notMatched
372-
373-
case (EmptyTree, _) =>
374-
if pattern.isEmpty then matched
375-
else notMatched
376-
377-
// No Match
378236
case _ =>
379-
notMatched
237+
(scrutinee, pattern) match
238+
/* Match type ascription (a) */
239+
case (Typed(expr1, _), _) =>
240+
expr1 =?= pattern
241+
242+
/* Match literal */
243+
case (Literal(constant1), _) =>
244+
pattern match
245+
case Literal(constant2) if constant1 == constant2 => matched
246+
case _ => notMatched
247+
248+
case (ref: RefTree, _) =>
249+
pattern match
250+
/* Match selection */
251+
case Select(qual2, _) if symbolMatch(scrutinee, pattern) =>
252+
ref match
253+
case Select(qual1, _) => qual1 =?= qual2
254+
case ref: Ident =>
255+
ref.tpe match
256+
case TermRef(qual: TermRef, _) => tpd.ref(qual) =?= qual2
257+
case _ => matched
258+
/* Match reference */
259+
case _: Ident if symbolMatch(scrutinee, pattern) => matched
260+
/* Match type */
261+
case TypeTreeTypeTest(pattern) if scrutinee.tpe <:< pattern.tpe => matched
262+
case _ => notMatched
263+
264+
/* Match application */
265+
case (Apply(fn1, args1), _) =>
266+
pattern match
267+
case Apply(fn2, args2) =>
268+
fn1 =?= fn2 &&& args1 =?= args2
269+
case _ => notMatched
270+
271+
/* Match type application */
272+
case (TypeApply(fn1, args1), _) =>
273+
pattern match
274+
case TypeApply(fn2, args2) =>
275+
fn1 =?= fn2 &&& args1 =?= args2
276+
case _ => notMatched
277+
278+
/* Match block */
279+
case (Block(stat1 :: stats1, expr1), _) =>
280+
pattern match
281+
case Block(stat2 :: stats2, expr2) =>
282+
val newEnv = (stat1, stat2) match {
283+
case (stat1: MemberDef, stat2: MemberDef) =>
284+
summon[Env] + (stat1.symbol -> stat2.symbol)
285+
case _ =>
286+
summon[Env]
287+
}
288+
withEnv(newEnv) {
289+
stat1 =?= stat2 &&& Block(stats1, expr1) =?= Block(stats2, expr2)
290+
}
291+
case _ => notMatched
292+
293+
/* Match if */
294+
case (If(cond1, thenp1, elsep1), _) =>
295+
pattern match
296+
case If(cond2, thenp2, elsep2) =>
297+
cond1 =?= cond2 &&& thenp1 =?= thenp2 &&& elsep1 =?= elsep2
298+
case _ => notMatched
299+
300+
/* Match while */
301+
case (WhileDo(cond1, body1), _) =>
302+
pattern match
303+
case WhileDo(cond2, body2) => cond1 =?= cond2 &&& body1 =?= body2
304+
case _ => notMatched
305+
306+
/* Match assign */
307+
case (Assign(lhs1, rhs1), _) =>
308+
pattern match
309+
case Assign(lhs2, rhs2) => lhs1 =?= lhs2 &&& rhs1 =?= rhs2
310+
case _ => notMatched
311+
312+
/* Match new */
313+
case (New(tpt1), _) =>
314+
pattern match
315+
case New(tpt2) if tpt1.tpe.typeSymbol == tpt2.tpe.typeSymbol => matched
316+
case _ => notMatched
317+
318+
/* Match this */
319+
case (This(_), _) =>
320+
pattern match
321+
case This(_) if scrutinee.symbol == pattern.symbol => matched
322+
case _ => notMatched
323+
324+
/* Match super */
325+
case (Super(qual1, mix1), _) =>
326+
pattern match
327+
case Super(qual2, mix2) if mix1 == mix2 => qual1 =?= qual2
328+
case _ => notMatched
329+
330+
/* Match varargs */
331+
case (SeqLiteral(elems1, _), _) =>
332+
pattern match
333+
case SeqLiteral(elems2, _) if elems1.size == elems2.size => elems1 =?= elems2
334+
case _ => notMatched
335+
336+
/* Match type */
337+
// TODO remove this?
338+
case (TypeTreeTypeTest(scrutinee), _) =>
339+
pattern match
340+
case TypeTreeTypeTest(pattern) if scrutinee.tpe <:< pattern.tpe => matched
341+
case _ => notMatched
342+
343+
/* Match val */
344+
case (scrutinee @ ValDef(_, tpt1, _), _) =>
345+
pattern match
346+
case pattern @ ValDef(_, tpt2, _) if checkValFlags() =>
347+
def rhsEnv = summon[Env] + (scrutinee.symbol -> pattern.symbol)
348+
tpt1 =?= tpt2 &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
349+
case _ => notMatched
350+
351+
/* Match def */
352+
case (scrutinee @ DefDef(_, paramss1, tpt1, _), _) =>
353+
pattern match
354+
case pattern @ DefDef(_, paramss2, tpt2, _) =>
355+
def rhsEnv: Env =
356+
val paramSyms: List[(Symbol, Symbol)] =
357+
for
358+
(clause1, clause2) <- paramss1.zip(paramss2)
359+
(param1, param2) <- clause1.zip(clause2)
360+
yield
361+
param1.symbol -> param2.symbol
362+
val oldEnv: Env = summon[Env]
363+
val newEnv: List[(Symbol, Symbol)] = (scrutinee.symbol -> pattern.symbol) :: paramSyms
364+
oldEnv ++ newEnv
365+
matchLists(paramss1, paramss2)(_ =?= _)
366+
&&& tpt1 =?= tpt2
367+
&&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
368+
case _ => notMatched
369+
370+
case (Closure(_, _, tpt1), _) =>
371+
pattern match
372+
case Closure(_, _, tpt2) => matched // TODO match tpt1 with tpt2?
373+
case _ => notMatched
374+
375+
case (NamedArg(name1, arg1), _) =>
376+
pattern match
377+
case NamedArg(name2, arg2) if name1 == name2 => arg1 =?= arg2
378+
case _ => notMatched
379+
380+
case (EmptyTree, _) =>
381+
if pattern.isEmpty then matched
382+
else notMatched
383+
384+
// No Match
385+
case _ =>
386+
notMatched
380387

381388
if (debug && res == notMatched)
382389
val quotes = QuotesImpl()

0 commit comments

Comments
 (0)