diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 54821444aed6..8495726b7b0f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -2020,14 +2020,24 @@ final class SearchRoot extends SearchHistory: val nsyms = vsyms.map(vsym => newSymbol(classSym, vsym.name, EmptyFlags, vsym.info, coord = span).entered) val vsymMap = (vsyms zip nsyms).toMap + def substVsymRefs(t: tpd.Tree, termRefMap: TermRef => Type, identMap: Ident => tpd.Tree): tpd.Tree = + new TreeTypeMap( + typeMap = new TypeMap { + def apply(tp: Type): Type = tp match + case ref: TermRef if vsymMap.contains(ref.symbol) => termRefMap(ref) + case _ => mapOver(tp) + }, + treeMap = { + case id: Ident if vsymMap.contains(id.symbol) => identMap(id) + case tree => tree + })(t) + val rhss = pruned.map(_._2) // Substitute dictionary references into dictionary entry RHSs - val rhsMap = new TreeTypeMap(treeMap = { - case id: Ident if vsymMap.contains(id.symbol) => - tpd.ref(vsymMap(id.symbol))(using ctx.withSource(id.source)).withSpan(id.span) - case tree => tree - }) - val nrhss = rhss.map(rhsMap(_)) + val nrhss = rhss.map(substVsymRefs( + _, + ref => classSym.thisType.select(vsymMap(ref.symbol)), + id => tpd.ref(vsymMap(id.symbol))(using ctx.withSource(id.source)).withSpan(id.span))) val vdefs = (nsyms zip nrhss) map { case (nsym, nrhs) => ValDef(nsym.asTerm, nrhs.changeNonLocalOwners(nsym)) @@ -2040,13 +2050,10 @@ final class SearchRoot extends SearchHistory: val inst = ValDef(valSym, New(classSym.typeRef, Nil)) // Substitute dictionary references into outermost result term. - val resMap = new TreeTypeMap(treeMap = { - case id: Ident if vsymMap.contains(id.symbol) => - Select(tpd.ref(valSym), id.name) - case tree => tree - }) - - val res = resMap(success.tree) + val res = substVsymRefs( + success.tree, + ref => valSym.termRef.select(vsymMap(ref.symbol)), + id => Select(tpd.ref(valSym), id.name)) val blk = Block(classDef :: inst :: Nil, res).withSpan(span) diff --git a/tests/pos/i20448.scala b/tests/pos/i20448.scala new file mode 100644 index 000000000000..9bf078fef7a5 --- /dev/null +++ b/tests/pos/i20448.scala @@ -0,0 +1,31 @@ +trait Generic[T] { + type Repr +} + +object Generic { + type Aux[T, R] = Generic[T] { type Repr = R } + + inline given [T <: Product]( + using m: scala.deriving.Mirror.ProductOf[T] + ): Generic.Aux[T, m.MirroredElemTypes] = ??? +} + +trait Delta[In] { + type Out +} + +object Delta { + type Aux[In, Out0] = Delta[In] { type Out = Out0 } + + given [T](using deltaT: Delta[T]): Delta.Aux[Option[T], deltaT.Out] = ??? + + given [H, T <: Tuple, HO](using deltaH: => Delta.Aux[H, HO]): Delta.Aux[H *: T, H] = ??? + + given [F, G, O]( using gen: Generic.Aux[F, G], genDelta: Delta.Aux[G, O]): Delta.Aux[F, O] = ??? +} + +object Test { + case class Bar(of: Option[Bar]) + + summon[Delta[Bar]] +}