aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala10
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala140
-rw-r--r--src/dotty/tools/dotc/typer/ReTyper.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala6
4 files changed, 77 insertions, 81 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index ae325af2a..5e52c5d7e 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -69,15 +69,6 @@ trait Checking {
defn.ObjectClass.typeRef
}
- /** Check that (return) type of implicit definition is not empty */
- def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match {
- case tpt: untpd.DerivedTypeTree =>
- case TypeTree(untpd.EmptyTree) =>
- val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else ""
- ctx.error(d"${resStr}type of implicit definition needs to be given explicitly", defTree.pos)
- case _ =>
- }
-
/** Check that a non-implicit parameter making up the first parameter section of an
* implicit conversion is not a singleton type.
*/
@@ -150,7 +141,6 @@ trait NoChecking extends Checking {
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
override def checkLegalPrefix(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
- override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = ()
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = ()
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 2d4bf8099..c3f1dcc81 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -519,80 +519,92 @@ class Namer { typer: Typer =>
* defined symbol, given its final return type
*/
def valOrDefDefSig(mdef: ValOrDefDef, sym: Symbol, typeParams: List[Symbol], paramFn: Type => Type)(implicit ctx: Context): Type = {
- val pt =
- if (!mdef.tpt.isEmpty) WildcardType
- else {
- /** An type for this definition that might be inherited from elsewhere:
- * If this is a setter parameter, the corresponding getter type.
- * If this is a class member, the conjunction of all result types
- * of overridden methods.
- * NoType if neither case holds.
- */
- val inherited =
- if (sym.owner.isTerm) NoType
- else {
- // TODO: Look only at member of supertype instead?
- lazy val schema = paramFn(WildcardType)
- val site = sym.owner.thisType
- ((NoType: Type) /: sym.owner.info.baseClasses.tail) { (tp, cls) =>
- val iRawInfo =
- cls.info.nonPrivateDecl(sym.name).matchingDenotation(site, schema).info
- val iInstInfo = iRawInfo match {
- case iRawInfo: PolyType =>
- if (iRawInfo.paramNames.length == typeParams.length)
- iRawInfo.instantiate(typeParams map (_.typeRef))
- else NoType
- case _ =>
- if (typeParams.isEmpty) iRawInfo
- else NoType
- }
- val iResType = iInstInfo.finalResultType.asSeenFrom(site, cls)
- if (iResType.exists)
- typr.println(s"using inherited type; raw: $iRawInfo, inst: $iInstInfo, inherited: $iResType")
- tp & iResType
+ def inferredType = {
+ /** A type for this definition that might be inherited from elsewhere:
+ * If this is a setter parameter, the corresponding getter type.
+ * If this is a class member, the conjunction of all result types
+ * of overridden methods.
+ * NoType if neither case holds.
+ */
+ val inherited =
+ if (sym.owner.isTerm) NoType
+ else {
+ // TODO: Look only at member of supertype instead?
+ lazy val schema = paramFn(WildcardType)
+ val site = sym.owner.thisType
+ ((NoType: Type) /: sym.owner.info.baseClasses.tail) { (tp, cls) =>
+ val iRawInfo =
+ cls.info.nonPrivateDecl(sym.name).matchingDenotation(site, schema).info
+ val iInstInfo = iRawInfo match {
+ case iRawInfo: PolyType =>
+ if (iRawInfo.paramNames.length == typeParams.length)
+ iRawInfo.instantiate(typeParams map (_.typeRef))
+ else NoType
+ case _ =>
+ if (typeParams.isEmpty) iRawInfo
+ else NoType
}
+ val iResType = iInstInfo.finalResultType.asSeenFrom(site, cls)
+ if (iResType.exists)
+ typr.println(s"using inherited type; raw: $iRawInfo, inst: $iInstInfo, inherited: $iResType")
+ tp & iResType
}
+ }
- /** The proto-type to be used when inferring the result type from
- * the right hand side. This is `WildcardType` except if the definition
- * is a default getter. In that case, the proto-type is the type of
- * the corresponding parameter where bound parameters are replaced by
- * Wildcards.
- */
- def rhsProto = {
- val name = sym.asTerm.name
- val idx = name.defaultGetterIndex
- if (idx < 0) WildcardType
- else {
- val original = name.defaultGetterToMethod
- val meth: Denotation =
- if (original.isConstructorName && (sym.owner is ModuleClass))
- sym.owner.companionClass.info.decl(nme.CONSTRUCTOR)
- else
- ctx.defContext(sym).denotNamed(original)
- def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match {
- case params :: paramss1 =>
- if (idx < params.length) wildApprox(params(idx))
- else paramProto(paramss1, idx - params.length)
- case nil =>
- WildcardType
- }
- val defaultAlts = meth.altsWith(_.hasDefaultParams)
- if (defaultAlts.length == 1)
- paramProto(defaultAlts.head.info.widen.paramTypess, idx)
+ /** The proto-type to be used when inferring the result type from
+ * the right hand side. This is `WildcardType` except if the definition
+ * is a default getter. In that case, the proto-type is the type of
+ * the corresponding parameter where bound parameters are replaced by
+ * Wildcards.
+ */
+ def rhsProto = {
+ val name = sym.asTerm.name
+ val idx = name.defaultGetterIndex
+ if (idx < 0) WildcardType
+ else {
+ val original = name.defaultGetterToMethod
+ val meth: Denotation =
+ if (original.isConstructorName && (sym.owner is ModuleClass))
+ sym.owner.companionClass.info.decl(nme.CONSTRUCTOR)
else
+ ctx.defContext(sym).denotNamed(original)
+ def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match {
+ case params :: paramss1 =>
+ if (idx < params.length) wildApprox(params(idx))
+ else paramProto(paramss1, idx - params.length)
+ case nil =>
WildcardType
}
+ val defaultAlts = meth.altsWith(_.hasDefaultParams)
+ if (defaultAlts.length == 1)
+ paramProto(defaultAlts.head.info.widen.paramTypess, idx)
+ else
+ WildcardType
}
+ }
- // println(s"final inherited for $sym: ${inherited.toString}") !!!
- // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
- val rhsCtx = ctx.fresh addMode Mode.InferringReturnType
- def rhsType = typedAheadExpr(mdef.rhs, rhsProto)(rhsCtx).tpe.widen.approximateUnion
- def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos)
- inherited orElse lhsType orElse WildcardType
+ // println(s"final inherited for $sym: ${inherited.toString}") !!!
+ // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
+ val rhsCtx = ctx.fresh addMode Mode.InferringReturnType
+ def rhsType = typedAheadExpr(mdef.rhs, rhsProto)(rhsCtx).tpe.widen.approximateUnion
+ def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos)
+ if (inherited.exists) inherited
+ else {
+ if (sym is Implicit) {
+ val resStr = if (mdef.isInstanceOf[DefDef]) "result " else ""
+ ctx.error(d"${resStr}type of implicit definition needs to be given explicitly", mdef.pos)
+ sym.resetFlag(Implicit)
+ }
+ lhsType orElse WildcardType
}
+ }
+
+ val pt = mdef.tpt match {
+ case _: untpd.DerivedTypeTree => WildcardType
+ case TypeTree(untpd.EmptyTree) => inferredType
+ case _ => WildcardType
+ }
paramFn(typedAheadType(mdef.tpt, pt).tpe)
}
diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala
index 8d8134781..76817fd16 100644
--- a/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -59,6 +59,4 @@ class ReTyper extends Typer {
override def localTyper(sym: Symbol) = this
override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
-
- override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = ()
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index c79ecdf85..f4b52ce09 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -753,7 +753,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val ValDef(mods, name, tpt, rhs) = vdef
val mods1 = typedModifiers(mods, sym)
val tpt1 = typedType(tpt)
- if ((sym is Implicit) && sym.owner.isType) checkImplicitTptNonEmpty(vdef)
val rhs1 = rhs match {
case Ident(nme.WILDCARD) => rhs withType tpt1.tpe
case _ => typedExpr(rhs, tpt1.tpe)
@@ -766,10 +765,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val mods1 = typedModifiers(mods, sym)
val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef])
val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef])
- if (sym is Implicit) {
- if (sym.owner.isType) checkImplicitTptNonEmpty(ddef)
- checkImplicitParamsNotSingletons(vparamss1)
- }
+ if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1)
val tpt1 = typedType(tpt)
val rhs1 = typedExpr(rhs, tpt1.tpe)
assignType(cpy.DefDef(ddef, mods1, name, tparams1, vparamss1, tpt1, rhs1), sym)