diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 8cb7903ad06f..2974e2840be2 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -156,7 +156,7 @@ object desugar { * - all package object members */ def valDef(vdef0: ValDef)(implicit ctx: Context): Tree = { - val vdef @ ValDef(name, tpt, rhs) = transformQuotedPatternName(vdef0) + val vdef @ ValDef(name, tpt, rhs) = vdef0 val mods = vdef.mods val setterNeeded = mods.is(Mutable) @@ -204,7 +204,7 @@ object desugar { * def f$default$2[T](x: Int) = x + "m" */ private def defDef(meth0: DefDef, isPrimaryConstructor: Boolean = false)(implicit ctx: Context): Tree = { - val meth @ DefDef(_, tparams, vparamss, tpt, rhs) = transformQuotedPatternName(meth0) + val meth @ DefDef(_, tparams, vparamss, tpt, rhs) = meth0 val methName = normalizeName(meth, tpt).asTermName val mods = meth.mods val epbuf = ListBuffer[ValDef]() @@ -279,26 +279,6 @@ object desugar { } } - /** Transforms a definition with a name starting with a `$` in a quoted pattern into a `quoted.binding.Binding` splice. - * - * The desugaring consists in adding the `@patternBindHole` annotation. This annotation is used during typing to perform the full transformation. - * - * A definition - * ```scala - * case '{ def $a(...) = ...; ... `$a`() ... } => a - * ``` - * into - * ```scala - * case '{ @patternBindHole def `$a`(...) = ...; ... `$a`() ... } => a - * ``` - */ - def transformQuotedPatternName(tree: ValOrDefDef)(implicit ctx: Context): ValOrDefDef = - if (ctx.mode.is(Mode.QuotedPattern) && !isBackquoted(tree) && tree.name != nme.ANON_FUN && tree.name.startsWith("$")) { - val mods = tree.mods.withAddedAnnotation(New(ref(defn.InternalQuoted_patternBindHoleAnnot.typeRef)).withSpan(tree.span)) - tree.withMods(mods) - } - else tree - /** Add an explicit ascription to the `expectedTpt` to every tail splice. * * - `'{ x }` -> `'{ x }` diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index d8806c093acc..a3840420dd82 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -695,7 +695,6 @@ class Definitions { @tu lazy val InternalQuoted_exprNestedSplice : Symbol = InternalQuotedModule.requiredMethod("exprNestedSplice") @tu lazy val InternalQuoted_typeQuote : Symbol = InternalQuotedModule.requiredMethod("typeQuote") @tu lazy val InternalQuoted_patternHole: Symbol = InternalQuotedModule.requiredMethod("patternHole") - @tu lazy val InternalQuoted_patternBindHoleAnnot: ClassSymbol = InternalQuotedModule.requiredClass("patternBindHole") @tu lazy val InternalQuoted_patternTypeAnnot: ClassSymbol = InternalQuotedModule.requiredClass("patternType") @tu lazy val InternalQuoted_QuoteTypeTagAnnot: ClassSymbol = InternalQuotedModule.requiredClass("quoteTypeTag") @tu lazy val InternalQuoted_fromAboveAnnot: ClassSymbol = InternalQuotedModule.requiredClass("fromAbove") diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index c2a207aff44b..e5c4f938197c 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -1963,7 +1963,6 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Definitions_isTupleClass(sym: Symbol): Boolean = defn.isTupleClass(sym) def Definitions_InternalQuoted_patternHole: Symbol = defn.InternalQuoted_patternHole - def Definitions_InternalQuoted_patternBindHoleAnnot: Symbol = defn.InternalQuoted_patternBindHoleAnnot def Definitions_InternalQuoted_patternTypeAnnot: Symbol = defn.InternalQuoted_patternTypeAnnot def Definitions_InternalQuoted_fromAboveAnnot: Symbol = defn.InternalQuoted_fromAboveAnnot diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index da4189aa0002..f416eb27cf58 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -219,23 +219,6 @@ trait QuotesAndSplices { TypeTree(tree.tpe.dealias).withSpan(tree.span) else tree - case ddef: ValOrDefDef => - if (ddef.symbol.hasAnnotation(defn.InternalQuoted_patternBindHoleAnnot)) { - val bindingType = ddef.symbol.info match { - case t: ExprType => t.resType - case t: MethodType => t.toFunctionType() - case t: PolyType => - HKTypeLambda(t.paramNames)( - x => t.paramInfos.mapConserve(_.subst(t, x).asInstanceOf[TypeBounds]), - x => t.resType.subst(t, x).toFunctionType()) - case t => t - } - assert(ddef.name.startsWith("$")) - val bindName = ddef.name.toString.stripPrefix("$").toTermName - val sym = ctx0.newPatternBoundSymbol(bindName, defn.StringType, ddef.span) - patBuf += Bind(sym, untpd.Ident(nme.WILDCARD).withType(defn.StringType)).withSpan(ddef.span) - } - super.transform(tree) case tdef: TypeDef if tdef.symbol.hasAnnotation(defn.InternalQuoted_patternTypeAnnot) => transformTypeBindingTypeDef(tdef, typePatBuf) case tree @ AppliedTypeTree(tpt, args) => diff --git a/library/src/scala/internal/quoted/CompileTime.scala b/library/src/scala/internal/quoted/CompileTime.scala index c44b34d1ae6b..c9e3ceb40dfc 100644 --- a/library/src/scala/internal/quoted/CompileTime.scala +++ b/library/src/scala/internal/quoted/CompileTime.scala @@ -28,6 +28,7 @@ object CompileTime { @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternHole`") def patternHole[T]: T = ??? + // TODO remove /** A splice of a name in a quoted pattern is desugared by wrapping getting this annotation */ @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternBindHole`") class patternBindHole extends Annotation diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src/scala/internal/quoted/Matcher.scala index b2a639989c17..8a022dd77328 100644 --- a/library/src/scala/internal/quoted/Matcher.scala +++ b/library/src/scala/internal/quoted/Matcher.scala @@ -69,15 +69,8 @@ private[quoted] object Matcher { } } - private def hasBindTypeAnnotation(tpt: TypeTree): Boolean = tpt match { - case Annotated(tpt2, annot) => isBindAnnotation(annot) || hasBindTypeAnnotation(tpt2) - case _ => false - } - private def hasPatternTypeAnnotation(sym: Symbol) = sym.annots.exists(isPatternTypeAnnotation) - private def hasBindAnnotation(sym: Symbol) = sym.annots.exists(isBindAnnotation) - private def hasFromAboveAnnotation(sym: Symbol) = sym.annots.exists(isFromAboveAnnotation) private def isPatternTypeAnnotation(tree: Tree): Boolean = tree match { @@ -85,11 +78,6 @@ private[quoted] object Matcher { case annot => annot.symbol.owner == internal.Definitions_InternalQuoted_patternTypeAnnot } - private def isBindAnnotation(tree: Tree): Boolean = tree match { - case New(tpt) => tpt.symbol == internal.Definitions_InternalQuoted_patternBindHoleAnnot - case annot => annot.symbol.owner == internal.Definitions_InternalQuoted_patternBindHoleAnnot - } - private def isFromAboveAnnotation(tree: Tree): Boolean = tree match { case New(tpt) => tpt.symbol == internal.Definitions_InternalQuoted_fromAboveAnnot case annot => annot.symbol.owner == internal.Definitions_InternalQuoted_fromAboveAnnot @@ -139,9 +127,6 @@ private[quoted] object Matcher { sFlags.is(Lazy) == pFlags.is(Lazy) && sFlags.is(Mutable) == pFlags.is(Mutable) } - def bindingMatch(sym: Symbol) = - matched(sym.name) - (scrutinee, pattern) match { // Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree @@ -254,16 +239,10 @@ private[quoted] object Matcher { tycon1 =?= tycon2 && args1 =?= args2 case (ValDef(_, tpt1, rhs1), ValDef(_, tpt2, rhs2)) if checkValFlags() => - val bindMatch = - if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol) - else matched def rhsEnv = summon[Env] + (scrutinee.symbol -> pattern.symbol) - bindMatch && tpt1 =?= tpt2 && treeOptMatches(rhs1, rhs2)(using summon[Context], rhsEnv) + tpt1 =?= tpt2 && treeOptMatches(rhs1, rhs2)(using summon[Context], rhsEnv) case (DefDef(_, typeParams1, paramss1, tpt1, Some(rhs1)), DefDef(_, typeParams2, paramss2, tpt2, Some(rhs2))) => - val bindMatch = - if (hasBindAnnotation(pattern.symbol)) bindingMatch(scrutinee.symbol) - else matched def rhsEnv = val oldEnv: Env = summon[Env] val newEnv: List[(Symbol, Symbol)] = @@ -271,11 +250,10 @@ private[quoted] object Matcher { paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol) oldEnv ++ newEnv - bindMatch && - typeParams1 =?= typeParams2 && - matchLists(paramss1, paramss2)(_ =?= _) && - tpt1 =?= tpt2 && - withEnv(rhsEnv)(rhs1 =?= rhs2) + typeParams1 =?= typeParams2 + && matchLists(paramss1, paramss2)(_ =?= _) + && tpt1 =?= tpt2 + && withEnv(rhsEnv)(rhs1 =?= rhs2) case (Closure(_, tpt1), Closure(_, tpt2)) => // TODO match tpt1 with tpt2? diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 84a553867b0c..0204a7d526eb 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -1497,9 +1497,6 @@ trait CompilerInterface { /** Symbol of scala.internal.Quoted.patternHole */ def Definitions_InternalQuoted_patternHole: Symbol - /** Symbol of scala.internal.Quoted.patternBindHole */ - def Definitions_InternalQuoted_patternBindHoleAnnot: Symbol - /** Symbol of scala.internal.Quoted.patternType */ def Definitions_InternalQuoted_patternTypeAnnot: Symbol diff --git a/tests/pos/quotedPatterns.scala b/tests/pos/quotedPatterns.scala index 0bfe97736f16..3a7248fdfef6 100644 --- a/tests/pos/quotedPatterns.scala +++ b/tests/pos/quotedPatterns.scala @@ -13,23 +13,17 @@ object Test { case '{ ((a: Int) => 3)($y) } => y case '{ 1 + ($y: Int)} => y case '{ val a = 1 + ($y: Int); 3 } => y - case '{ val $y: Int = $z; println(`$y`); 1 } => - val a: String = y + case '{ val y: Int = $z; println(y); 1 } => z - case '{ (($y: Int) => 1 + `$y` + ($z: Int))(2) } => - val a: String = y + case '{ ((y: Int) => 1 + y + ($z: Int))(2) } => z - case '{ def $ff: Int = $z; `$ff` } => - val a: String = ff + case '{ def ff: Int = $z; ff } => z - case '{ def $ff(i: Int): Int = $z; 2 } => - val a: String = ff + case '{ def ff(i: Int): Int = $z; 2 } => z - case '{ def $ff(i: Int)(j: Int): Int = $z; 2 } => - val a: String = ff + case '{ def ff(i: Int)(j: Int): Int = $z; 2 } => z - case '{ def $ff[T](i: T): Int = $z; 2 } => - val a: String = ff + case '{ def ff[T](i: T): Int = $z; 2 } => z case '{ poly[$t]($x); 4 } => ??? case '{ type $X; poly[`$X`]($x); 4 } => ??? diff --git a/tests/run-macros/quote-matcher-runtime.check b/tests/run-macros/quote-matcher-runtime.check index 59ed107db039..0eb9a148e9aa 100644 --- a/tests/run-macros/quote-matcher-runtime.check +++ b/tests/run-macros/quote-matcher-runtime.check @@ -237,8 +237,8 @@ Pattern: scala.internal.quoted.CompileTime.patternHole[scala.Function1[scala.Int Result: Some(List(Expr(((x: scala.Int) => "abc")))) Scrutinee: ((x: scala.Int) => "abc") -Pattern: ((x: scala.Int @scala.internal.quoted.CompileTime.patternBindHole) => scala.internal.quoted.CompileTime.patternHole[scala.Predef.String]) -Result: Some(List(String(x), Expr("abc"))) +Pattern: ((x: scala.Int) => scala.internal.quoted.CompileTime.patternHole[scala.Predef.String]) +Result: Some(List(Expr("abc"))) Scrutinee: scala.StringContext.apply("abc", "xyz") Pattern: scala.StringContext.apply("abc", "xyz") @@ -267,10 +267,10 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } -Result: Some(List(String(a), Expr(45))) +Result: Some(List(Expr(45))) Scrutinee: { val a: scala.Int = 45 @@ -297,7 +297,7 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole var a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + var a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } Result: None @@ -369,7 +369,7 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } Result: None @@ -379,7 +379,7 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole var a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + var a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } Result: None @@ -419,7 +419,7 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } Result: None @@ -429,7 +429,7 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole lazy val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + lazy val a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } Result: None @@ -499,10 +499,10 @@ Scrutinee: { () } Pattern: { - @scala.internal.quoted.CompileTime.patternBindHole def a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] + def a: scala.Int = scala.internal.quoted.CompileTime.patternHole[scala.Int] () } -Result: Some(List(String(a), Expr(45))) +Result: Some(List(Expr(45))) Scrutinee: { def a(x: scala.Int): scala.Int = 45 @@ -569,20 +569,20 @@ Scrutinee: { () } Pattern: { - def a(x: scala.Int @scala.internal.quoted.CompileTime.patternBindHole): scala.Int = 45 + def a(x: scala.Int): scala.Int = 45 () } -Result: Some(List(String(x))) +Result: Some(List()) Scrutinee: { def a(x: scala.Int): scala.Int = 45 () } Pattern: { - def a(x: scala.Int @scala.internal.quoted.CompileTime.patternBindHole): scala.Int = 45 + def a(x: scala.Int): scala.Int = 45 () } -Result: Some(List(String(x))) +Result: Some(List()) Scrutinee: { def a(x: scala.Int): scala.Int = x diff --git a/tests/run-macros/quote-matcher-runtime/quoted_2.scala b/tests/run-macros/quote-matcher-runtime/quoted_2.scala index e83318e55d5d..fa07d6a79309 100644 --- a/tests/run-macros/quote-matcher-runtime/quoted_2.scala +++ b/tests/run-macros/quote-matcher-runtime/quoted_2.scala @@ -81,43 +81,43 @@ object Test { matches((() => "abc")(), (patternHole[() => String]).apply()) matches((x: Int) => "abc", patternHole[Int=> String]) matches(((x: Int) => "abc")(4), (patternHole[Int => String]).apply(4)) - matches((x: Int) => "abc", (x: Int @patternBindHole) => patternHole[String]) + matches((x: Int) => "abc", (x: Int) => patternHole[String]) matches(StringContext("abc", "xyz"), StringContext("abc", "xyz")) matches(StringContext("abc", "xyz"), StringContext(patternHole, patternHole)) matches(StringContext("abc", "xyz"), StringContext(patternHole[Seq[String]]: _*)) matches({ val a: Int = 45 }, { val a: Int = 45 }) - matches({ val a: Int = 45 }, { @patternBindHole val a: Int = patternHole }) + matches({ val a: Int = 45 }, { val a: Int = patternHole }) matches({ val a: Int = 45 }, { lazy val a: Int = 45 }) matches({ val a: Int = 45 }, { var a: Int = 45 }) - matches({ val a: Int = 45 }, { @patternBindHole var a: Int = patternHole }) + matches({ val a: Int = 45 }, { var a: Int = patternHole }) matches({ val a: Int = 45; a + a }, { val x: Int = 45; x + x }) matches({ val a: Int = 45; val b = a }, { val x: Int = 45; val y = x }) matches({ val a: Int = 45; a + a }, { val x: Int = 45; x + patternHole[Int] }) matches({ lazy val a: Int = 45 }, { val a: Int = 45 }) matches({ lazy val a: Int = 45 }, { lazy val a: Int = 45 }) matches({ lazy val a: Int = 45 }, { var a: Int = 45 }) - matches({ lazy val a: Int = 45 }, { @patternBindHole val a: Int = patternHole }) - matches({ lazy val a: Int = 45 }, { @patternBindHole var a: Int = patternHole }) + matches({ lazy val a: Int = 45 }, { val a: Int = patternHole }) + matches({ lazy val a: Int = 45 }, { var a: Int = patternHole }) matches({ var a: Int = 45 }, { val a: Int = 45 }) matches({ var a: Int = 45 }, { lazy val a: Int = 45 }) matches({ var a: Int = 45 }, { var a: Int = 45 }) - matches({ var a: Int = 45 }, { @patternBindHole val a: Int = patternHole }) - matches({ var a: Int = 45 }, { @patternBindHole lazy val a: Int = patternHole }) + matches({ var a: Int = 45 }, { val a: Int = patternHole }) + matches({ var a: Int = 45 }, { lazy val a: Int = patternHole }) matches({ println(); println() }, { println(); println() }) matches({ { println() }; println() }, { println(); println() }) matches({ println(); { println() } }, { println(); println() }) matches({ println(); println() }, { println(); { println() } }) matches({ println(); println() }, { { println() }; println() }) matches({ def a: Int = 45 }, { def a: Int = 45 }) - matches({ def a: Int = 45 }, { @patternBindHole def a: Int = patternHole[Int] }) + matches({ def a: Int = 45 }, { def a: Int = patternHole[Int] }) matches({ def a(x: Int): Int = 45 }, { def a(x: Int): Int = 45 }) matches({ def a(x: Int): Int = 45 }, { def a(x: Int, y: Int): Int = 45 }) matches({ def a(x: Int): Int = 45 }, { def a(x: Int)(y: Int): Int = 45 }) matches({ def a(x: Int, y: Int): Int = 45 }, { def a(x: Int): Int = 45 }) matches({ def a(x: Int)(y: Int): Int = 45 }, { def a(x: Int): Int = 45 }) matches({ def a(x: String): Int = 45 }, { def a(x: String): Int = 45 }) - matches({ def a(x: Int): Int = 45 }, { def a(x: Int @patternBindHole): Int = 45 }) - matches({ def a(x: Int): Int = 45 }, { def a(x: Int @patternBindHole): Int = 45 }) + matches({ def a(x: Int): Int = 45 }, { def a(x: Int): Int = 45 }) + matches({ def a(x: Int): Int = 45 }, { def a(x: Int): Int = 45 }) matches({ def a(x: Int): Int = x }, { def b(y: Int): Int = y }) matches({ def a: Int = a }, { def b: Int = b }) matches({ def a: Int = a; a + a }, { def a: Int = a; a + a })