diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 140 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ReTyper.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 6 |
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) |