summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-09-16 22:26:24 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-09-16 22:26:24 +0000
commite557acb9a7d672c0635c3eaf9fe385adc41e5c86 (patch)
treed13db6639464acc57f0e44b4b3ef6f3e607ad403 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parentce223fe7abc47af712382a64404604e75f9f4d20 (diff)
downloadscala-e557acb9a7d672c0635c3eaf9fe385adc41e5c86.tar.gz
scala-e557acb9a7d672c0635c3eaf9fe385adc41e5c86.tar.bz2
scala-e557acb9a7d672c0635c3eaf9fe385adc41e5c86.zip
part 2 of the dependent method refactoring: imp...
part 2 of the dependent method refactoring: improved interaction with implicit search (needed for oopsla paper) more to come in this area, see e.g. #3346 (stanford edsl stuff) reopens #13, which wasn't fixed properly before imo, anyway (have a look at -Xprint:typer output before this commit: a type that's not expressible in surface syntax is inferred -- also removed duplicate test file) closes #3731: co-evolve type alias type symbols when their rhs is updated and they are referenced by type selections (see typemap) review by odersky
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala79
1 files changed, 50 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e71ad5475c..f793da0c54 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -178,18 +178,12 @@ trait Typers { self: Analyzer =>
*/
def applyImplicitArgs(fun: Tree): Tree = fun.tpe match {
case MethodType(params, _) =>
- var positional = true
val argResultsBuff = new ListBuffer[SearchResult]()
+ val argBuff = new ListBuffer[Tree]()
- // apply the substitutions (undet type param -> type) that were determined
- // by implicit resolution of implicit arguments on the left of this argument
- for(param <- params) {
- var paramTp = param.tpe
- for(ar <- argResultsBuff)
- paramTp = paramTp.subst(ar.subst.from, ar.subst.to)
-
- argResultsBuff += inferImplicit(fun, paramTp, true, false, context)
- }
+ def mkPositionalArg(argTree: Tree, paramName: Name) = argTree
+ def mkNamedArg(argTree: Tree, paramName: Name) = atPos(argTree.pos)(new AssignOrNamedArg(Ident(paramName), (argTree)))
+ var mkArg: (Tree, Name) => Tree = mkPositionalArg
def errorMessage(paramName: Name, paramTp: Type) =
paramTp.typeSymbol match {
@@ -200,23 +194,40 @@ trait Typers { self: Analyzer =>
else "parameter "+paramName+": ")+paramTp
}
- val argResults = argResultsBuff.toList
- val args = argResults.zip(params) flatMap {
- case (arg, param) =>
- if (arg != SearchFailure) {
- if (positional) List(arg.tree)
- else List(atPos(arg.tree.pos)(new AssignOrNamedArg(Ident(param.name), (arg.tree))))
- } else {
- if (!param.hasFlag(DEFAULTPARAM))
- context.error(fun.pos, errorMessage(param.name, param.tpe))
- positional = false
- Nil
- }
+ // DEPMETTODO: instantiate type vars that depend on earlier implicit args (see adapt (4.1))
+ //
+ // apply the substitutions (undet type param -> type) that were determined
+ // by implicit resolution of implicit arguments on the left of this argument
+ for(param <- params) {
+ var paramTp = param.tpe
+ for(ar <- argResultsBuff)
+ paramTp = paramTp.subst(ar.subst.from, ar.subst.to)
+
+ val res = inferImplicit(fun, paramTp, true, false, context)
+ argResultsBuff += res
+
+ if (res != SearchFailure) {
+ argBuff += mkArg(res.tree, param.name)
+ } else {
+ mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
+ if (!param.hasFlag(DEFAULTPARAM))
+ context.error(fun.pos, errorMessage(param.name, param.tpe))
+ /* else {
+ TODO: alternative (to expose implicit search failure more) -->
+ resolve argument, do type inference, keep emitting positional args, infer type params based on default value for arg
+ for (ar <- argResultsBuff) ar.subst traverse defaultVal
+ val targs = exprTypeArgs(context.undetparams, defaultVal.tpe, paramTp)
+ substExpr(tree, tparams, targs, pt)
+ }*/
+ }
}
- for (s <- argResults map (_.subst)) {
- s traverse fun
- for (arg <- args) s traverse arg
+
+ val args = argBuff.toList
+ for (ar <- argResultsBuff) {
+ ar.subst traverse fun
+ for (arg <- args) ar.subst traverse arg
}
+
new ApplyToImplicitArgs(fun, args) setPos fun.pos
case ErrorType =>
fun
@@ -819,10 +830,20 @@ trait Typers { self: Analyzer =>
context.undetparams = context.undetparams ::: tparams1
adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original)
case mt: MethodType if mt.isImplicit && ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1)
- if (context.undetparams nonEmpty) // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
- // dropped so that type args of implicit method are inferred even if polymorphic expressions are allowed
- // needed for implicits in 2.8 collection library -- maybe once #3346 is fixed, we can reinstate the condition?
- context.undetparams = inferExprInstance(tree, context.extractUndetparams(), pt, false) // false: retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType
+ if (context.undetparams nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
+ // dropped so that type args of implicit method are inferred even if polymorphic expressions are allowed
+ // needed for implicits in 2.8 collection library -- maybe once #3346 is fixed, we can reinstate the condition?
+ context.undetparams =
+ inferExprInstance(tree, context.extractUndetparams(), pt,
+ // approximate types that depend on arguments since dependency on implicit argument is like dependency on type parameter
+ if(settings.YdepMethTpes.value) mt.approximate else mt,
+ // if we are looking for a manifest, instantiate type to Nothing anyway,
+ // as we would get ambiguity errors otherwise. Example
+ // Looking for a manifest of Nil: This mas many potential types,
+ // so we need to instantiate to minimal type List[Nothing].
+ false) // false: retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType
+ }
+
val typer1 = constrTyperIf(treeInfo.isSelfOrSuperConstrCall(tree))
if (original != EmptyTree && pt != WildcardType)
typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match {