From 5d0c47a3d4b8486357e31ce91e853a62d013d5f9 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Mon, 8 Apr 2024 19:24:59 +0200 Subject: [PATCH 1/2] Fix infinite loop in Mirror synthesis of unreducible match type This regressed in f7e2e7ce752f9c472c06fe1685464879fa06f6f7 (present in 3.4.0). --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 2 +- tests/neg/i19198.scala | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i19198.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index c94724faf4d4..61cba4c80203 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -379,7 +379,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): // avoid type aliases for tuples Right(MirrorSource.GenericTuple(types)) case _ => reduce(tp.underlying) - case tp: MatchType => reduce(tp.normalized) + case tp: MatchType => reduce(tp.tryNormalize.orElse(tp.superType)) case _ => reduce(tp.superType) case tp @ AndType(l, r) => for diff --git a/tests/neg/i19198.scala b/tests/neg/i19198.scala new file mode 100644 index 000000000000..ad5ee29bb042 --- /dev/null +++ b/tests/neg/i19198.scala @@ -0,0 +1,9 @@ +import deriving.Mirror +import compiletime.summonInline + +type DoesNotReduce[T] = T match + case String => Any + +class Foo +@main def Test: Unit = + summonInline[Mirror.Of[DoesNotReduce[Option[Int]]]] // error From 4699140dcdc76e00d3a85f3eeab25d843b938e5a Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Mon, 8 Apr 2024 20:43:52 +0200 Subject: [PATCH 2/2] Do not assume the superType of a match type gives us a sound mirror --- compiler/src/dotty/tools/dotc/typer/Synthesizer.scala | 4 +++- tests/neg/i19198.scala | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 61cba4c80203..d244af12dd91 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -379,7 +379,9 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): // avoid type aliases for tuples Right(MirrorSource.GenericTuple(types)) case _ => reduce(tp.underlying) - case tp: MatchType => reduce(tp.tryNormalize.orElse(tp.superType)) + case tp: MatchType => + val n = tp.tryNormalize + if n.exists then reduce(n) else Left(i"its subpart `$tp` is an unreducible match type.") case _ => reduce(tp.superType) case tp @ AndType(l, r) => for diff --git a/tests/neg/i19198.scala b/tests/neg/i19198.scala index ad5ee29bb042..be4fc1602697 100644 --- a/tests/neg/i19198.scala +++ b/tests/neg/i19198.scala @@ -4,6 +4,10 @@ import compiletime.summonInline type DoesNotReduce[T] = T match case String => Any +type DoesNotReduce2[T] <: T = T match + case String => T + class Foo @main def Test: Unit = summonInline[Mirror.Of[DoesNotReduce[Option[Int]]]] // error + summonInline[Mirror.Of[DoesNotReduce2[Option[Int]]]] // error