aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-10-22 17:11:04 +0200
committerMartin Odersky <odersky@gmail.com>2015-10-22 17:11:04 +0200
commitda945c4613cb9a11c89649aeabf1913e3b3019dd (patch)
tree63923ddca849eee1d8ee95140da531004910dd6c
parent746889b4ed0f53e433c123ddb2b90dece1298fff (diff)
downloaddotty-da945c4613cb9a11c89649aeabf1913e3b3019dd.tar.gz
dotty-da945c4613cb9a11c89649aeabf1913e3b3019dd.tar.bz2
dotty-da945c4613cb9a11c89649aeabf1913e3b3019dd.zip
Better handling of merge errors
Instead of picking one at random, throw a MergeError which might be caught later in mergeDenot. MergeDenot has enough info to pick a simulate Scala2 linarization if the prefix comes from Scala2, or it rethrows the exception so that it becomes a type error.
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala12
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--tests/neg/i827.scala7
4 files changed, 21 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index b223a8086..bd03cc056 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -308,7 +308,17 @@ object Denotations {
else if (!sym2.exists) sym1
else if (preferSym(sym2, sym1)) sym2
else sym1
- new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
+ val jointInfo =
+ try info1 & info2
+ catch {
+ case ex: MergeError =>
+ if (pre.widen.classSymbol.is(Scala2x))
+ info1 // follow Scala2 linearization -
+ // compare with way merge is performed in SymDenotation#computeMembersNamed
+ else
+ throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}")
+ }
+ new JointRefDenotation(sym, jointInfo, denot1.validFor & denot2.validFor)
}
}
} else NoDenotation
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 5fbffe6e9..74a156dbe 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -1057,6 +1057,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
println(TypeComparer.explained { implicit ctx => tp1 <:< tp2})
assert(false, s"andConflict ${tp1.show} and ${tp2.show}")
*/
+ if (!ctx.isAfterTyper && !ctx.mode.is(Mode.Scala2Unpickling))
+ throw new MergeError(msg)
ctx.warning(msg, ctx.tree.pos)
winner
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index e4f228915..58a6d226d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -492,10 +492,8 @@ object Types {
try go(this)
catch {
- case ex: MergeError =>
- throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}")
case ex: Throwable =>
- ctx.println(i"findMember exception for $this member $name")
+ core.println(i"findMember exception for $this member $name")
throw ex // DEBUG
}
finally {
diff --git a/tests/neg/i827.scala b/tests/neg/i827.scala
new file mode 100644
index 000000000..cc795b590
--- /dev/null
+++ b/tests/neg/i827.scala
@@ -0,0 +1,7 @@
+trait A { trait Inner }
+trait B { self: A =>
+ trait Inner extends self.Inner
+}
+
+
+class C extends C