From 0accbb5f30d4af0d1eae30d45f1c46ba2ffb5433 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 31 May 2020 17:16:52 +0200 Subject: [PATCH 1/3] Fix #9088: Fix problematic code in productMirror --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 2 +- tests/run/poly-kinded-derives.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 8eaa2a0e4b86..ba8a4e53efc2 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -279,7 +279,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): case mirroredType: HKTypeLambda => val elems = mirroredType.derivedLambdaType( - resType = TypeOps.nestedPairs(accessors.map(mirroredType.memberInfo(_).widenExpr)) + resType = TypeOps.nestedPairs(accessors.map(_.info)) ) (mkMirroredMonoType(mirroredType), elems) case _ => diff --git a/tests/run/poly-kinded-derives.scala b/tests/run/poly-kinded-derives.scala index 549e1953c1b7..c98dcb9541e1 100644 --- a/tests/run/poly-kinded-derives.scala +++ b/tests/run/poly-kinded-derives.scala @@ -27,7 +27,7 @@ object Test extends App { given t2 [T] as Functor[[U] =>> (T, U)] {} given t3 [T, U] as Functor[[V] =>> (T, U, V)] {} - def derived[F[_]](using m: Mirror { type MirroredType = F ; type MirroredElemTypes[_] }, r: Functor[m.MirroredElemTypes]): Functor[F] = new Functor[F] {} + def derived[F[_]](using m: Mirror { type MirroredType[X] = F[X] ; type MirroredElemTypes[_] }, r: Functor[m.MirroredElemTypes]): Functor[F] = new Functor[F] {} } case class Mono(i: Int) derives Functor @@ -43,7 +43,7 @@ object Test extends App { given [C] as FunctorK[[F[_]] =>> C] {} given [T] as FunctorK[[F[_]] =>> Tuple1[F[T]]] - def derived[F[_[_]]](using m: Mirror { type MirroredType = F ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {} + def derived[F[_[_]]](using m: Mirror { type MirroredType[X[_]] = F[X] ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {} } case class Mono(i: Int) derives FunctorK @@ -61,7 +61,7 @@ object Test extends App { given t2 as Bifunctor[[T, U] =>> (T, U)] {} given t3 [T] as Bifunctor[[U, V] =>> (T, U, V)] {} - def derived[F[_, _]](using m: Mirror { type MirroredType = F ; type MirroredElemTypes[_, _] }, r: Bifunctor[m.MirroredElemTypes]): Bifunctor[F] = ??? + def derived[F[_, _]](using m: Mirror { type MirroredType[X, Y] = F[X, Y] ; type MirroredElemTypes[_, _] }, r: Bifunctor[m.MirroredElemTypes]): Bifunctor[F] = ??? } case class Mono(i: Int) derives Bifunctor From 9c164450b44579c9062b152cca4b67f8df6baeca Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 31 May 2020 18:04:27 +0200 Subject: [PATCH 2/3] A better fix --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index ba8a4e53efc2..f921f4a8538e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -277,9 +277,11 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString))) val (monoType, elemsType) = mirroredType match case mirroredType: HKTypeLambda => + def accessorType(acc: Symbol) = + acc.info.subst(cls.typeParams, mirroredType.paramRefs) val elems = mirroredType.derivedLambdaType( - resType = TypeOps.nestedPairs(accessors.map(_.info)) + resType = TypeOps.nestedPairs(accessors.map(accessorType)) ) (mkMirroredMonoType(mirroredType), elems) case _ => From 70e2c2b5ad3a2800643cb0ef6ce352abb3ce9dde Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 31 May 2020 18:18:40 +0200 Subject: [PATCH 3/3] Harden new productMirrorCode to work for erroneous code --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index f921f4a8538e..54c459647ec0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -278,7 +278,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): val (monoType, elemsType) = mirroredType match case mirroredType: HKTypeLambda => def accessorType(acc: Symbol) = - acc.info.subst(cls.typeParams, mirroredType.paramRefs) + if cls.typeParams.hasSameLengthAs(mirroredType.paramRefs) then + acc.info.subst(cls.typeParams, mirroredType.paramRefs) + else + acc.info val elems = mirroredType.derivedLambdaType( resType = TypeOps.nestedPairs(accessors.map(accessorType))