summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-11-22 16:22:05 +0000
committerMartin Odersky <odersky@gmail.com>2006-11-22 16:22:05 +0000
commit4af77453d44c809c1ac06e78a8b698e2ef28a79d (patch)
tree1ac21e83729ff3cac7af9a6d34b34ea8a7109faf /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parentf7e598a6a96719eed46c2c9e8f2a8e74e5533d24 (diff)
downloadscala-4af77453d44c809c1ac06e78a8b698e2ef28a79d.tar.gz
scala-4af77453d44c809c1ac06e78a8b698e2ef28a79d.tar.bz2
scala-4af77453d44c809c1ac06e78a8b698e2ef28a79d.zip
1.
2. Modified ambiguous check for implicits. 3. Cleanup of AddInterfaces
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 52096ffbcd..932cfeced3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2384,13 +2384,15 @@ trait Typers requires Analyzer {
val tc = newTyper(context.makeImplicit(reportAmbiguous))
- def ambiguousError(info1: ImplicitInfo, info2: ImplicitInfo) =
+ def ambiguousError(info1: ImplicitInfo, info2: ImplicitInfo,
+ pre1: String, pre2: String, trailer: String) =
error(
pos,
- "ambiguous implicit value:\n" +
- " both "+info1.sym + info1.sym.locationString+" of type "+info1.tpe+
- "\n and "+info2.sym + info2.sym.locationString+" of type "+info2.tpe+
- (if (isView) "\n are possible conversion functions from "+ pt.typeArgs(0)+" to "+pt.typeArgs(1)
+ "ambiguous implicit value:\n "+
+ pre1+" "+info1.sym+info1.sym.locationString+" of type "+info1.tpe+"\n "+
+ pre2+" "+info2.sym+info2.sym.locationString+" of type "+info2.tpe+"\n "+
+ trailer+
+ (if (isView) "are possible conversion functions from "+ pt.typeArgs(0)+" to "+pt.typeArgs(1)
else "\n match expected type "+pt))
/** Search list of implicit info lists for one matching prototype
@@ -2405,15 +2407,13 @@ trait Typers requires Analyzer {
* @return ...
*/
def searchImplicit(implicitInfoss: List[List[ImplicitInfo]], isLocal: boolean): Tree = {
- def isSubClassOrObject(sym1: Symbol, sym2: Symbol) = {
- (sym1 isSubClass sym2) ||
- sym1.isModuleClass && sym2.isModuleClass &&
- (sym1.linkedClassOfClass isSubClass sym2.linkedClassOfClass)
- }
+ def isSubClassOrObject(sym1: Symbol, sym2: Symbol): boolean =
+ sym1 != NoSymbol && (sym1 isSubClass sym2) ||
+ sym1.isModuleClass && isSubClassOrObject(sym1.linkedClassOfClass, sym2) ||
+ sym2.isModuleClass && isSubClassOrObject(sym1, sym2.linkedClassOfClass)
def improves(info1: ImplicitInfo, info2: ImplicitInfo) =
(info2 == NoImplicitInfo) ||
(info1 != NoImplicitInfo) &&
- isSubClassOrObject(info1.sym.owner, info2.sym.owner) &&
isStrictlyBetter(info1.tpe, info2.tpe)
val shadowed = new HashSet[Name](8)
def isApplicable(info: ImplicitInfo): boolean =
@@ -2429,10 +2429,17 @@ trait Typers requires Analyzer {
}
val applicable = List.flatten(implicitInfoss map applicableInfos)
val best = (NoImplicitInfo /: applicable) ((best, alt) => if (improves(alt, best)) alt else best)
- val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
if (best == NoImplicitInfo) EmptyTree
else {
- if (!competing.isEmpty) ambiguousError(best, competing.head)
+ val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
+ if (!competing.isEmpty) ambiguousError(best, competing.head, "both", "and ", "")
+ for (val alt <- applicable)
+ if (alt.sym.owner != best.sym.owner && isSubClassOrObject(alt.sym.owner, best.sym.owner)) {
+ ambiguousError(best, alt,
+ "most specific definition is:",
+ "yet alternative definition ",
+ "is defined in a subclass.\n Both definitions ")
+ }
tc.typedImplicit(pos, best, pt, isLocal)
}
}