diff options
author | Martin Odersky <odersky@gmail.com> | 2007-06-05 15:57:59 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-06-05 15:57:59 +0000 |
commit | e51207992f525ed9e32a7a9a39512b4d7e503c03 (patch) | |
tree | b9440d03aed294fde3f8aaa293f60ed98b5de0c1 /src/compiler/scala/tools/nsc/typechecker/Infer.scala | |
parent | e060c61b6127ceb2de0e4ce5d3f3d685bc542804 (diff) | |
download | scala-e51207992f525ed9e32a7a9a39512b4d7e503c03.tar.gz scala-e51207992f525ed9e32a7a9a39512b4d7e503c03.tar.bz2 scala-e51207992f525ed9e32a7a9a39512b4d7e503c03.zip |
deprecated &f, .f, requires.
Added existential types.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Infer.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 91 |
1 files changed, 16 insertions, 75 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 6ce9514f54..0cb6aef48e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -124,20 +124,6 @@ trait Infer { } } - /** Do type arguments <code>targs</code> conform to formal parameters - * <code>tparams</code>? - * - * @param tparams ... - * @param targs ... - * @return ... - */ - private def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): boolean = { - val bounds = tparams map { tparam => - tparam.info.asSeenFrom(pre, owner).instantiateTypeParams(tparams, targs).bounds - } - !(List.map2(bounds, targs)((bound, targ) => bound containsType targ) contains false) - } - /** Solve constraint collected in types <code>tvars</code>. * * @param tvars All type variables to be instantiated. @@ -147,55 +133,10 @@ trait Infer { * @param upper When <code>true</code> search for max solution else min. * @throws NoInstance */ - private def solve(tvars: List[TypeVar], tparams: List[Symbol], - variances: List[int], upper: boolean): List[Type] = { - val config = tvars zip (tparams zip variances) - - def solveOne(tvar: TypeVar, tparam: Symbol, variance: int): unit = { - if (tvar.constr.inst == NoType) { - val up = if (variance != CONTRAVARIANT) upper else !upper - tvar.constr.inst = null - val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo - // Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG - var cyclic = bound contains tparam - for ((tvar2, (tparam2, variance2)) <- config) { - if (tparam2 != tparam && - ((bound contains tparam2) || - up && (tparam2.info.bounds.lo =:= tparam.tpe) || //@M TODO: might be affected by change to tpe in Symbol - !up && (tparam2.info.bounds.hi =:= tparam.tpe))) { //@M TODO: might be affected by change to tpe in Symbol - if (tvar2.constr.inst eq null) cyclic = true - solveOne(tvar2, tparam2, variance2) - } - } - if (!cyclic) { - if (up) { - if (bound.symbol != AnyClass) { - tvar.constr.hibounds = - bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds - } - for (tparam2 <- tparams) - if (tparam2.info.bounds.lo =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol - tvar.constr.hibounds = - tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.hibounds - } else { - if (bound.symbol != AllClass && bound.symbol != tparam) { - tvar.constr.lobounds = - bound.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds - } - for (tparam2 <- tparams) - if (tparam2.info.bounds.hi =:= tparam.tpe) //@M TODO: might be affected by change to tpe in Symbol - tvar.constr.lobounds = - tparam2.tpe.instantiateTypeParams(tparams, tvars) :: tvar.constr.lobounds - } - } - tvar.constr.inst = NoType // necessary because hibounds/lobounds may contain tvar - //Console.println("solving "+tvar+" "+up+" "+(if (up) (tvar.constr.hibounds) else tvar.constr.lobounds))//DEBUG - tvar.constr.inst = if (up) glb(tvar.constr.hibounds) else lub(tvar.constr.lobounds) - assertNonCyclic(tvar)//debug - } - } - for ((tvar, (tparam, variance)) <- config) - solveOne(tvar, tparam, variance) + private def solvedTypes(tvars: List[TypeVar], tparams: List[Symbol], + variances: List[int], upper: boolean): List[Type] = { + solve(tvars, tparams, variances, upper) + for (val tvar <- tvars) assert(tvar.constr.inst != tvar, tvar.origin) tvars map instantiate } @@ -445,7 +386,7 @@ trait Infer { val tvars = tparams map freshVar if (isCompatible(restpe.instantiateTypeParams(tparams, tvars), pt)) { try { - solve(tvars, tparams, tparams map varianceInType(restpe), false) + solvedTypes(tvars, tparams, tparams map varianceInType(restpe), false) } catch { case ex: NoInstance => null } @@ -550,7 +491,7 @@ trait Infer { } () } - val targs = solve(tvars, tparams, tparams map varianceInTypes(formals), false) + val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals), false) List.map2(tparams, targs) {(tparam, targ) => if (targ.symbol == AllClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) { uninstantiated += tparam @@ -657,11 +598,11 @@ trait Infer { " do not conform to the expected kinds of the type parameters "+ tparams.mkString("(", ",", ")") + tparams.head.locationString+ "." + kindErrors.toList.mkString("\n", ", ", "")) else if (!isWithinBounds(pre, owner, tparams, targs)) { - if (!(targs exists (.isErroneous)) && !(tparams exists (.isErroneous))) { + if (!(targs exists (_.isErroneous)) && !(tparams exists (_.isErroneous))) { error(pos, prefix + "type arguments " + targs.mkString("[", ",", "]") + " do not conform to " + tparams.head.owner + "'s type parameter bounds " + - (tparams map (.defString)).mkString("[", ",", "]")) + (tparams map (_.defString)).mkString("[", ",", "]")) } if (settings.explaintypes.value) { val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) @@ -816,7 +757,7 @@ trait Infer { case MethodType(formals0, _) => try { val formals = formalTypes(formals0, args.length) - val argtpes = actualTypes(args map (.tpe.deconst), formals.length) + val argtpes = actualTypes(args map (_.tpe.deconst), formals.length) val restpe = fn.tpe.resultType(argtpes) val uninstantiated = new ListBuffer[Symbol] val targs = methTypeArgs(undetparams, formals, restpe, argtpes, pt, uninstantiated) @@ -833,7 +774,7 @@ trait Infer { "no type parameters for " + applyErrorMsg( fn, " exist so that it can be applied to arguments ", - args map (.tpe.widen), WildcardType) + + args map (_.tpe.widen), WildcardType) + "\n --- because ---\n" + ex.getMessage()) List() } @@ -891,7 +832,7 @@ trait Infer { */ def computeArgs = try { - val targs = solve(tvars, undetparams, undetparams map varianceInType(restpe), true) + val targs = solvedTypes(tvars, undetparams, undetparams map varianceInType(restpe), true) checkBounds(tree.pos, NoPrefix, NoSymbol, undetparams, targs, "inferred ") new TreeTypeSubstituter(undetparams, targs).traverse(tree) } catch { @@ -933,7 +874,7 @@ trait Infer { tvar.constr.inst != NoType && isFullyDefined(tvar.constr.inst) && (tparam.info.bounds containsType tvar.constr.inst)) { - context.nextEnclosing(.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) + context.nextEnclosing(_.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) tparam setInfo tvar.constr.inst tparam resetFlag DEFERRED if (settings.debug.value) log("new alias of " + tparam + " = " + tparam.info) @@ -947,7 +888,7 @@ trait Infer { if (!(lo <:< hi)) { if (settings.debug.value) log("inconsistent: "+tparam+" "+lo+" "+hi) } else if (!((lo <:< tparam.info.bounds.lo) && (tparam.info.bounds.hi <:< hi))) { - context.nextEnclosing(.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) + context.nextEnclosing(_.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam) tparam setInfo mkTypeBounds(lo, hi) if (settings.debug.value) log("new bounds of " + tparam + " = " + tparam.info) } else { @@ -1192,7 +1133,7 @@ trait Infer { inferMethodAlternative(tree, undetparams, argtpes, WildcardType) } } else if (!competing.isEmpty) { - if (!(argtpes exists (.isErroneous)) && !pt.isErroneous) + if (!(argtpes exists (_.isErroneous)) && !pt.isErroneous) context.ambiguousError(tree.pos, pre, best, competing.head, "argument types " + argtpes.mkString("(", ",", ")") + (if (pt == WildcardType) "" else " and expected result type " + pt)) @@ -1252,7 +1193,7 @@ trait Infer { if (sym0.hasFlag(OVERLOADED)) { val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) } if (sym == NoSymbol) { - if (!(argtypes exists (.isErroneous))) { + if (!(argtypes exists (_.isErroneous))) { error( tree.pos, "type arguments " + argtypes.mkString("[", ",", "]") + @@ -1264,7 +1205,7 @@ trait Infer { if (sym.hasFlag(OVERLOADED)) { val tparams = new AsSeenFromMap(pre, sym.alternatives.head.owner).mapOver( sym.alternatives.head.typeParams) - val bounds = tparams map (.tpe) //@M TODO: might be affected by change to tpe in Symbol + val bounds = tparams map (_.tpe) //@M TODO: might be affected by change to tpe in Symbol val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), sym.alternatives)) |