Skip to content

Commit e31a485

Browse files
committed
Better diagnosis for cyclic references caused by implicit search
Since we now allow to drop the explicit type of a local implicit val it can happen that this causes a cyclic reference, namely when the typechecking of the right-hand side involves an implicit search. It's unpractical and fragile to avoid this. Instead we give now a nice error message explaining the problem and how to fix it in source code.
1 parent 4c1bf42 commit e31a485

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ object ErrorReporting {
4646
errorMsg(msg, cx.outer)
4747
}
4848
} else msg
49-
errorMsg(ex.show, ctx)
49+
50+
if (cycleSym.is(Implicit, butNot = Method) && cycleSym.owner.isTerm)
51+
em"""cyclic reference involving implicit $cycleSym
52+
|This happens when the right hand-side of $cycleSym's definition involves an implicit search.
53+
|To avoid the error, give $cycleSym an explicit type."""
54+
else
55+
errorMsg(ex.show, ctx)
5056
}
5157

5258
def wrongNumberOfArgs(fntpe: Type, kind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,6 @@ class Namer { typer: Typer =>
10011001
def missingType(modifier: String) = {
10021002
ctx.error(s"${modifier}type of implicit definition needs to be given explicitly", mdef.pos)
10031003
sym.resetFlag(Implicit)
1004-
10051004
}
10061005
if (sym is Implicit)
10071006
mdef match {

tests/neg/implicitDefs.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,11 @@ object implicitDefs {
88
implicit val x = 2 // error: type of implicit definition needs to be given explicitly
99
implicit def y(x: Int) = 3 // error: result type of implicit definition needs to be given explicitly
1010
implicit def z(a: x.type): String = "" // error: implicit conversion may not have a parameter of singleton type
11+
12+
def foo(implicit x: String) = 1
13+
14+
def bar() = {
15+
implicit val x = foo
16+
x
17+
}
1118
}

0 commit comments

Comments
 (0)