summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
3 files changed, 15 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index c23d29f159..0472f4fb21 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -420,7 +420,9 @@ self: Analyzer =>
*/
def tryImplicit(info: ImplicitInfo): SearchResult =
if (containsError(info.tpe) ||
- (isLocal && shadowed.contains(info.name)) // || (isView && (info.sym == Predef_identity || info.sym == Predef_conforms))
+ (isLocal && shadowed.contains(info.name)) //||
+ // (isView && (info.sym == Predef_identity || info.sym == Predef_conforms})) //@M this condition prevents no-op conversions, which are a problem (besides efficiency),
+ // one example is removeNames in NamesDefaults, which relies on the type checker failing in case of ambiguity between an assignment/named arg
) SearchFailure
else typedImplicit(info)
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 482c53fac5..9d485cc730 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -390,9 +390,16 @@ trait NamesDefaults { self: Analyzer =>
argPos(index) = pos
rhs
case t: Tree =>
- errorTree(arg, "reference to "+ name +" is ambiguous; it is both, a parameter\n"+
+ //@M was: errorTree(arg, ...)
+ // this throws an exception that's caught in `tryTypedApply` (as it uses `silent`)
+ // unfortunately, tryTypedApply recovers from the exception if you use errorTree(arg, ...) and conforms is allowed as a view (see tryImplicit in Implicits)
+ // because it tries to produce a new qualifier (if the old one was P, the new one will be conforms.apply(P)), and if that works, it pretends nothing happened
+ // so, to make sure tryTypedApply fails, pass EmptyTree instead
+ errorTree(EmptyTree, "reference to "+ name +" is ambiguous; it is both, a parameter\n"+
"name of the method and the name of a variable currently in scope.")
}
+ //@M note that we don't get here when an ambiguity was detected (during the computation of res),
+ // as errorTree throws an exception
typer.context.undetparams = udp
res
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 13a9d6e142..b609f1f24b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -992,8 +992,10 @@ trait Typers { self: Analyzer =>
((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) &&
phase.id <= currentRun.typerPhase.id && !qtpe.isError && !tp.isError &&
qtpe.typeSymbol != NullClass && qtpe.typeSymbol != NothingClass && qtpe != WildcardType &&
- context.implicitsEnabled) { // don't try to convert a top-level type that's the subject of an implicit search
- // (otherwise we get divergence, e.g., starting at `conforms` during ant quick.bin)
+ context.implicitsEnabled) { // don't try to adapt a top-level type that's the subject of an implicit search
+ // this happens because, if isView, typedImplicit tries to apply the "current" implicit value to
+ // a value that needs to be coerced, so we check whether the implicit value has an `apply` method
+ // (if we allow this, we get divergence, e.g., starting at `conforms` during ant quick.bin)
// note: implicit arguments are still inferred (this kind of "chaining" is allowed)
val coercion = inferView(qual, qtpe, name, tp)
if (coercion != EmptyTree)