Skip to content

Commit 1128dbc

Browse files
committed
Fix Mirror.Product for type lambdas
We don't need to guess how the type parameters should be substituted. Instead we can use the result type directly to obtain the member type.
1 parent 1f48de1 commit 1128dbc

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

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

Lines changed: 3 additions & 12 deletions
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)

tests/pos/i13859.scala

Lines changed: 31 additions & 0 deletions
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)