diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-09-14 14:23:28 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-09-14 14:23:28 +0000 |
commit | 3b8129c77b9426a621163d4e5bf54943f58692a1 (patch) | |
tree | cfd3a9c7c28b0b135bd06d65275803770e5b99f5 /src/compiler | |
parent | 45b659cd413a1411c90cd27261d8260229f93898 (diff) | |
download | scala-3b8129c77b9426a621163d4e5bf54943f58692a1.tar.gz scala-3b8129c77b9426a621163d4e5bf54943f58692a1.tar.bz2 scala-3b8129c77b9426a621163d4e5bf54943f58692a1.zip |
closes #1693: improve implicit conversion disam...
closes #1693: improve implicit conversion disambiguation by
incorporating the expected type of the member that triggered the
conversion
back-ported fix by Martin in embeddings branch.
review by odersky (just in case it shouldn't have been back-ported)
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 35 |
2 files changed, 32 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 28c4b67db9..900f7e471b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -214,8 +214,8 @@ trait Contexts { self: Analyzer => def make(tree: Tree): Context = make(tree, owner) - def makeSilent(reportAmbiguousErrors: Boolean): Context = { - val c = make(tree) + def makeSilent(reportAmbiguousErrors: Boolean, newtree: Tree = tree): Context = { + val c = make(newtree) c.reportGeneralErrors = false c.reportAmbiguousErrors = reportAmbiguousErrors c diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 461ed8b2cc..7ef494ea73 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -692,14 +692,18 @@ trait Typers { self: Analyzer => else qual.tpe.nonLocalMember(name) } - def silent[T](op: Typer => T): Any /* in fact, TypeError or T */ = { + def silent[T](op: Typer => T, + reportAmbiguousErrors: Boolean = context.reportAmbiguousErrors, + newtree: Tree = context.tree): Any /* in fact, TypeError or T */ = { val rawTypeStart = startCounter(rawTypeFailed) val findMemberStart = startCounter(findMemberFailed) val subtypeStart = startCounter(subtypeFailed) val failedSilentStart = startTimer(failedSilentNanos) try { - if (context.reportGeneralErrors) { - val context1 = context.makeSilent(context.reportAmbiguousErrors) + if (context.reportGeneralErrors || + reportAmbiguousErrors != context.reportAmbiguousErrors || + newtree != context.tree) { + val context1 = context.makeSilent(reportAmbiguousErrors, newtree) context1.undetparams = context.undetparams context1.savedTypeBounds = context.savedTypeBounds context1.namedApplyBlockInfo = context.namedApplyBlockInfo @@ -3349,7 +3353,9 @@ trait Typers { self: Analyzer => val funpt = if (isPatternMode) pt else WildcardType val appStart = startTimer(failedApplyNanos) val opeqStart = startTimer(failedOpEqNanos) - silent(_.typed(fun, funMode(mode), funpt)) match { + silent(_.typed(fun, funMode(mode), funpt), + if ((mode & EXPRmode) != 0) false else context.reportAmbiguousErrors, + if ((mode & EXPRmode) != 0) tree else context.tree) match { case fun1: Tree => val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1 incCounter(typedApplyCount) @@ -3541,7 +3547,26 @@ trait Typers { self: Analyzer => member(qual, name) } if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & EXPRmode) != 0) { - val qual1 = adaptToName(qual, name) + val qual1 = try { + adaptToName(qual, name) + } catch { + case ex: TypeError => + // this happens if implicits are ambiguous; try again with more context info. + // println("last ditch effort: "+qual+" . "+name) // DEBUG + context.tree match { + case Apply(tree1, args) if tree1 eq tree => // try handling the arguments + // println("typing args: "+args) // DEBUG + silent(_.typedArgs(args, mode)) match { + case args: List[_] => + adaptToArguments(qual, name, args.asInstanceOf[List[Tree]], WildcardType) + case _ => + throw ex + } + case _ => + // println("not in an apply: "+context.tree+"/"+tree) // DEBUG + throw ex + } + } if (qual1 ne qual) return typed(treeCopy.Select(tree, qual1, name), mode, pt) } |