Skip to content

Commit 3e2a7d5

Browse files
committed
Fail fast in more cases
1 parent edfa025 commit 3e2a7d5

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
@@ -185,7 +185,7 @@ object QuoteMatcher {
185185

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

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

228-
/* Match literal */
229-
case (Literal(constant1), Literal(constant2)) if constant1 == constant2 =>
230-
matched
231-
232-
/* Match type ascription (a) */
233-
case (Typed(expr1, _), pattern) =>
234-
expr1 =?= pattern
235-
236228
/* Match type ascription (b) */
237-
case (scrutinee, Typed(expr2, _)) =>
229+
case (_, Typed(expr2, _)) =>
238230
scrutinee =?= expr2
239231

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

377384
if (debug && res == notMatched)
378385
val quotes = QuotesImpl()

0 commit comments

Comments
 (0)