@@ -10,6 +10,7 @@ import dotty.tools.dotc.core.Contexts._
10
10
import dotty .tools .dotc .core .Decorators ._
11
11
import dotty .tools .dotc .core .Flags ._
12
12
import dotty .tools .dotc .core .NameKinds .PatMatGivenVarName
13
+ import dotty .tools .dotc .core .NameOps .isVarPattern
13
14
import dotty .tools .dotc .core .Names ._
14
15
import dotty .tools .dotc .core .StagingContext ._
15
16
import dotty .tools .dotc .core .StdNames ._
@@ -24,7 +25,6 @@ import dotty.tools.dotc.util.Stats.record
24
25
import dotty .tools .dotc .reporting .IllegalVariableInPatternAlternative
25
26
import scala .collection .mutable
26
27
27
-
28
28
/** Type quotes `'{ ... }` and splices `${ ... }` */
29
29
trait QuotesAndSplices {
30
30
self : Typer =>
@@ -394,9 +394,84 @@ trait QuotesAndSplices {
394
394
}
395
395
val quoted0 = desugar.quotedPattern(quoted, untpd.TypedSplice (TypeTree (quotedPt)))
396
396
val quoteCtx = quoteContext.addMode(Mode .QuotedPattern ).retractMode(Mode .Pattern )
397
+
398
+ def normalizeTypeBindings (quoted : untpd.Tree ): untpd.Tree =
399
+ val variables = mutable.Set .empty[TypeName ] // TODO use stable order
400
+ def normalizeType (tpt : untpd.Tree ): untpd.Tree =
401
+ new untpd.UntypedTreeMap {
402
+ override def transform (tpt : untpd.Tree )(using Context ) =
403
+ tpt match
404
+ case untpd.Ident (tpnme.WILDCARD_STAR ) => tpt
405
+ case tpt @ untpd.Ident (name) if ! tpt.isBackquoted && name.isVarPattern =>
406
+ variables += name.asTypeName
407
+ tpt.pushAttachment(Trees .Backquoted , ())
408
+ tpt
409
+ case _ : untpd.TypedSplice => tpt
410
+ case _ =>
411
+ super .transform(tpt)
412
+ }.transform(tpt)
413
+ val transformed : untpd.Tree = new untpd.UntypedTreeMap {
414
+ override def transform (tree : untpd.Tree )(using Context ) =
415
+ // println("- " + tree.show)
416
+ // println("- " + tree)
417
+ tree match
418
+ case untpd.Splice (_) => tree
419
+ case untpd.Typed (expr, tpt) =>
420
+ untpd.cpy.Typed (tree)(
421
+ super .transform(expr),
422
+ normalizeType(tpt)
423
+ )
424
+ case untpd.TypeApply (fn, targs) =>
425
+ untpd.cpy.TypeApply (tree)(
426
+ super .transform(fn),
427
+ targs.map(normalizeType)
428
+ )
429
+ case _ => super .transform(tree)
430
+ }.transform(quoted)
431
+
432
+ def typeBindingDefinedInSource : List [TypeName ] =
433
+ transformed match
434
+ case untpd.Block (stats, _) =>
435
+ stats.takeWhile {
436
+ case untpd.TypeDef (name, _) => name.isVarPattern
437
+ case _ => false
438
+ }.map(_.asInstanceOf [untpd.TypeDef ].name.asTypeName)
439
+ case _ => Nil
440
+ variables --= typeBindingDefinedInSource
441
+
442
+ // println("==============")
443
+ // println(quoted.show)
444
+ // println(quoted)
445
+ // println("--------------")
446
+ // println(transformed.show)
447
+ // println(transformed)
448
+ // println(" ")
449
+ // println(variables)
450
+ // println(" ")
451
+
452
+ if variables.isEmpty then transformed
453
+ else
454
+ transformed match
455
+ case untpd.Block (stats, expr) =>
456
+ val typeBindings = stats.takeWhile {
457
+ case untpd.TypeDef (name, _) => name.isVarPattern
458
+ case _ => false
459
+ }
460
+ variables --= typeBindings.map(_.asInstanceOf [untpd.TypeDef ].name.asTypeName)
461
+ untpd.cpy.Block (quoted)(
462
+ variables.toList.map(name => untpd.TypeDef (name, untpd.TypeBoundsTree (untpd.EmptyTree , untpd.EmptyTree , untpd.EmptyTree ))) ::: stats,
463
+ expr
464
+ )
465
+ case _ =>
466
+ untpd.cpy.Block (quoted)(
467
+ variables.toList.map(name => untpd.TypeDef (name, untpd.TypeBoundsTree (untpd.EmptyTree , untpd.EmptyTree , untpd.EmptyTree ))),
468
+ transformed
469
+ )
470
+
471
+ val quoted0normalized = normalizeTypeBindings(quoted0)
397
472
val quoted1 =
398
- if quoted.isType then typedType(quoted0 , WildcardType )(using quoteCtx)
399
- else typedExpr(quoted0 , WildcardType )(using quoteCtx)
473
+ if quoted.isType then typedType(quoted0normalized , WildcardType )(using quoteCtx)
474
+ else typedExpr(quoted0normalized , WildcardType )(using quoteCtx)
400
475
401
476
val (typeBindings, shape, splices) = splitQuotePattern(quoted1)
402
477
0 commit comments