From 9a4199709d2c3c910dbbe17bffdac97df69b1d8f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 17 Mar 2009 19:16:19 +0000 Subject: chyanged implicits so that implicit Builder pat... chyanged implicits so that implicit Builder pattern works. --- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 16 ++++++++++++---- src/compiler/scala/tools/nsc/typechecker/Infer.scala | 6 +++--- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 +++++- src/compiler/scala/tools/nsc/typechecker/Variances.scala | 2 -- 4 files changed, 20 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 6d91179c3d..0efdc6fbe2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -52,6 +52,16 @@ self: Analyzer => search.result } + /** If type `pt` an instance of Manifest or OptManifest, or an abstract type lower-bounded + * by such an instance? + */ + def isManifest(pt: Type): Boolean = pt match { + case TypeRef(_, ManifestClass, List(_)) | + TypeRef(_, OptManifestClass, List(_)) => true + case TypeRef(_, tsym, _) => tsym.isAbstractType && isManifest(pt.bounds.lo) + case _ => false + } + /** The result of an implicit search * @param tree The tree representing the implicit * @param subst A substituter that represents the undetermined type parameters @@ -234,7 +244,7 @@ self: Analyzer => private def typedImplicit(info: ImplicitInfo): SearchResult = context.openImplicits find (dominates(pt, _)) match { case Some(pending) => - println("Pending implicit "+pending+" dominates "+pt) + //println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) throw DivergentImplicit SearchFailure case None => @@ -273,9 +283,7 @@ self: Analyzer => def approximate(tp: Type) = tp.instantiateTypeParams(undetParams, undetParams map (_ => WildcardType)) - /** Instantiated `pt' so that covariant occurrences of undetermined - * type parameters are replaced by Any, and all other occurrences - * are replaced by Nothing + /** Instantiated `pt' so that undetermined type parameters are replaced by wildcards */ val wildPt = approximate(pt) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index db43125ccc..1a07103e24 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -524,7 +524,7 @@ trait Infer { */ def adjustTypeArgs(tparams: List[Symbol], targs: List[Type], restpe: Type, uninstantiated: ListBuffer[Symbol]): List[Type] = List.map2(tparams, targs) {(tparam, targ) => - if (targ.typeSymbol == NothingClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) { + if (targ.typeSymbol == NothingClass && (restpe == WildcardType || (varianceInType(restpe)(tparam) & COVARIANT) == 0)) { uninstantiated += tparam tparam.tpe } else if (targ.typeSymbol == RepeatedParamClass) { @@ -943,12 +943,12 @@ trait Infer { val targs = exprTypeArgs(tparams, tree.tpe, pt) val uninstantiated = new ListBuffer[Symbol] val detargs = if (keepNothings) targs - else adjustTypeArgs(tparams, targs, pt, uninstantiated) + else adjustTypeArgs(tparams, targs, WildcardType, uninstantiated) val undetparams = uninstantiated.toList val detparams = tparams remove (undetparams contains _) substExpr(tree, detparams, detargs, pt) if (inferInfo) - println("inferred expr instance "+tree) + println("inferred expr instance "+tree+", detargs = "+detargs+", undetparams = "+undetparams) undetparams } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 955bd9ee4c..55ad496c94 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -747,7 +747,11 @@ trait Typers { self: Analyzer => case mt: ImplicitMethodType if ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1) if (!context.undetparams.isEmpty && (mode & POLYmode) == 0) { // (9) context.undetparams = inferExprInstance( - tree, context.extractUndetparams(), pt, false) + tree, context.extractUndetparams(), pt, mt.paramTypes exists isManifest) + // if we are looking for a manifest, instantiate type to Nothing anyway, + // as we would get amnbiguity errors otherwise. Example + // Looking for a manifest of Nil: This mas many potential types, + // so we need to instantiate to minimal type List[Nothing]. } val typer1 = constrTyperIf(treeInfo.isSelfOrSuperConstrCall(tree)) typer1.typed(typer1.applyImplicitArgs(tree), mode, pt) diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala index cc68373f40..a02b4b04a1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala @@ -74,8 +74,6 @@ trait Variances { varianceInType(attrib.atp)(tparam) } - - /** Compute variance of type parameter tparam in type tp. */ def varianceInType(tp: Type)(tparam: Symbol): Int = tp match { case ErrorType | WildcardType | NoType | NoPrefix | ThisType(_) | ConstantType(_) => -- cgit v1.2.3