diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 6ae568686185..b266166745de 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -274,27 +274,21 @@ 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 renaming the the definition and adding the `@patternBindHole` annotation. This - * annotation is used during typing to perform the full transformation. + * 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() ... } + * case '{ def $a(...) = ...; ... `$a`() ... } => a * ``` * into * ```scala - * case '{ @patternBindHole def a(...) = ... a() ...; ... a() ... } + * case '{ @patternBindHole def `$a`(...) = ...; ... `$a`() ... } => a * ``` */ def transformQuotedPatternName(tree: ValOrDefDef)(implicit ctx: Context): ValOrDefDef = { if (ctx.mode.is(Mode.QuotedPattern) && !tree.isBackquoted && tree.name != nme.ANON_FUN && tree.name.startsWith("$")) { - val name = tree.name.toString.substring(1).toTermName - val newTree: ValOrDefDef = tree match { - case tree: ValDef => cpy.ValDef(tree)(name) - case tree: DefDef => cpy.DefDef(tree)(name) - } val mods = tree.mods.withAddedAnnotation(New(ref(defn.InternalQuoted_patternBindHoleAnnot.typeRef)).withSpan(tree.span)) - newTree.withMods(mods) + tree.withMods(mods) } else tree } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 5445b693e7d4..0af0d7b409ee 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1986,7 +1986,9 @@ class Typer extends Namer case t => t } val bindingExprTpe = AppliedType(defn.QuotedMatchingBindingType, bindingType :: Nil) - val sym = ctx0.newPatternBoundSymbol(ddef.name, bindingExprTpe, ddef.span) + assert(ddef.name.startsWith("$")) + val bindName = ddef.name.toString.stripPrefix("$").toTermName + val sym = ctx0.newPatternBoundSymbol(bindName, bindingExprTpe, ddef.span) patBuf += Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingExprTpe)).withSpan(ddef.span) } super.transform(tree) diff --git a/tests/pos/quotedPatterns.scala b/tests/pos/quotedPatterns.scala index 6a1e9a1329d0..1309c8067845 100644 --- a/tests/pos/quotedPatterns.scala +++ b/tests/pos/quotedPatterns.scala @@ -12,17 +12,13 @@ object Test { case '{ ((a: Int) => 3)($y) } => y case '{ 1 + ($y: Int)} => y case '{ val a = 1 + ($y: Int); 3 } => y - // currently gives an unreachable case warning - // but only when used in conjunction with the others. - // I believe this is because implicit arguments are not taken - // into account when checking whether we have already seen an `unapply` before. - case '{ val $y: Int = $z; 1 } => + case '{ val $y: Int = $z; println(`$y`); 1 } => val a: quoted.matching.Bind[Int] = y z - case '{ (($y: Int) => 1 + y + ($z: Int))(2) } => + case '{ (($y: Int) => 1 + `$y` + ($z: Int))(2) } => val a: quoted.matching.Bind[Int] = y z - case '{ def $ff: Int = $z; ff } => + case '{ def $ff: Int = $z; `$ff` } => val a: quoted.matching.Bind[Int] = ff z case '{ def $ff(i: Int): Int = $z; 2 } =>