@@ -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
+ val typeNormalizer = new untpd.UntypedTreeMap {
401
+ override def transform (tpt : untpd.Tree )(using Context ) =
402
+ tpt match
403
+ case untpd.Ident (tpnme.WILDCARD_STAR ) => tpt
404
+ case tpt @ untpd.Ident (name) if name.isTypeName && ! tpt.isBackquoted && name.isVarPattern =>
405
+ variables += name.asTypeName
406
+ tpt.pushAttachment(Trees .Backquoted , ())
407
+ tpt
408
+ case _ : untpd.TypedSplice => tpt
409
+ case _ => super .transform(tpt)
410
+ }
411
+ val termNormalizer = new untpd.UntypedTreeMap {
412
+ override def transform (tree : untpd.Tree )(using Context ) =
413
+ tree match
414
+ case untpd.Splice (_) => tree
415
+ case untpd.Typed (expr, tpt) =>
416
+ untpd.cpy.Typed (tree)(
417
+ super .transform(expr),
418
+ typeNormalizer.transform(tpt)
419
+ )
420
+ case untpd.TypeApply (fn, targs) =>
421
+ untpd.cpy.TypeApply (tree)(
422
+ super .transform(fn),
423
+ targs.map(typeNormalizer.transform)
424
+ )
425
+ case _ => super .transform(tree)
426
+ }
427
+
428
+ val transformed : untpd.Tree =
429
+ if quoted.isType then quoted // FIXME: typeNormalizer.transform(quoted)
430
+ else termNormalizer.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