From 712cf58559a81090b9731782803d06d1e349ac53 Mon Sep 17 00:00:00 2001 From: Olivier Blanvillain Date: Fri, 30 Apr 2021 19:06:45 +0200 Subject: [PATCH 1/2] Fix #7380: Check type members of mirror formals --- .../src/dotty/tools/dotc/typer/Synthesizer.scala | 11 ++++++++++- tests/neg/7380.scala | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/neg/7380.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 0406c98d790b..62749190749e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -219,6 +219,12 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): case _ => true loop(formal) + private def checkRefinement(formal: Type, name: TypeName, expected: Type, span: Span)(using Context): Unit = + val actual = formal.lookupRefined(name) + if actual.exists && !(expected =:= actual) + then report.error( + em"$name missmatch, expected: $expected, found: $actual.", ctx.source.atSpan(span)) + private def mkMirroredMonoType(mirroredType: HKTypeLambda)(using Context): Type = val monoMap = new TypeMap: def apply(t: Type) = t match @@ -260,10 +266,13 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): case _ => val elems = TypeOps.nestedPairs(accessors.map(mirroredType.memberInfo(_).widenExpr)) (mirroredType, elems) + val elemsLabels = TypeOps.nestedPairs(elemLabels) + checkRefinement(formal, tpnme.MirroredElemTypes, elemsType, span) + checkRefinement(formal, tpnme.MirroredElemLabels, elemsLabels, span) val mirrorType = mirrorCore(defn.Mirror_ProductClass, monoType, mirroredType, cls.name, formal) .refinedWith(tpnme.MirroredElemTypes, TypeAlias(elemsType)) - .refinedWith(tpnme.MirroredElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels))) + .refinedWith(tpnme.MirroredElemLabels, TypeAlias(elemsLabels)) val mirrorRef = if (cls.is(Scala2x)) anonymousMirror(monoType, ExtendsProductMirror, span) else companionPath(mirroredType, span) diff --git a/tests/neg/7380.scala b/tests/neg/7380.scala new file mode 100644 index 000000000000..20f64db90447 --- /dev/null +++ b/tests/neg/7380.scala @@ -0,0 +1,14 @@ +import scala.deriving.Mirror + +object Test { + summon[Mirror.Of[(Int, String)] { + type MirroredElemTypes = (Int, Int, Int) + }] // error + // MirroredElemTypes missmatch, expected: (Int, String), found: (Int, Int, Int). + + summon[Mirror.Of[(Int, String)] { + type MirroredElemLabels = ("_1", "_2", "_3") + }] // error + // MirroredElemLabels missmatch, expected: (("_1" : String), ("_2" : String)), + // found: (("_1" : String), ("_2" : String), ("_3" : String)). +} From 1afccfaa0964310bef5e19a495af95ed4565363d Mon Sep 17 00:00:00 2001 From: Olivier Blanvillain Date: Mon, 3 May 2021 15:44:45 +0200 Subject: [PATCH 2/2] Update compiler/src/dotty/tools/dotc/typer/Synthesizer.scala Co-authored-by: Guillaume Martres --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 62749190749e..629f8dbad3cc 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -223,7 +223,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): val actual = formal.lookupRefined(name) if actual.exists && !(expected =:= actual) then report.error( - em"$name missmatch, expected: $expected, found: $actual.", ctx.source.atSpan(span)) + em"$name mismatch, expected: $expected, found: $actual.", ctx.source.atSpan(span)) private def mkMirroredMonoType(mirroredType: HKTypeLambda)(using Context): Type = val monoMap = new TypeMap: