@@ -11,7 +11,7 @@ import dotty.tools.dotc.core.Constants._
11
11
import dotty .tools .dotc .core .Contexts ._
12
12
import dotty .tools .dotc .core .Decorators ._
13
13
import dotty .tools .dotc .core .Flags ._
14
- import dotty .tools .dotc .core .NameKinds .{UniqueName , PatMatVarName }
14
+ import dotty .tools .dotc .core .NameKinds .{UniqueName , PatMatGivenVarName }
15
15
import dotty .tools .dotc .core .Names ._
16
16
import dotty .tools .dotc .core .StagingContext ._
17
17
import dotty .tools .dotc .core .StdNames ._
@@ -37,7 +37,7 @@ trait QuotesAndSplices {
37
37
38
38
import tpd ._
39
39
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]`
41
41
* while tracking the quotation level in the context.
42
42
*/
43
43
def typedQuote (tree : untpd.Quote , pt : Type )(using Context ): Tree = {
@@ -83,7 +83,7 @@ trait QuotesAndSplices {
83
83
def spliceOwner (ctx : Context ): Symbol =
84
84
if (ctx.mode.is(Mode .QuotedPattern )) spliceOwner(ctx.outer) else ctx.owner
85
85
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)))
87
87
val baseType = pat.tpe.baseType(defn.QuotedExprClass )
88
88
val argType = if baseType != NoType then baseType.argTypesHi.head else defn.NothingType
89
89
ref(defn.InternalQuoted_exprSplice ).appliedToType(argType).appliedTo(pat)
@@ -158,25 +158,11 @@ trait QuotesAndSplices {
158
158
}
159
159
160
160
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 )
180
166
else
181
167
val tree1 = typedSelect(untpd.Select (tree.expr, tpnme.Underlying ), pt)(using spliceContext).withSpan(tree.span)
182
168
val msg = em " Consider using canonical type reference ${tree1.tpe} instead "
@@ -185,6 +171,24 @@ trait QuotesAndSplices {
185
171
tree1
186
172
}
187
173
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
+
188
192
private def checkSpliceOutsideQuote (tree : untpd.Tree )(using Context ): Unit =
189
193
if (level == 0 && ! ctx.owner.ownersIterator.exists(_.is(Inline )))
190
194
report.error(" Splice ${...} outside quotes '{...} or inline method" , tree.srcPos)
@@ -201,17 +205,17 @@ trait QuotesAndSplices {
201
205
*
202
206
* A quote pattern
203
207
* ```
204
- * case '{ type ${given t: Type[$ t @ _]}; ${ls: Expr[List[$ t]]} } => ...
208
+ * case '{ type ${given t$giveni : Type[t @ _]}; ${ls: Expr[List[t]]} } => ...
205
209
* ```
206
210
* will return
207
211
* ```
208
212
* (
209
- * Map(<$t >: Symbol -> <$ t @ _>: Bind),
213
+ * Map(<t$giveni >: Symbol -> <t @ _>: Bind),
210
214
* <'{
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]]
213
217
* }>: Tree,
214
- * List(<ls: Expr[List[$ t]]>: Tree)
218
+ * List(<ls: Expr[List[t]]>: Tree)
215
219
* )
216
220
* ```
217
221
*/
@@ -278,7 +282,7 @@ trait QuotesAndSplices {
278
282
tree
279
283
case tdef : TypeDef =>
280
284
if tdef.symbol.hasAnnotation(defn.InternalQuotedPatterns_patternTypeAnnot ) then
281
- transformTypeBindingTypeDef(PatMatVarName .fresh(), tdef, typePatBuf)
285
+ transformTypeBindingTypeDef(PatMatGivenVarName .fresh(tdef.name.toTermName ), tdef, typePatBuf)
282
286
else if tdef.symbol.isClass then
283
287
val kind = if tdef.symbol.is(Module ) then " objects" else " classes"
284
288
report.error(" Implementation restriction: cannot match " + kind, tree.srcPos)
@@ -358,38 +362,38 @@ trait QuotesAndSplices {
358
362
* within the quotes become patterns again and typed accordingly.
359
363
*
360
364
* ```
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 ]]`
365
369
* '{ val h: $t = $ls.head }
366
370
* ```
367
371
*
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).
370
374
* All these generated types are inserted at the start of the quoted code.
371
375
*
372
376
* After typing the tree will resemble
373
377
*
374
378
* ```
375
- * case '{ type ${given t: Type[$ t @ _]}; ${ls: Expr[List[$ t]]} } => ...
379
+ * case '{ type ${given t$giveni : Type[t @ _]}; ${ls: Expr[List[t]]} } => ...
376
380
* ```
377
381
*
378
382
* Then the pattern is _split_ into the expression contained in the pattern replacing the splices by holes,
379
383
* and the patterns in the splices. All these are recombined into a call to `Matcher.unapply`.
380
384
*
381
385
* ```
382
386
* 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
385
389
* ](
386
390
* 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
389
393
* )(
390
394
* '{ // 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]]
393
397
* },
394
398
* true, // If there is at least one type splice. Used to instantiate the context with or without GADT constraints
395
399
* x$2 // tasty.Reflection instance
@@ -409,7 +413,7 @@ trait QuotesAndSplices {
409
413
case _ => defn.AnyType
410
414
}
411
415
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 )
413
417
val quoted1 =
414
418
if quoted.isType then typedType(quoted0, WildcardType )(using quoteCtx)
415
419
else typedExpr(quoted0, WildcardType )(using quoteCtx)
0 commit comments