Skip to content

Commit 2390de2

Browse files
committed
Flag missing parent type of implicit object as error
Implicit objects should not allow parent types to be computed from argument expressions of an application. This is analogous to demanding an explicit type for implicit vals and defs.
1 parent dc1bf9f commit 2390de2

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,11 @@ class Namer { typer: Typer =>
718718
localCtx
719719
}
720720

721+
def missingType(sym: Symbol, modifier: String)(implicit ctx: Context) = {
722+
ctx.error(s"${modifier}type of implicit definition needs to be given explicitly", sym.pos)
723+
sym.resetFlag(Implicit)
724+
}
725+
721726
/** The completer of a symbol defined by a member def or import (except ClassSymbols) */
722727
class Completer(val original: Tree)(implicit ctx: Context) extends LazyType {
723728

@@ -851,7 +856,11 @@ class Namer { typer: Typer =>
851856
val targs1 = targs map (typedAheadType(_))
852857
val ptype = typedAheadType(tpt).tpe appliedTo targs1.tpes
853858
if (ptype.typeParams.isEmpty) ptype
854-
else fullyDefinedType(typedAheadExpr(parent).tpe, "class parent", parent.pos)
859+
else {
860+
if (denot.is(ModuleClass) && denot.sourceModule.is(Implicit))
861+
missingType(denot.symbol, "parent ")(creationContext)
862+
fullyDefinedType(typedAheadExpr(parent).tpe, "class parent", parent.pos)
863+
}
855864
}
856865

857866
/* Check parent type tree `parent` for the following well-formedness conditions:
@@ -1080,14 +1089,10 @@ class Namer { typer: Typer =>
10801089
lhsType // keep constant types that fill in for a non-constant (to be revised when inline has landed).
10811090
else inherited
10821091
else {
1083-
def missingType(modifier: String) = {
1084-
ctx.error(s"${modifier}type of implicit definition needs to be given explicitly", mdef.pos)
1085-
sym.resetFlag(Implicit)
1086-
}
10871092
if (sym is Implicit)
10881093
mdef match {
1089-
case _: DefDef => missingType("result")
1090-
case _: ValDef if sym.owner.isType => missingType("")
1094+
case _: DefDef => missingType(sym, "result ")
1095+
case _: ValDef if sym.owner.isType => missingType(sym, "")
10911096
case _ =>
10921097
}
10931098
lhsType orElse WildcardType

tests/neg/i3067.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Test[T](f: List[String] => T)
2+
3+
object o {
4+
5+
implicit val x = 3 // error
6+
7+
implicit def y = "abc" // error
8+
9+
implicit object a extends Test(_ map identity) // error
10+
implicit object b extends Test(_ map identity)
11+
}

0 commit comments

Comments
 (0)