From f6a725e0d3d1d234e377d64746494b55def6ba8c Mon Sep 17 00:00:00 2001 From: doofin <8177dph@gmail.com> Date: Wed, 15 Mar 2023 20:25:36 +0100 Subject: [PATCH 1/3] fix:better error msg for cyclic error for constructors --- compiler/src/dotty/tools/dotc/core/TypeErrors.scala | 7 ++++++- compiler/src/dotty/tools/dotc/reporting/messages.scala | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index 24a207da6836..baa2d85080e7 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -140,8 +140,11 @@ class CyclicReference private (val denot: SymDenotation)(using Context) extends // cycleSym.flags would try completing denot and would fail, but here we can use flagsUNSAFE to detect flags // set by the parser. val unsafeFlags = cycleSym.flagsUNSAFE - val isMethod = unsafeFlags.is(Method) + val isMethod = unsafeFlags.is(Method) // sometimes,isMethod and isConstructor can both be true! val isVal = !isMethod && cycleSym.isTerm + val isConstructor = cycleSym.isConstructor + + // println("isMethod?"+isMethod+",isConstr:"+isConstructor) /* This CyclicReference might have arisen from asking for `m`'s type while trying to infer it. * To try to diagnose this, walk the context chain searching for context in @@ -154,6 +157,8 @@ class CyclicReference private (val denot: SymDenotation)(using Context) extends case tree: untpd.ValOrDefDef if !tree.tpt.typeOpt.exists => if (inImplicitSearch) TermMemberNeedsResultTypeForImplicitSearch(cycleSym) + else if (isConstructor) + CyclicMsgUnknownBug(cycleSym) else if (isMethod) OverloadedOrRecursiveMethodNeedsResultType(cycleSym) else if (isVal) diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 4d5e77ef2c49..b631b91be43a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -1231,6 +1231,14 @@ extends CyclicMsg(OverloadedOrRecursiveMethodNeedsResultTypeID) { |""" } +class CyclicMsgUnknownBug(cycleSym: Symbol)(using Context) +extends CyclicMsg(OverloadedOrRecursiveMethodNeedsResultTypeID) { + def msg(using Context) = i"""Compiler bug: unknown cyclic error for $cycleSym. please report""" + def explain(using Context) = + i"""|For temporary fix, add type annotations to areas involving this constructor + """ +} + class RecursiveValueNeedsResultType(cycleSym: Symbol)(using Context) extends CyclicMsg(RecursiveValueNeedsResultTypeID) { def msg(using Context) = i"""Recursive $cycleSym needs type""" From 7bca6b330919f04e248ed1ae5b90142bd10b24fd Mon Sep 17 00:00:00 2001 From: doofin <8177dph@gmail.com> Date: Sat, 29 Apr 2023 22:26:16 +0200 Subject: [PATCH 2/3] test:add test for error msg for cyclic error --- .../dotc/reporting/CyclicErrorMessages.scala | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 compiler/test/dotty/tools/dotc/reporting/CyclicErrorMessages.scala diff --git a/compiler/test/dotty/tools/dotc/reporting/CyclicErrorMessages.scala b/compiler/test/dotty/tools/dotc/reporting/CyclicErrorMessages.scala new file mode 100644 index 000000000000..65cd3abe981e --- /dev/null +++ b/compiler/test/dotty/tools/dotc/reporting/CyclicErrorMessages.scala @@ -0,0 +1,38 @@ +package dotty.tools +package dotc +package reporting + +import dotty.tools.dotc.core.Contexts.Context +import org.junit.Assert._ +import org.junit.Test + +/*better error message for cyclic errors when using exports as in #17076 */ +class CyclicErrorMessages extends ErrorMessagesTest { + @Test def cyclicErrMsg = + checkMessagesAfter("typer") { + """object A { + | def bar(x: B.Foo[Int]) = x + |} + | + |object B { + | import C.* + | case class Foo[T <: Int](x: Any) + | def foo = Foo(0) + |} + | + |object C extends D.Foo[Int](0) + | + |object D { + | export B.foo + | type Foo[T <: Int] = B.Foo[T] + |} + """.stripMargin + }.expect { (itcx, messages) => + given Context = itcx + + assertMessageCount(2, messages) + val msg = messages.head.message + + assertTrue(msg.contains("Compiler bug: unknown cyclic error")) + } +} From 037be3f5c2771e729813c6fd99b9f73fe269cb10 Mon Sep 17 00:00:00 2001 From: eason du <8177dph@gmail.com> Date: Sun, 29 Oct 2023 22:59:55 +0100 Subject: [PATCH 3/3] rm comments in TypeErrors.scala --- compiler/src/dotty/tools/dotc/core/TypeErrors.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index baa2d85080e7..7043e944f180 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -140,7 +140,7 @@ class CyclicReference private (val denot: SymDenotation)(using Context) extends // cycleSym.flags would try completing denot and would fail, but here we can use flagsUNSAFE to detect flags // set by the parser. val unsafeFlags = cycleSym.flagsUNSAFE - val isMethod = unsafeFlags.is(Method) // sometimes,isMethod and isConstructor can both be true! + val isMethod = unsafeFlags.is(Method) val isVal = !isMethod && cycleSym.isTerm val isConstructor = cycleSym.isConstructor