Skip to content

Commit 1003d7c

Browse files
authored
Merge pull request #14003 from joroKr21/product-mirror
Fix Mirror.Product for type lambdas
2 parents 4437469 + 1139338 commit 1003d7c

File tree

3 files changed

+42
-13
lines changed

3 files changed

+42
-13
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

+7
Original file line numberDiff line numberDiff line change
@@ -829,4 +829,11 @@ object TypeOps:
829829
def nestedPairs(ts: List[Type])(using Context): Type =
830830
ts.foldRight(defn.EmptyTupleModule.termRef: Type)(defn.PairClass.typeRef.appliedTo(_, _))
831831

832+
class StripTypeVarsMap(using Context) extends TypeMap:
833+
def apply(tp: Type) = mapOver(tp).stripTypeVar
834+
835+
/** Apply [[Type.stripTypeVar]] recursively. */
836+
def stripTypeVars(tp: Type)(using Context): Type =
837+
new StripTypeVarsMap().apply(tp)
838+
832839
end TypeOps

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

+4-13
Original file line numberDiff line numberDiff line change
@@ -249,21 +249,12 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
249249
val cls = mirroredType.classSymbol
250250
val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal))
251251
val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString)))
252+
val nestedPairs = TypeOps.nestedPairs(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))
252253
val (monoType, elemsType) = mirroredType match
253254
case mirroredType: HKTypeLambda =>
254-
def accessorType(acc: Symbol) =
255-
if cls.typeParams.hasSameLengthAs(mirroredType.paramRefs) then
256-
acc.info.subst(cls.typeParams, mirroredType.paramRefs)
257-
else
258-
acc.info
259-
val elems =
260-
mirroredType.derivedLambdaType(
261-
resType = TypeOps.nestedPairs(accessors.map(accessorType))
262-
)
263-
(mkMirroredMonoType(mirroredType), elems)
255+
(mkMirroredMonoType(mirroredType), mirroredType.derivedLambdaType(resType = nestedPairs))
264256
case _ =>
265-
val elems = TypeOps.nestedPairs(accessors.map(mirroredType.memberInfo(_).widenExpr))
266-
(mirroredType, elems)
257+
(mirroredType, nestedPairs)
267258
val elemsLabels = TypeOps.nestedPairs(elemLabels)
268259
checkRefinement(formal, tpnme.MirroredElemTypes, elemsType, span)
269260
checkRefinement(formal, tpnme.MirroredElemLabels, elemsLabels, span)
@@ -344,7 +335,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
344335
(using Context): Tree =
345336
if checkFormal(formal) then
346337
formal.member(tpnme.MirroredType).info match
347-
case TypeBounds(mirroredType, _) => synth(mirroredType.stripTypeVar, formal, span)
338+
case TypeBounds(mirroredType, _) => synth(TypeOps.stripTypeVars(mirroredType), formal, span)
348339
case other => EmptyTree
349340
else EmptyTree
350341

tests/pos/i13859.scala

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import scala.deriving.*
2+
3+
object Test:
4+
type Kind1[C, O[_]] = C {
5+
type MirroredType[X] = O[X]
6+
type MirroredMonoType = O[Any]
7+
type MirroredElemTypes[_] <: Tuple
8+
}
9+
10+
type Kind2[C, O[_, _]] = C {
11+
type MirroredType[X, Y] = O[X, Y]
12+
type MirroredMonoType = O[Any, Any]
13+
type MirroredElemTypes[_, _] <: Tuple
14+
}
15+
16+
type Test[X] = (X, Boolean)
17+
type Swap[X, Y] = (Y, X)
18+
19+
locally {
20+
val x = summon[Kind1[Mirror.Product, Test]]
21+
x: Mirror.Product {
22+
type MirroredElemTypes[X] = (X, Boolean)
23+
}
24+
}
25+
26+
locally {
27+
val x = summon[Kind2[Mirror.Product, Swap]]
28+
x: Mirror.Product {
29+
type MirroredElemTypes[X, Y] = (Y, X)
30+
}
31+
}

0 commit comments

Comments
 (0)