aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala8
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala41
-rw-r--r--src/dotty/tools/dotc/core/Types.scala16
-rw-r--r--src/dotty/tools/dotc/transform/OverridingPairs.scala7
-rw-r--r--src/dotty/tools/dotc/typer/EtaExpansion.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala11
-rw-r--r--test/dotc/tests.scala4
-rw-r--r--tests/disabled/not-representable/pos/t3498-old.scala (renamed from tests/pending/pos/t3498-old.scala)0
-rw-r--r--tests/disabled/structural-type/pos/t3175-pos.scala (renamed from tests/pending/pos/t3175-pos.scala)0
-rw-r--r--tests/disabled/structural-type/pos/t3363-new.scala (renamed from tests/pending/pos/t3363-new.scala)2
-rw-r--r--tests/disabled/structural-type/pos/t3363-old.scala (renamed from tests/pending/pos/t3363-old.scala)2
-rw-r--r--tests/neg/over.scala8
-rw-r--r--tests/neg/overrides.scala42
-rw-r--r--tests/pending/pos/java-override/A.java3
-rw-r--r--tests/pending/pos/java-override/B.scala7
-rw-r--r--tests/pending/pos/self-type-override.scala13
-rw-r--r--tests/pending/pos/t3278.scala15
-rw-r--r--tests/pending/pos/t3480.scala2
-rw-r--r--tests/pos/sammy_poly.scala (renamed from tests/pending/pos/sammy_poly.scala)0
-rw-r--r--tests/pos/scoping1.scala (renamed from tests/pending/pos/scoping1.scala)2
-rw-r--r--tests/pos/sealed-final.scala (renamed from tests/pending/pos/sealed-final.scala)0
-rw-r--r--tests/pos/spec-sealed.scala (renamed from tests/pending/pos/spec-sealed.scala)0
-rw-r--r--tests/pos/subtyping.scala29
-rw-r--r--tests/pos/t319.scala (renamed from tests/pending/pos/t319.scala)3
-rw-r--r--tests/pos/t3252.scala (renamed from tests/pending/pos/t3252.scala)0
-rw-r--r--tests/pos/t3278.scala30
-rw-r--r--tests/pos/t3343.scala (renamed from tests/pending/pos/t3343.scala)0
-rw-r--r--tests/pos/t3411.scala (renamed from tests/pending/pos/t3411.scala)0
-rw-r--r--tests/pos/t344.scala (renamed from tests/pending/pos/t344.scala)0
30 files changed, 146 insertions, 108 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 8fdc4a9db..77c607ca7 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -759,6 +759,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Ident(defn.ScalaRuntimeModule.requiredMethod(name).termRef).appliedToArgs(args)
}
+ /** An extractor that pulls out type arguments */
+ object MaybePoly {
+ def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match {
+ case TypeApply(tree, targs) => Some(tree, targs)
+ case _ => Some(tree, Nil)
+ }
+ }
+
/** A traverser that passes the enlcosing class or method as an argumenr
* to the traverse method.
*/
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 998b4f944..4a16ca45d 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -285,7 +285,7 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
def underlyingIfRepeated(isJava: Boolean)(implicit ctx: Context): Type =
if (self.isRepeatedParam) {
- val seqClass = if(isJava) defn.ArrayClass else defn.SeqClass
+ val seqClass = if (isJava) defn.ArrayClass else defn.SeqClass
translateParameterized(defn.RepeatedParamClass, seqClass)
}
else self
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index b40baafdf..1687d6159 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -648,45 +648,34 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
// Tests around `matches`
/** A function implementing `tp1` matches `tp2`. */
- final def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = tp1 match {
+ final def matchesType(tp1: Type, tp2: Type, relaxed: Boolean): Boolean = tp1.widen match {
case tp1: MethodType =>
- tp2 match {
+ tp2.widen match {
case tp2: MethodType =>
tp1.isImplicit == tp2.isImplicit &&
matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
- matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), alwaysMatchSimple)
- case tp2: ExprType =>
- tp1.paramNames.isEmpty &&
- matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple)
- case _ =>
- false
- }
- case tp1: ExprType =>
- tp2 match {
- case tp2: MethodType =>
- tp2.paramNames.isEmpty &&
- matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple)
- case tp2: ExprType =>
- matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple)
- case _ =>
- false // was: matchesType(tp1.resultType, tp2, alwaysMatchSimple)
+ matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
+ case tp2 =>
+ relaxed && tp1.paramNames.isEmpty &&
+ matchesType(tp1.resultType, tp2, relaxed)
}
case tp1: PolyType =>
- tp2 match {
+ tp2.widen match {
case tp2: PolyType =>
sameLength(tp1.paramNames, tp2.paramNames) &&
- matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), alwaysMatchSimple)
+ matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
case _ =>
false
}
case _ =>
- tp2 match {
- case _: MethodType | _: PolyType =>
+ tp2.widen match {
+ case _: PolyType =>
false
- case tp2: ExprType =>
- false // was: matchesType(tp1, tp2.resultType, alwaysMatchSimple)
- case _ =>
- alwaysMatchSimple || isSameType(tp1, tp2)
+ case tp2: MethodType =>
+ relaxed && tp2.paramNames.isEmpty &&
+ matchesType(tp1, tp2.resultType, relaxed)
+ case tp2 =>
+ relaxed || isSameType(tp1, tp2)
}
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 6c87d44e6..e759c3ad3 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -598,17 +598,21 @@ object Types {
* - Either both types are polytypes with the same number of
* type parameters and their result types match after renaming
* corresponding type parameters
- * - Or both types are (possibly nullary) method types with equivalent parameter types
- * and matching result types
- * - Or both types are equivalent
- * - Or phase.erasedTypes is false and both types are neither method nor
- * poly types.
+ * - Or both types are method types with =:=-equivalent(*) parameter types
+ * and matching result types after renaming corresponding parameter types
+ * if the method types are dependent.
+ * - Or both types are =:=-equivalent
+ * - Or phase.erasedTypes is false, and neither type takes
+ * term or type parameters.
+ *
+ * (*) when matching with a Java method, we also regard Any and Object as equivalent
+ * parameter types.
*/
def matches(that: Type)(implicit ctx: Context): Boolean =
if (Config.newMatch) this.signature matches that.signature
else track("matches") {
ctx.typeComparer.matchesType(
- this, that, alwaysMatchSimple = !ctx.phase.erasedTypes)
+ this, that, relaxed = !ctx.phase.erasedTypes)
}
/** This is the same as `matches` except that it also matches => T with T and
diff --git a/src/dotty/tools/dotc/transform/OverridingPairs.scala b/src/dotty/tools/dotc/transform/OverridingPairs.scala
index f631dcf9a..650a03054 100644
--- a/src/dotty/tools/dotc/transform/OverridingPairs.scala
+++ b/src/dotty/tools/dotc/transform/OverridingPairs.scala
@@ -39,12 +39,7 @@ object OverridingPairs {
* relative to <base>.this do
*/
protected def matches(sym1: Symbol, sym2: Symbol): Boolean =
- sym1.isType || {
- val info1 = self.memberInfo(sym1)
- val info2 = self.memberInfo(sym2)
- // info1.signature == info2.signature && // TODO enable for speed
- info1 matches info2
- }
+ sym1.isType || self.memberInfo(sym1).matches(self.memberInfo(sym2))
/** The symbols that can take part in an overriding pair */
private val decls = {
diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 6ecd90c08..b59748247 100644
--- a/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -34,8 +34,11 @@ object EtaExpansion {
* lhs += expr
*/
def liftAssigned(defs: mutable.ListBuffer[Tree], tree: Tree)(implicit ctx: Context): Tree = tree match {
- case Apply(fn @ Select(pre, name), args) =>
- cpy.Apply(tree)(cpy.Select(fn)(lift(defs, pre), name), liftArgs(defs, fn.tpe, args))
+ case Apply(MaybePoly(fn @ Select(pre, name), targs), args) =>
+ cpy.Apply(tree)(
+ cpy.Select(fn)(
+ lift(defs, pre), name).appliedToTypeTrees(targs),
+ liftArgs(defs, fn.tpe, args))
case Select(pre, name) =>
cpy.Select(tree)(lift(defs, pre), name)
case _ =>
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index ce07ba74c..59aba4723 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -400,10 +400,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tree.lhs match {
case lhs @ Apply(fn, args) =>
typed(cpy.Apply(lhs)(untpd.Select(fn, nme.update), args :+ tree.rhs), pt)
- case untpd.TypedSplice(Apply(Select(fn, app), args)) if app == nme.apply =>
- typed(cpy.Apply(fn)(
- untpd.Select(untpd.TypedSplice(fn), nme.update),
- (args map untpd.TypedSplice) :+ tree.rhs), pt)
+ case untpd.TypedSplice(Apply(MaybePoly(Select(fn, app), targs), args)) if app == nme.apply =>
+ val rawUpdate: untpd.Tree = untpd.Select(untpd.TypedSplice(fn), nme.update)
+ val wrappedUpdate =
+ if (targs.isEmpty) rawUpdate
+ else untpd.TypeApply(rawUpdate, targs map untpd.TypedSplice)
+ val appliedUpdate = cpy.Apply(fn)(wrappedUpdate, (args map untpd.TypedSplice) :+ tree.rhs)
+ typed(appliedUpdate, pt)
case lhs =>
val lhsCore = typedUnadapted(lhs)
def lhs1 = typed(untpd.TypedSplice(lhsCore))
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 89ac2b6c4..21fdd555b 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -82,8 +82,8 @@ class tests extends CompilerTest {
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 4)
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 4)
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
- @Test def neg_over = compileFile(negDir, "over", xerrors = 1)
- @Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 7)
+ @Test def neg_over = compileFile(negDir, "over", xerrors = 3)
+ @Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 11)
@Test def neg_projections = compileFile(negDir, "projections", xerrors = 1)
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 1)
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 4)
diff --git a/tests/pending/pos/t3498-old.scala b/tests/disabled/not-representable/pos/t3498-old.scala
index 118a8d849..118a8d849 100644
--- a/tests/pending/pos/t3498-old.scala
+++ b/tests/disabled/not-representable/pos/t3498-old.scala
diff --git a/tests/pending/pos/t3175-pos.scala b/tests/disabled/structural-type/pos/t3175-pos.scala
index 89bbf8b5f..89bbf8b5f 100644
--- a/tests/pending/pos/t3175-pos.scala
+++ b/tests/disabled/structural-type/pos/t3175-pos.scala
diff --git a/tests/pending/pos/t3363-new.scala b/tests/disabled/structural-type/pos/t3363-new.scala
index f935cfe1a..835d9471b 100644
--- a/tests/pending/pos/t3363-new.scala
+++ b/tests/disabled/structural-type/pos/t3363-new.scala
@@ -7,7 +7,7 @@ object TestCase {
//if fs was reduced to List (generic type with one parameter) then the code compiles
//if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine
- implicit def map2ops[T,F](fs: Map[T,F]): TestCase.MapOps[F]{lazy val m: reflect.runtime.universe.TypeTag[T]; def is(xs: List[T]): List[List[T]]} = new MapOps[F] {
+ implicit def map2ops[T,F](fs: Map[T,F]): TestCase.MapOps[F]{val m: reflect.runtime.universe.TypeTag[T]; def is(xs: List[T]): List[List[T]]} = new MapOps[F] {
//if you remove this line, then code compiles
lazy val m: TypeTag[T] = sys.error("just something to make it compile")
def is(xs: List[T]) = List(xs)
diff --git a/tests/pending/pos/t3363-old.scala b/tests/disabled/structural-type/pos/t3363-old.scala
index 8e54d4b4a..0088eff3d 100644
--- a/tests/pending/pos/t3363-old.scala
+++ b/tests/disabled/structural-type/pos/t3363-old.scala
@@ -5,7 +5,7 @@ object TestCase {
//if fs was reduced to List (generic type with one parameter) then the code compiles
//if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine
- implicit def map2ops[T,F](fs: Map[T,F]): TestCase.MapOps[F]{lazy val m: Manifest[T]; def is(xs: List[T]): List[List[T]]} = new MapOps[F] {
+ implicit def map2ops[T,F](fs: Map[T,F]): TestCase.MapOps[F]{val m: Manifest[T]; def is(xs: List[T]): List[List[T]]} = new MapOps[F] {
//if you remove this line, then code compiles
lazy val m: Manifest[T] = sys.error("just something to make it compile")
def is(xs: List[T]) = List(xs)
diff --git a/tests/neg/over.scala b/tests/neg/over.scala
index 488d71614..80ce7d09f 100644
--- a/tests/neg/over.scala
+++ b/tests/neg/over.scala
@@ -8,3 +8,11 @@ class C extends T {
override val y = 2
}
+
+class D extends T {
+
+ def x(): String = ""
+
+}
+
+
diff --git a/tests/neg/overrides.scala b/tests/neg/overrides.scala
index 943cc8bc4..9fe06d930 100644
--- a/tests/neg/overrides.scala
+++ b/tests/neg/overrides.scala
@@ -79,3 +79,45 @@ class Y2 extends X2 {
class X3 {
override type T = A1
}
+
+package p3 {
+
+// Dotty change of rules: Toverrider#f does not
+// override TCommon#f, hence the accidental override rule
+// applies.
+trait TCommon {
+ def f: String
+}
+
+class C1 extends TCommon {
+ def f = "in C1"
+}
+
+trait TOverrider { this: TCommon =>
+ override def f = "in TOverrider" // The overridden self-type member...
+}
+
+class C2 extends C1 with TOverrider // ... fails to override, here.
+
+}
+
+package p4 {
+
+ abstract class C[T] { def head: T }
+ case class D[T](head: Int) extends C[T]
+
+}
+
+package p5 {
+class A {
+ def m: String = "foo"
+}
+
+class B extends A {
+ override val m: Int = 42
+}
+
+class C extends A {
+ override def m: Int = 42
+}
+}
diff --git a/tests/pending/pos/java-override/A.java b/tests/pending/pos/java-override/A.java
new file mode 100644
index 000000000..0d7f453e8
--- /dev/null
+++ b/tests/pending/pos/java-override/A.java
@@ -0,0 +1,3 @@
+public interface A {
+ void o(Object o);
+}
diff --git a/tests/pending/pos/java-override/B.scala b/tests/pending/pos/java-override/B.scala
new file mode 100644
index 000000000..cb4addbcc
--- /dev/null
+++ b/tests/pending/pos/java-override/B.scala
@@ -0,0 +1,7 @@
+//trait T { def t(o: Object): Unit }
+
+class B extends A /*with T*/ {
+ override def o(o: Any): Unit = ()
+
+ //override def t(o: AnyRef): Unit = ()
+}
diff --git a/tests/pending/pos/self-type-override.scala b/tests/pending/pos/self-type-override.scala
deleted file mode 100644
index 7c40ef37e..000000000
--- a/tests/pending/pos/self-type-override.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-trait TCommon {
- def f: String
-}
-
-class C1 extends TCommon {
- def f = "in C1"
-}
-
-trait TOverrider { this: TCommon =>
- override def f = "in TOverrider" // The overridden self-type member...
-}
-
-class C2 extends C1 with TOverrider // ... fails to override, here.
diff --git a/tests/pending/pos/t3278.scala b/tests/pending/pos/t3278.scala
deleted file mode 100644
index 458070c5e..000000000
--- a/tests/pending/pos/t3278.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-class Foo
-class Test {
- def update[B](x : B, b : Int): Unit = {}
- def apply[B](x : B) = 1
-}
-
-object Test {
- def main(a : Array[String]): Unit = {
- val a = new Test
- val f = new Foo
- a(f) = 1 //works
- a(f) = a(f) + 1 //works
- a(f) += 1 //error: reassignment to val
- }
-}
diff --git a/tests/pending/pos/t3480.scala b/tests/pending/pos/t3480.scala
index d9a092e8a..f04ea2933 100644
--- a/tests/pending/pos/t3480.scala
+++ b/tests/pending/pos/t3480.scala
@@ -1,4 +1,4 @@
object Test {
- val List(_*) = List(1)
+ val List(_: _*) = List(1)
val Array( who, what : _* ) = "Eclipse plugin cannot not handle this" split (" ")
}
diff --git a/tests/pending/pos/sammy_poly.scala b/tests/pos/sammy_poly.scala
index f43fa292c..f43fa292c 100644
--- a/tests/pending/pos/sammy_poly.scala
+++ b/tests/pos/sammy_poly.scala
diff --git a/tests/pending/pos/scoping1.scala b/tests/pos/scoping1.scala
index 9fe1b5f3e..83ad1357a 100644
--- a/tests/pending/pos/scoping1.scala
+++ b/tests/pos/scoping1.scala
@@ -2,7 +2,7 @@ object This extends App {
trait A {
def foo(): Unit
}
- class C { self: A =>
+ abstract class C { self: A =>
def bar() = this.foo()
}
class D extends C with A {
diff --git a/tests/pending/pos/sealed-final.scala b/tests/pos/sealed-final.scala
index bdedb5c1f..bdedb5c1f 100644
--- a/tests/pending/pos/sealed-final.scala
+++ b/tests/pos/sealed-final.scala
diff --git a/tests/pending/pos/spec-sealed.scala b/tests/pos/spec-sealed.scala
index d7ecfaaab..d7ecfaaab 100644
--- a/tests/pending/pos/spec-sealed.scala
+++ b/tests/pos/spec-sealed.scala
diff --git a/tests/pos/subtyping.scala b/tests/pos/subtyping.scala
index 29d830dd2..e65bdd16f 100644
--- a/tests/pos/subtyping.scala
+++ b/tests/pos/subtyping.scala
@@ -1,32 +1,5 @@
-class A {
- def test1(): Unit = {
- implicitly[this.type <:< this.type]
- implicitly[this.type <:< A]
- }
-}
object test {
- def tag1[T](x: T): String & T = ???
- def tag2[T](x: T): T & String = ???
-
- val x1: Int & String = tag1(0)
- val x2: Int & String = tag2(0)
- val x3: String & Int = tag1(0)
- val x4: String & Int = tag2(0)
-
-}
-
-object test2 {
-
- class A
- class B
-
- val x: A | B = ???
- val y: B | A = x
-
- val a: A & B = ???
- val b: B & A = a
+ val x: Int = 1
}
-
-
diff --git a/tests/pending/pos/t319.scala b/tests/pos/t319.scala
index eed25eb84..5c06f4db0 100644
--- a/tests/pending/pos/t319.scala
+++ b/tests/pos/t319.scala
@@ -14,7 +14,8 @@ object test {
val a = new A { type T = String };
/** val b: B { type T = String } = functor(a) */
val b: B { type T = String } = {
- val tmp = new functor() { val arg = a };
+ val tmp = new functor() { val arg: A { type T = String } = a };
+ // Dotty deviaton: arg needs an explicit type here, or else the inherited type `A` would be assumed.
tmp.res
}
diff --git a/tests/pending/pos/t3252.scala b/tests/pos/t3252.scala
index 3ecc1e7ce..3ecc1e7ce 100644
--- a/tests/pending/pos/t3252.scala
+++ b/tests/pos/t3252.scala
diff --git a/tests/pos/t3278.scala b/tests/pos/t3278.scala
new file mode 100644
index 000000000..05bfbc146
--- /dev/null
+++ b/tests/pos/t3278.scala
@@ -0,0 +1,30 @@
+class Foo
+class Test {
+ def update[B](x : B, b : Int): Unit = {}
+ def apply[B](x : B) = 1
+}
+class Test2 {
+ type B = Foo
+ def update(x : B, b : Int): Unit = {}
+ def apply(x : B) = 1
+}
+
+object Test {
+ def main(a : Array[String]): Unit = {
+ val a = new Test
+ val f = new Foo
+ a(f) = 1 //works
+ a(f) = a(f) + 1 //works
+ a(f) += 1 //error: reassignment to val
+ }
+}
+object Test2 {
+ def main(args : Array[String]): Unit = {
+ args(0) += "a"
+ val a = new Test2
+ val f = new Foo
+ a(f) = 1 //works
+ a(f) = a(f) + 1 //works
+ a(f) += 1 //error: reassignment to val
+ }
+}
diff --git a/tests/pending/pos/t3343.scala b/tests/pos/t3343.scala
index 9d1bc9355..9d1bc9355 100644
--- a/tests/pending/pos/t3343.scala
+++ b/tests/pos/t3343.scala
diff --git a/tests/pending/pos/t3411.scala b/tests/pos/t3411.scala
index 6d46be4e4..6d46be4e4 100644
--- a/tests/pending/pos/t3411.scala
+++ b/tests/pos/t3411.scala
diff --git a/tests/pending/pos/t344.scala b/tests/pos/t344.scala
index 449a763af..449a763af 100644
--- a/tests/pending/pos/t344.scala
+++ b/tests/pos/t344.scala