From 212211d8af5f814474f2ea8421ae602e4f2763cd Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 15 Oct 2020 09:30:31 +0200 Subject: [PATCH] Fix #9994: Handle subtyping between two `ThisType` Previously, i9994.scala failed when compiled with `-Ythrough-tasty` with: 7 | def foo: this.type = this | ^ | error overriding method foo in trait Foo of type => (Bar.this : pkg.Bar); | method foo of type => (Bar.this : pkg.Bar) has incompatible type The two types were pretty-printed the same but were actually: ExprType(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),module class )),class Bar))) and ExprType(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),class Bar))) Fixed by explicitly handling subtyping between two `ThisType` (previously we felt through to `fourthTry` were the type of the lhs was widened), this is a rare case because `ThisType` are interned, so usually two `ThisType` to the same class are `eq` and therefore `isSubType` returns true. --- .../dotty/tools/dotc/core/TypeComparer.scala | 2 + .../test/BootstrappedStdLibTASYyTest.scala | 49 ------------------- tests/pos/i9994.scala | 7 +++ 3 files changed, 9 insertions(+), 49 deletions(-) create mode 100644 tests/pos/i9994.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 3e0a313ee869..de1b595f62f7 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -310,6 +310,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling def compareThis = { val cls2 = tp2.cls tp1 match { + case tp1: ThisType => + tp1.cls eq cls2 case tp1: NamedType if cls2.is(Module) && cls2.eq(tp1.typeSymbol) => cls2.isStaticOwner || recur(tp1.prefix, cls2.owner.thisType) || diff --git a/stdlib-bootstrapped-tasty-tests/test/BootstrappedStdLibTASYyTest.scala b/stdlib-bootstrapped-tasty-tests/test/BootstrappedStdLibTASYyTest.scala index 93b6e97f41bb..313aa5513aaa 100644 --- a/stdlib-bootstrapped-tasty-tests/test/BootstrappedStdLibTASYyTest.scala +++ b/stdlib-bootstrapped-tasty-tests/test/BootstrappedStdLibTASYyTest.scala @@ -149,55 +149,6 @@ object BootstrappedStdLibTASYyTest: "scala.Long", "scala.Short", "scala.Unit", - - // See #9994 - // -- Error: - // | def addOne(kv: (K, V)) = { - // | ^ - // |error overriding method addOne in trait Growable of type (elem: (K, V)): (TrieMap.this : scala.collection.concurrent.TrieMap[K, V]); - // | method addOne of type (kv: (K, V)): (TrieMap.this : scala.collection.concurrent.TrieMap[K, V]) has incompatible type - // -- Error: - // | def subtractOne(k: K) = { - // | ^ - // |error overriding method subtractOne in trait Shrinkable of type (elem: K): (TrieMap.this : scala.collection.concurrent.TrieMap[K, V]); - // | method subtractOne of type (k: K): (TrieMap.this : scala.collection.concurrent.TrieMap[K, V]) has incompatible type - "scala.collection.concurrent.TrieMap", - "scala.collection.immutable.HashMapBuilder", - "scala.collection.immutable.HashSetBuilder", - "scala.collection.immutable.LazyList", - "scala.collection.immutable.ListMapBuilder", - "scala.collection.immutable.MapBuilderImpl", - "scala.collection.immutable.SetBuilderImpl", - "scala.collection.immutable.TreeSeqMap", - "scala.collection.immutable.VectorBuilder", - "scala.collection.immutable.VectorMapBuilder", - "scala.collection.mutable.AnyRefMap", - "scala.collection.mutable.ArrayBuilder", - "scala.collection.mutable.CollisionProofHashMap", - "scala.collection.mutable.LongMap", - "scala.collection.mutable.SortedMap", - "scala.collection.mutable.StringBuilder", - "scala.jdk.AnyAccumulator", - "scala.jdk.DoubleAccumulator", - "scala.jdk.IntAccumulator", - "scala.jdk.LongAccumulator", - - // See #9994 - // -- Error: - // | override def filterInPlace(p: A => Boolean): this.type = { - // | ^ - // |error overriding method filterInPlace in trait SetOps of type (p: A => Boolean): (HashSet.this : scala.collection.mutable.HashSet[A]); - // | method filterInPlace of type (p: A => Boolean): (HashSet.this : scala.collection.mutable.HashSet[A]) has incompatible type - "scala.collection.mutable.HashSet", - - // See #9994 - // -- Error: - // | def force: this.type = { - // | ^ - // |error overriding method force in class Stream of type => (Cons.this : scala.collection.immutable.Stream.Cons[A]); - // | method force of type => (Cons.this : scala.collection.immutable.Stream.Cons[A]) has incompatible type - "scala.collection.immutable.Stream", - ) /** Set of classes that cannot be loaded from TASTy */ diff --git a/tests/pos/i9994.scala b/tests/pos/i9994.scala new file mode 100644 index 000000000000..d2125fe07df9 --- /dev/null +++ b/tests/pos/i9994.scala @@ -0,0 +1,7 @@ +package pkg + +trait Foo: + def foo: this.type + +final class Bar extends Foo: + def foo: this.type = this