Skip to content

Commit a6b207d

Browse files
committed
Refactor QuoteMatcher with regard to type params matching, and refine test cases
1 parent c33874c commit a6b207d

File tree

11 files changed

+46
-15
lines changed

11 files changed

+46
-15
lines changed

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -431,20 +431,6 @@ class QuoteMatcher(debug: Boolean) {
431431
case TypeTreeTypeTest(pattern) if isSubTypeUnderEnv(scrutinee, pattern) => matched
432432
case _ => notMatched
433433

434-
// TODO-18271: We might want to restrict type bounds/type defs to match
435-
// only when they are empty bounds (<: Nothing :> Any)
436-
// to keep behavioral difference minimal
437-
case TypeBoundsTree(sclo, schi, scalias) =>
438-
pattern match
439-
case TypeBoundsTree(ptlo, pthi, ptalias) =>
440-
sclo =?= ptlo &&& schi =?= pthi &&& scalias =?= ptalias
441-
case _ => notMatched
442-
443-
case TypeDef(_, rhs1) =>
444-
pattern match
445-
case TypeDef(_, rhs2) => rhs1 =?= rhs2
446-
case _ => notMatched
447-
448434
/* Match val */
449435
case scrutinee @ ValDef(_, tpt1, _) =>
450436
pattern match
@@ -468,6 +454,20 @@ class QuoteMatcher(debug: Boolean) {
468454
notMatched
469455
case _ => matched
470456

457+
/**
458+
* Implementation restriction: The current implementation matches type parameters
459+
* only when they have empty bounds (>: Nothing <: Any)
460+
*/
461+
def matchTypeDef(sctypedef: TypeDef, pttypedef: TypeDef): MatchingExprs = sctypedef match
462+
case TypeDef(_, TypeBoundsTree(sclo, schi, EmptyTree))
463+
if sclo.tpe == defn.NothingType && schi.tpe == defn.AnyType =>
464+
pttypedef match
465+
case TypeDef(_, TypeBoundsTree(ptlo, pthi, EmptyTree))
466+
if sclo.tpe == defn.NothingType && schi.tpe == defn.AnyType =>
467+
matched
468+
case _ => notMatched
469+
case _ => notMatched
470+
471471
def matchParamss(scparamss: List[ParamClause], ptparamss: List[ParamClause])(using Env): optional[(Env, MatchingExprs)] =
472472
(scparamss, ptparamss) match {
473473
case (ValDefs(scparams) :: screst, ValDefs(ptparams) :: ptrest) =>
@@ -480,7 +480,7 @@ class QuoteMatcher(debug: Boolean) {
480480
val (resEnv, mrrest) = withEnv(newEnv)(matchParamss(screst, ptrest))
481481
(resEnv, mr1 &&& mrrest)
482482
case (TypeDefs(scparams) :: screst, TypeDefs(ptparams) :: ptrest) =>
483-
val mr1 = matchLists(scparams, ptparams)(_ =?= _)
483+
val mr1 = matchLists(scparams, ptparams)(matchTypeDef)
484484
val Env(termEnv, typeEnv) = summon[Env]
485485
val newEnv = new Env(
486486
termEnv = termEnv,

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class CompilationTests {
138138
@Test def runAll: Unit = {
139139
implicit val testGroup: TestGroup = TestGroup("runAll")
140140
aggregateTests(
141+
compileFilesInDir("tests/run-custom-args/quoted-pattern-poly", defaultOptions.and("-language:experimental.quotedPatternsWithPolymorphicFunctions")),
141142
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init")),
142143
compileFilesInDir("tests/run-deep-subtype", allowDeepSubtypes),
143144
compileFilesInDir("tests/run-custom-args/captures", allowDeepSubtypes.and("-language:experimental.captureChecking")),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Case 1 matched
2+
not matched
3+
not matched
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted.*
2+
3+
inline def testExpr(inline body: Any) = ${ testExprImpl1('body) }
4+
def testExprImpl1(body: Expr[Any])(using Quotes): Expr[String] =
5+
body match
6+
case '{ [A] => (x : A, y : A) => (x, y) } => Expr("Case 1 matched")
7+
case '{ [A <: Iterable[Int]] => (x : A) => x } => Expr("Case 2 matched")
8+
case _ => Expr("not matched")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@main def Test: Unit =
2+
println(testExpr([B] => (x : B, y : B) => (x, y)))
3+
println(testExpr([B <: Iterable[Int]] => (x : B) => x))
4+
println(testExpr([B <: List[Int]] => (x : B) => x))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Case 1 matched
2+
not matched
3+
not matched
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted.*
2+
3+
inline def testExpr(inline body: Any) = ${ testExprImpl1('body) }
4+
def testExprImpl1(body: Expr[Any])(using Quotes): Expr[String] =
5+
body match
6+
case '{ [A] => (x : A, y : A) => (x, y) } => Expr("Case 1 matched")
7+
case '{ [A <: Iterable[Int]] => (x : A) => x } => Expr("Case 2 matched")
8+
case _ => Expr("not matched")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@main def Test: Unit =
2+
println(testExpr([B] => (x : B, y : B) => (x, y)))
3+
println(testExpr([B <: Iterable[Int]] => (x : B) => x))
4+
println(testExpr([B <: List[Int]] => (x : B) => x))

0 commit comments

Comments
 (0)