diff options
author | Paul Phillips <paulp@improving.org> | 2012-06-11 13:49:10 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-07-05 21:08:29 -0700 |
commit | ddcb351a2e0aeea9373a891a05c8db73334470a9 (patch) | |
tree | ec0e0efe4a0a1fcb1ef3be96a227770fd5695910 /src | |
parent | 34d36108bf152469a934408da2b55c1df9c70a7a (diff) | |
download | scala-ddcb351a2e0aeea9373a891a05c8db73334470a9.tar.gz scala-ddcb351a2e0aeea9373a891a05c8db73334470a9.tar.bz2 scala-ddcb351a2e0aeea9373a891a05c8db73334470a9.zip |
Fix SI-3836 not-really-ambiguous import detection.
Normalize types before declaring that two imports are ambiguous,
because they might be the same thing. Review by @moors.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 018daf4568..ccd346e72d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4620,10 +4620,33 @@ trait Typers extends Modes with Adaptations with Tags { if (impSym.exists) { var impSym1: Symbol = NoSymbol var imports1 = imports.tail + + /** It's possible that seemingly conflicting identifiers are + * identifiably the same after type normalization. In such cases, + * allow compilation to proceed. A typical example is: + * package object foo { type InputStream = java.io.InputStream } + * import foo._, java.io._ + */ def ambiguousImport() = { - if (!(imports.head.qual.tpe =:= imports1.head.qual.tpe && impSym == impSym1)) - ambiguousError( - "it is imported twice in the same scope by\n"+imports.head + "\nand "+imports1.head) + // The types of the qualifiers from which the ambiguous imports come. + // If the ambiguous name is a value, these must be the same. + def t1 = imports.head.qual.tpe + def t2 = imports1.head.qual.tpe + // The types of the ambiguous symbols, seen as members of their qualifiers. + // If the ambiguous name is a monomorphic type, we can relax this far. + def mt1 = t1 memberType impSym + def mt2 = t2 memberType impSym1 + // Monomorphism restriction on types is in part because type aliases could have the + // same target type but attach different variance to the parameters. Maybe it can be + // relaxed, but doesn't seem worth it at present. + if (t1 =:= t2 && impSym == impSym1) + log(s"Suppressing ambiguous import: $t1 =:= $t2 && $impSym == $impSym1") + else if (mt1 =:= mt2 && name.isTypeName && impSym.isMonomorphicType && impSym1.isMonomorphicType) + log(s"Suppressing ambiguous import: $mt1 =:= $mt2 && $impSym and $impSym1 are equivalent") + else { + log(s"Import is genuinely ambiguous: !($t1 =:= $t2)") + ambiguousError(s"it is imported twice in the same scope by\n${imports.head}\nand ${imports1.head}") + } } while (errorContainer == null && !imports1.isEmpty && (!imports.head.isExplicitImport(name) || |