Skip to content

Commit 8748dea

Browse files
Refactor split quote symbol mapping (#18104)
Now, the mapping is a `SeqMap[Symbol, Symbol]` to convey its ordering and the `Bind` is created when we are creating the tree of the quote pattern. Follow up of the refactoring in #17956
2 parents 9e06db7 + 9044c4e commit 8748dea

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import dotty.tools.dotc.util.Spans._
2626
import dotty.tools.dotc.util.Stats.record
2727
import dotty.tools.dotc.reporting.IllegalVariableInPatternAlternative
2828
import scala.collection.mutable
29+
import scala.collection.SeqMap
2930

3031
/** Type quotes `'{ ... }` and splices `${ ... }` */
3132
trait QuotesAndSplices {
@@ -206,7 +207,7 @@ trait QuotesAndSplices {
206207
* will return
207208
* ```
208209
* (
209-
* Map(<t$giveni>: Symbol -> <t @ _>: Bind),
210+
* Map(<t$giveni>: Symbol -> <t>: Symbol),
210211
* <'{
211212
* @scala.internal.Quoted.patternType type t
212213
* scala.internal.Quoted.patternHole[List[t]]
@@ -215,10 +216,10 @@ trait QuotesAndSplices {
215216
* )
216217
* ```
217218
*/
218-
private def splitQuotePattern(quoted: Tree)(using Context): (collection.Map[Symbol, Bind], Tree, List[Tree]) = {
219+
private def splitQuotePattern(quoted: Tree)(using Context): (SeqMap[Symbol, Symbol], Tree, List[Tree]) = {
219220
val ctx0 = ctx
220221

221-
val bindSymMapping: collection.Map[Symbol, Bind] = unapplyBindingsMapping(quoted)
222+
val bindSymMapping: SeqMap[Symbol, Symbol] = unapplyBindingsMapping(quoted)
222223

223224
object splitter extends tpd.TreeMap {
224225
private var variance: Int = 1
@@ -298,7 +299,7 @@ trait QuotesAndSplices {
298299
report.error(IllegalVariableInPatternAlternative(tdef.symbol.name), tdef.srcPos)
299300
if variance == -1 then
300301
tdef.symbol.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_fromAboveAnnot.typeRef)).withSpan(tdef.span)))
301-
val bindingType = bindSymMapping(tdef.symbol).symbol.typeRef
302+
val bindingType = bindSymMapping(tdef.symbol).typeRef
302303
val bindingTypeTpe = AppliedType(defn.QuotedTypeClass.typeRef, bindingType :: Nil)
303304
val sym = newPatternBoundSymbol(nameOfSyntheticGiven, bindingTypeTpe, tdef.span, flags = ImplicitVal)(using ctx0)
304305
buff += Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingTypeTpe)).withSpan(tdef.span)
@@ -343,11 +344,12 @@ trait QuotesAndSplices {
343344
* binding that will be as type variable in the encoded `unapply` of the quote pattern.
344345
*
345346
* @return Mapping from type variable symbols defined in the quote pattern into
346-
* type variable `Bind` definitions for the `unapply` of the quote pattern.
347+
* type variable definitions for the `unapply` of the quote pattern.
347348
* This mapping retains the original type variable definition order.
348349
*/
349-
private def unapplyBindingsMapping(quoted: Tree)(using Context): collection.Map[Symbol, Bind] = {
350+
private def unapplyBindingsMapping(quoted: Tree)(using Context): SeqMap[Symbol, Symbol] = {
350351
val mapping = mutable.LinkedHashMap.empty[Symbol, Symbol]
352+
351353
// Collect all existing type variable bindings and create new symbols for them.
352354
// The old info is used, it may contain references to the old symbols.
353355
new tpd.TreeTraverser {
@@ -376,11 +378,7 @@ trait QuotesAndSplices {
376378
newBindings.info = newBindings.info.subst(oldBindings, newBindingsRefs)
377379
ctx.gadtState.addToConstraint(newBindings) // This must be preformed after the info has been updated
378380

379-
// Map into Bind nodes retaining the original order
380-
val mapping2: mutable.Map[Symbol, Bind] = mutable.LinkedHashMap.empty
381-
for (oldSym, newSym) <- mapping do
382-
mapping2(oldSym) = Bind(newSym, untpd.Ident(nme.WILDCARD).withType(newSym.info)).withSpan(quoted.span)
383-
mapping2
381+
mapping
384382
}
385383

386384
/** Type a quote pattern `case '{ <quoted> } =>` qiven the a current prototype. Typing the pattern
@@ -470,20 +468,23 @@ trait QuotesAndSplices {
470468
else tpd.Block(typeTypeVariables, pattern)
471469
}
472470

473-
val (typeBindings, shape, splices) = splitQuotePattern(quoted1)
471+
val (bindSymMapping, shape, splices) = splitQuotePattern(quoted1)
474472

475473
class ReplaceBindings extends TypeMap() {
476474
override def apply(tp: Type): Type = tp match {
477475
case tp: TypeRef =>
478476
val tp1 = if (tp.symbol.isTypeSplice) tp.dealias else tp
479-
mapOver(typeBindings.get(tp1.typeSymbol).fold(tp)(_.symbol.typeRef))
477+
mapOver(bindSymMapping.get(tp1.typeSymbol).fold(tp)(_.typeRef))
480478
case tp => mapOver(tp)
481479
}
482480
}
483481
val replaceBindings = new ReplaceBindings
484482
val patType = defn.tupleType(splices.tpes.map(tpe => replaceBindings(tpe.widen)))
485483

486-
val typeBindingsTuple = tpd.hkNestedPairsTypeTree(typeBindings.values.toList)
484+
val typeBinds = bindSymMapping.values.map(sym =>
485+
Bind(sym, untpd.Ident(nme.WILDCARD).withType(sym.info)).withSpan(quoted.span)
486+
).toList
487+
val typeBindingsTuple = tpd.hkNestedPairsTypeTree(typeBinds)
487488

488489
val replaceBindingsInTree = new TreeMap {
489490
private var bindMap = Map.empty[Symbol, Symbol]

0 commit comments

Comments
 (0)