diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala index a9dcebd702f7..946a1f6884c6 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala @@ -147,7 +147,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] { StaticFieldsShouldPrecedeNonStaticID, IllegalSuperAccessorID, TraitParameterUsedAsParentPrefixID, - UnknownNamedEnclosingClassOrObjectID + UnknownNamedEnclosingClassOrObjectID, + IllegalCyclicTypeReferenceID def errorNumber = ordinal - 2 } diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 608cd0c1584a..99ccc916e9be 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -2392,4 +2392,11 @@ object messages { |current scope. """.stripMargin } + + case class IllegalCyclicTypeReference(sym: Symbol, where: String, lastChecked: Type)(implicit val ctx: Context) + extends Message(IllegalCyclicTypeReferenceID) { + val kind: String = "Type" + val msg: String = i"illegal cyclic type reference: ${where} ${hl(lastChecked.show)} of $sym refers back to the type itself" + val explanation: String = "" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 8edcba80bc57..5d9a0ad11c1a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -300,7 +300,7 @@ object Checking { catch { case ex: CyclicReference => if (reportErrors) - errorType(i"illegal cyclic reference: ${checker.where} ${checker.lastChecked} of $sym refers back to the type itself", sym.sourcePos) + errorType(IllegalCyclicTypeReference(sym, checker.where, checker.lastChecked), sym.sourcePos) else info } } diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index b56a103468a1..31156bbae6b2 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1672,4 +1672,19 @@ class ErrorMessagesTests extends ErrorMessagesTest { val UnknownNamedEnclosingClassOrObject(name) :: Nil = messages assertEquals("doesNotExist", name.show) } + + @Test def illegalCyclicTypeReference() = + checkMessagesAfter(RefChecks.name) { + """ + |type X = List[X] + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(1, messages) + val IllegalCyclicTypeReference(sym, where, lastChecked) :: Nil = messages + assertEquals("type X", sym.show) + assertEquals("alias", where) + assertEquals("List[X]", lastChecked.show) + } }