Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:better error msg for cyclic error for constructors #17131

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/core/TypeErrors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ class CyclicReference private (val denot: SymDenotation)(using Context) extends
val unsafeFlags = cycleSym.flagsUNSAFE
val isMethod = unsafeFlags.is(Method)
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
Expand All @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down
38 changes: 38 additions & 0 deletions compiler/test/dotty/tools/dotc/reporting/CyclicErrorMessages.scala
Original file line number Diff line number Diff line change
@@ -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"))
}
}
Loading