From fd843241ff4c9d346091955cb386af532336f29a Mon Sep 17 00:00:00 2001 From: Eugene Flesselle Date: Tue, 9 Apr 2024 18:52:11 +0200 Subject: [PATCH 1/2] Add explanation to checkCaseClassInheritanceInvariant error msg Closes #18552 which was actually not an error, see: https://github.com/scala/scala3/blob/73882c5b62b8cd96031ad975f7677949433a9f21/compiler/src/dotty/tools/dotc/typer/RefChecks.scala#L889-L893 Co-authored-by: Anna Herlihy Co-authored-by: Natsu Kagami --- .../src/dotty/tools/dotc/typer/RefChecks.scala | 17 ++++++++++------- tests/neg/i18552.check | 12 ++++++++++++ tests/neg/i18552.scala | 9 +++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/neg/i18552.check create mode 100644 tests/neg/i18552.scala diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 173d5e6b1f7e..4af4d11a3d9c 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -891,11 +891,14 @@ object RefChecks { * can assume invariant refinement for case classes in `constrainPatternType`. */ def checkCaseClassInheritanceInvariant() = - for (caseCls <- clazz.info.baseClasses.tail.find(_.is(Case))) - for (baseCls <- caseCls.info.baseClasses.tail) - if (baseCls.typeParams.exists(_.paramVarianceSign != 0)) - for (problem <- variantInheritanceProblems(baseCls, caseCls, "non-variant", "case ")) - report.errorOrMigrationWarning(problem, clazz.srcPos, MigrationVersion.Scala2to3) + for + caseCls <- clazz.info.baseClasses.tail.find(_.is(Case)) + baseCls <- caseCls.info.baseClasses.tail + if baseCls.typeParams.exists(_.paramVarianceSign != 0) + problem <- variantInheritanceProblems(baseCls, caseCls, i"base $baseCls", "case ") + withExplain = problem.appendExplanation: + "Refining a basetype of a case class is not allowed, enabling better GADT constraints in case class patterns." + do report.errorOrMigrationWarning(withExplain, clazz.srcPos, MigrationVersion.Scala2to3) checkNoAbstractMembers() if (abstractErrors.isEmpty) checkNoAbstractDecls(clazz) @@ -924,7 +927,7 @@ object RefChecks { for { cls <- clazz.info.baseClasses.tail if cls.paramAccessors.nonEmpty && !mixins.contains(cls) - problem <- variantInheritanceProblems(cls, clazz.asClass.superClass, "parameterized", "super") + problem <- variantInheritanceProblems(cls, clazz.asClass.superClass, i"parameterized base $cls", "super") } report.error(problem, clazz.srcPos) } @@ -947,7 +950,7 @@ object RefChecks { if (combinedBT =:= thisBT) None // ok else Some( - em"""illegal inheritance: $clazz inherits conflicting instances of $baseStr base $baseCls. + em"""illegal inheritance: $clazz inherits conflicting instances of $baseStr. | | Direct basetype: $thisBT | Basetype via $middleStr$middle: $combinedBT""") diff --git a/tests/neg/i18552.check b/tests/neg/i18552.check new file mode 100644 index 000000000000..85b422a6ccde --- /dev/null +++ b/tests/neg/i18552.check @@ -0,0 +1,12 @@ +-- Error: tests/neg/i18552.scala:9:6 ----------------------------------------------------------------------------------- +9 |class MB(id:Int) extends MA(id) with M[B] // error + | ^ + | illegal inheritance: class MB inherits conflicting instances of base trait M. + | + | Direct basetype: M[B] + | Basetype via case class MA: M[A] + |--------------------------------------------------------------------------------------------------------------------- + | Explanation (enabled by `-explain`) + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Refining a basetype of a case class is not allowed, enabling better GADT constraints in case class patterns. + --------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i18552.scala b/tests/neg/i18552.scala new file mode 100644 index 000000000000..29f928e1dcfa --- /dev/null +++ b/tests/neg/i18552.scala @@ -0,0 +1,9 @@ +//> using options -explain + +trait A +trait B extends A + +trait M[+T] + +case class MA(id:Int) extends M[A] +class MB(id:Int) extends MA(id) with M[B] // error From cbcc8c85cbc4bc4e8ae9c5f0ca7d3ec2f5df8ba9 Mon Sep 17 00:00:00 2001 From: Eugene Flesselle Date: Wed, 10 Apr 2024 11:33:56 +0200 Subject: [PATCH 2/2] Rephrase explanation msg --- compiler/src/dotty/tools/dotc/typer/RefChecks.scala | 3 ++- tests/neg/i18552.check | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 4af4d11a3d9c..7fd0cb940680 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -897,7 +897,8 @@ object RefChecks { if baseCls.typeParams.exists(_.paramVarianceSign != 0) problem <- variantInheritanceProblems(baseCls, caseCls, i"base $baseCls", "case ") withExplain = problem.appendExplanation: - "Refining a basetype of a case class is not allowed, enabling better GADT constraints in case class patterns." + """Refining a basetype of a case class is not allowed. + |This is a limitation that enables better GADT constraints in case class patterns""".stripMargin do report.errorOrMigrationWarning(withExplain, clazz.srcPos, MigrationVersion.Scala2to3) checkNoAbstractMembers() if (abstractErrors.isEmpty) diff --git a/tests/neg/i18552.check b/tests/neg/i18552.check index 85b422a6ccde..a7a04ed78b47 100644 --- a/tests/neg/i18552.check +++ b/tests/neg/i18552.check @@ -8,5 +8,6 @@ |--------------------------------------------------------------------------------------------------------------------- | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Refining a basetype of a case class is not allowed, enabling better GADT constraints in case class patterns. + | Refining a basetype of a case class is not allowed. + | This is a limitation that enables better GADT constraints in case class patterns ---------------------------------------------------------------------------------------------------------------------