@@ -11,7 +11,7 @@ import dotty.tools.dotc.core.Constants._
1111import dotty .tools .dotc .core .Contexts ._
1212import dotty .tools .dotc .core .Decorators ._
1313import dotty .tools .dotc .core .Flags ._
14- import dotty .tools .dotc .core .NameKinds .{UniqueName , PatMatVarName }
14+ import dotty .tools .dotc .core .NameKinds .{UniqueName , PatMatGivenVarName }
1515import dotty .tools .dotc .core .Names ._
1616import dotty .tools .dotc .core .StagingContext ._
1717import dotty .tools .dotc .core .StdNames ._
@@ -37,7 +37,7 @@ trait QuotesAndSplices {
3737
3838 import tpd ._
3939
40- /** Translate `'{ t }` into `scala.quoted.Expr.apply(t )` and `'[T]` into `scala.quoted.Type.apply[T]`
40+ /** Translate `'{ e }` into `scala.quoted.Expr.apply(e )` and `'[T]` into `scala.quoted.Type.apply[T]`
4141 * while tracking the quotation level in the context.
4242 */
4343 def typedQuote (tree : untpd.Quote , pt : Type )(using Context ): Tree = {
@@ -83,7 +83,7 @@ trait QuotesAndSplices {
8383 def spliceOwner (ctx : Context ): Symbol =
8484 if (ctx.mode.is(Mode .QuotedPattern )) spliceOwner(ctx.outer) else ctx.owner
8585 val pat = typedPattern(tree.expr, defn.QuotedExprClass .typeRef.appliedTo(pt))(
86- using spliceContext.retractMode(Mode .QuotedPattern ).withOwner(spliceOwner(ctx)))
86+ using spliceContext.retractMode(Mode .QuotedPattern ).addMode( Mode . Pattern ). withOwner(spliceOwner(ctx)))
8787 val baseType = pat.tpe.baseType(defn.QuotedExprClass )
8888 val argType = if baseType != NoType then baseType.argTypesHi.head else defn.NothingType
8989 ref(defn.InternalQuoted_exprSplice ).appliedToType(argType).appliedTo(pat)
@@ -158,25 +158,11 @@ trait QuotesAndSplices {
158158 }
159159
160160 if ctx.mode.is(Mode .QuotedPattern ) && level == 1 then
161- def spliceOwner (ctx : Context ): Symbol =
162- if (ctx.mode.is(Mode .QuotedPattern )) spliceOwner(ctx.outer) else ctx.owner
163- val (name, expr) = tree.expr match {
164- case Ident (name) =>
165- val nameOfSyntheticGiven = PatMatVarName .fresh()
166- (name.toTypeName, untpd.cpy.Ident (tree.expr)(nameOfSyntheticGiven))
167- case expr =>
168- report.error(" expected a name binding" , expr.srcPos)
169- (" $error" .toTypeName, expr)
170- }
171-
172- val typeSymInfo = pt match
173- case pt : TypeBounds => pt
174- case _ => TypeBounds .empty
175- val typeSym = newSymbol(spliceOwner(ctx), name, EmptyFlags , typeSymInfo, NoSymbol , tree.expr.span)
176- typeSym.addAnnotation(Annotation (New (ref(defn.InternalQuotedPatterns_patternTypeAnnot .typeRef)).withSpan(tree.expr.span)))
177- val pat = typedPattern(expr, defn.QuotedTypeClass .typeRef.appliedTo(typeSym.typeRef))(
178- using spliceContext.retractMode(Mode .QuotedPattern ).withOwner(spliceOwner(ctx)))
179- pat.select(tpnme.Underlying )
161+ report.error(
162+ """ `$` for quote pattern varable is not supported anymore.
163+ |Use lower cased variable name without the `$` instead.""" .stripMargin,
164+ tree.srcPos)
165+ ref(defn.NothingType )
180166 else
181167 val tree1 = typedSelect(untpd.Select (tree.expr, tpnme.Underlying ), pt)(using spliceContext).withSpan(tree.span)
182168 val msg = em " Consider using canonical type reference ${tree1.tpe} instead "
@@ -185,6 +171,24 @@ trait QuotesAndSplices {
185171 tree1
186172 }
187173
174+ /** Type a pattern variable name `t` in quote pattern as `${given t$giveni: Type[t @ _]}`.
175+ * The resulting pattern is the split in `splitQuotePattern`.
176+ */
177+ def typedQuotedTypeVar (tree : untpd.Ident , pt : Type )(using Context ): Tree =
178+ def spliceOwner (ctx : Context ): Symbol =
179+ if (ctx.mode.is(Mode .QuotedPattern )) spliceOwner(ctx.outer) else ctx.owner
180+ val name = tree.name.toTypeName
181+ val nameOfSyntheticGiven = PatMatGivenVarName .fresh(tree.name.toTermName)
182+ val expr = untpd.cpy.Ident (tree)(nameOfSyntheticGiven)
183+ val typeSymInfo = pt match
184+ case pt : TypeBounds => pt
185+ case _ => TypeBounds .empty
186+ val typeSym = newSymbol(spliceOwner(ctx), name, EmptyFlags , typeSymInfo, NoSymbol , tree.span)
187+ typeSym.addAnnotation(Annotation (New (ref(defn.InternalQuotedPatterns_patternTypeAnnot .typeRef)).withSpan(tree.span)))
188+ val pat = typedPattern(expr, defn.QuotedTypeClass .typeRef.appliedTo(typeSym.typeRef))(
189+ using spliceContext.retractMode(Mode .QuotedPattern ).withOwner(spliceOwner(ctx)))
190+ pat.select(tpnme.Underlying )
191+
188192 private def checkSpliceOutsideQuote (tree : untpd.Tree )(using Context ): Unit =
189193 if (level == 0 && ! ctx.owner.ownersIterator.exists(_.is(Inline )))
190194 report.error(" Splice ${...} outside quotes '{...} or inline method" , tree.srcPos)
@@ -201,17 +205,17 @@ trait QuotesAndSplices {
201205 *
202206 * A quote pattern
203207 * ```
204- * case '{ type ${given t: Type[$ t @ _]}; ${ls: Expr[List[$ t]]} } => ...
208+ * case '{ type ${given t$giveni : Type[t @ _]}; ${ls: Expr[List[t]]} } => ...
205209 * ```
206210 * will return
207211 * ```
208212 * (
209- * Map(<$t >: Symbol -> <$ t @ _>: Bind),
213+ * Map(<t$giveni >: Symbol -> <t @ _>: Bind),
210214 * <'{
211- * @scala.internal.Quoted.patternType type $ t
212- * scala.internal.Quoted.patternHole[List[$ t]]
215+ * @scala.internal.Quoted.patternType type t
216+ * scala.internal.Quoted.patternHole[List[t]]
213217 * }>: Tree,
214- * List(<ls: Expr[List[$ t]]>: Tree)
218+ * List(<ls: Expr[List[t]]>: Tree)
215219 * )
216220 * ```
217221 */
@@ -278,7 +282,7 @@ trait QuotesAndSplices {
278282 tree
279283 case tdef : TypeDef =>
280284 if tdef.symbol.hasAnnotation(defn.InternalQuotedPatterns_patternTypeAnnot ) then
281- transformTypeBindingTypeDef(PatMatVarName .fresh(), tdef, typePatBuf)
285+ transformTypeBindingTypeDef(PatMatGivenVarName .fresh(tdef.name.toTermName ), tdef, typePatBuf)
282286 else if tdef.symbol.isClass then
283287 val kind = if tdef.symbol.is(Module ) then " objects" else " classes"
284288 report.error(" Implementation restriction: cannot match " + kind, tree.srcPos)
@@ -358,38 +362,38 @@ trait QuotesAndSplices {
358362 * within the quotes become patterns again and typed accordingly.
359363 *
360364 * ```
361- * case '{ ($ls: List[$ t]) } =>
362- * // `t` is of type `Type[T$1 ]` for some unknown T$1
363- * // `t` is implicitly available
364- * // `l ` is of type `Expr[List[T$1 ]]`
365+ * case '{ ($ls: List[t]) } =>
366+ * // `t$giveni ` is of type `Type[t ]` for some unknown `t`
367+ * // `t$giveni ` is implicitly available
368+ * // `ls ` is of type `Expr[List[t ]]`
365369 * '{ val h: $t = $ls.head }
366370 * ```
367371 *
368- * For each type splice we will create a new type binding in the pattern match ($ t @ _ in this case)
369- * and a corresponding type in the quoted pattern as a hole (@patternType type $t in this case).
372+ * For each type splice we will create a new type binding in the pattern match (` t @ _` in this case)
373+ * and a corresponding type in the quoted pattern as a hole (` @patternType type t` in this case).
370374 * All these generated types are inserted at the start of the quoted code.
371375 *
372376 * After typing the tree will resemble
373377 *
374378 * ```
375- * case '{ type ${given t: Type[$ t @ _]}; ${ls: Expr[List[$ t]]} } => ...
379+ * case '{ type ${given t$giveni : Type[t @ _]}; ${ls: Expr[List[t]]} } => ...
376380 * ```
377381 *
378382 * Then the pattern is _split_ into the expression contained in the pattern replacing the splices by holes,
379383 * and the patterns in the splices. All these are recombined into a call to `Matcher.unapply`.
380384 *
381385 * ```
382386 * case scala.internal.quoted.Expr.unapply[
383- * Tuple1[$ t @ _], // Type binging definition
384- * Tuple2[Type[$ t], Expr[List[$ t]]] // Typing the result of the pattern match
387+ * Tuple1[t @ _], // Type binging definition
388+ * Tuple2[Type[t], Expr[List[t]]] // Typing the result of the pattern match
385389 * ](
386390 * Tuple2.unapply
387- * [Type[$ t], Expr[List[$ t]]] //Propagated from the tuple above
388- * (implicit t @ _, ls @ _: Expr[List[$ t]]) // from the spliced patterns
391+ * [Type[t], Expr[List[t]]] //Propagated from the tuple above
392+ * (given t$giveni @ _, ls @ _: Expr[List[t]]) // from the spliced patterns
389393 * )(
390394 * '{ // Runtime quote Matcher.unapply uses to mach against. Expression directly inside the quoted pattern without the splices
391- * @scala.internal.Quoted.patternType type $ t
392- * scala.internal.Quoted.patternHole[List[$ t]]
395+ * @scala.internal.Quoted.patternType type t
396+ * scala.internal.Quoted.patternHole[List[t]]
393397 * },
394398 * true, // If there is at least one type splice. Used to instantiate the context with or without GADT constraints
395399 * x$2 // tasty.Reflection instance
@@ -409,7 +413,7 @@ trait QuotesAndSplices {
409413 case _ => defn.AnyType
410414 }
411415 val quoted0 = desugar.quotedPattern(quoted, untpd.TypedSplice (TypeTree (quotedPt)))
412- val quoteCtx = quoteContext.addMode(Mode .QuotedPattern )
416+ val quoteCtx = quoteContext.addMode(Mode .QuotedPattern ).retractMode( Mode . Pattern )
413417 val quoted1 =
414418 if quoted.isType then typedType(quoted0, WildcardType )(using quoteCtx)
415419 else typedExpr(quoted0, WildcardType )(using quoteCtx)
0 commit comments