diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 1b7486840bbb..c20fc27f9d1a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -124,6 +124,7 @@ public enum ErrorMessageID { SymbolChangedSemanticsInVersionID, UnableToEmitSwitchID, MissingCompanionForStaticID, + PolymorphicMethodMissingTypeInParentID, ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index b8c6a84e771a..fb8b5705b604 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -2064,4 +2064,14 @@ object messages { val explanation = hl"An object that contains ${"@static"} members must have a companion class." } + + case class PolymorphicMethodMissingTypeInParent(rsym: Symbol, parentSym: Symbol)(implicit ctx: Context) + extends Message(PolymorphicMethodMissingTypeInParentID) { + val kind = "Syntax" + val msg = hl"polymorphic refinement $rsym without matching type in parent $parentSym is no longer allowed" + val explanation = + hl"""Polymorphic $rsym is not allowed in the structural refinement of $parentSym because + |$rsym does not override any method in $parentSym. Structural refinement does not allow for + |polymorphic methods.""" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index fa2cd8f25c5b..345183fd2c05 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1169,7 +1169,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit checkRefinementNonCyclic(refinement, refineCls, seen) val rsym = refinement.symbol if (rsym.info.isInstanceOf[PolyType] && rsym.allOverriddenSymbols.isEmpty) - ctx.error(i"polymorphic refinement $rsym without matching type in parent $tpt1 is no longer allowed", refinement.pos) } + ctx.error(PolymorphicMethodMissingTypeInParent(rsym, tpt1.symbol), refinement.pos) + } assignType(cpy.RefinedTypeTree(tree)(tpt1, refinements1), tpt1, refinements1, refineCls) } diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 69f985e03f61..c94af01eb3cd 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1277,4 +1277,21 @@ class ErrorMessagesTests extends ErrorMessagesTest { val MissingCompanionForStatic(member) = messages.head assertEquals(member.show, "method bar") } + + @Test def polymorphicMethodMissingTypeInParent = + checkMessagesAfter("frontend") { + """ + |object Test { + | import scala.reflect.Selectable.reflectiveSelectable + | def foo(x: { def get[T](a: T): Int }) = 5 + |} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + + assertMessageCount(1, messages) + val PolymorphicMethodMissingTypeInParent(rsym, parentSym) = messages.head + assertEquals("method get", rsym.show) + assertEquals("class Object", parentSym.show) + } }