summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala29
-rw-r--r--test/files/neg/t2442.flags2
-rw-r--r--test/files/neg/t3836.check13
-rw-r--r--test/files/neg/t3836.scala28
-rw-r--r--test/files/pos/t3836.scala14
-rw-r--r--test/files/run/t3613.scala2
7 files changed, 85 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 046b177444..65b0ff1e6d 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -613,8 +613,8 @@ abstract class ClassfileParser {
parseAttributes(sym, info)
getScope(jflags).enter(sym)
- // sealed java enums (experimental)
- if (isEnum && opt.experimental) {
+ // sealed java enums
+ if (isEnum) {
val enumClass = sym.owner.linkedClassOfClass
if (!enumClass.isSealed)
enumClass setFlag (SEALED | ABSTRACT)
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) ||
diff --git a/test/files/neg/t2442.flags b/test/files/neg/t2442.flags
index 32cf036c3d..e8fb65d50c 100644
--- a/test/files/neg/t2442.flags
+++ b/test/files/neg/t2442.flags
@@ -1 +1 @@
--Xexperimental -Xfatal-warnings \ No newline at end of file
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t3836.check b/test/files/neg/t3836.check
new file mode 100644
index 0000000000..ff2fc36ae9
--- /dev/null
+++ b/test/files/neg/t3836.check
@@ -0,0 +1,13 @@
+t3836.scala:17: error: reference to IOException is ambiguous;
+it is imported twice in the same scope by
+import foo.bar._
+and import java.io._
+ def f = new IOException // genuinely different
+ ^
+t3836.scala:26: error: reference to Bippy is ambiguous;
+it is imported twice in the same scope by
+import baz._
+and import bar._
+ def f: Bippy[Int] = ???
+ ^
+two errors found
diff --git a/test/files/neg/t3836.scala b/test/files/neg/t3836.scala
new file mode 100644
index 0000000000..a68f6e172f
--- /dev/null
+++ b/test/files/neg/t3836.scala
@@ -0,0 +1,28 @@
+package foo
+
+package object bar {
+ type IOException = Object
+ type Bippy[T] = List[T]
+}
+
+package object baz {
+ type Bippy[+T] = List[T]
+}
+
+package baz {
+ import java.io._
+ import foo.bar._
+
+ object Test {
+ def f = new IOException // genuinely different
+ }
+}
+
+package baz2 {
+ import bar._
+ import baz._
+
+ object Test2 {
+ def f: Bippy[Int] = ???
+ }
+}
diff --git a/test/files/pos/t3836.scala b/test/files/pos/t3836.scala
new file mode 100644
index 0000000000..840f171164
--- /dev/null
+++ b/test/files/pos/t3836.scala
@@ -0,0 +1,14 @@
+package foo
+
+package object bar {
+ type IOException = java.io.IOException
+}
+
+package baz {
+ import java.io._
+ import foo.bar._
+
+ object Test {
+ def f = new IOException
+ }
+}
diff --git a/test/files/run/t3613.scala b/test/files/run/t3613.scala
index c3b249571b..171a6a21aa 100644
--- a/test/files/run/t3613.scala
+++ b/test/files/run/t3613.scala
@@ -8,7 +8,7 @@ class Boopy {
case "Boopy" => fireIntervalAdded( model, 0, 1 )
}
def getSize = 0
- def getElementAt( idx: Int ) : AnyRef = "egal"
+ def getElementAt( idx: Int ) = ???
}
}