Skip to content

Commit

Permalink
Fix scala#9994: Handle subtyping between two ThisType
Browse files Browse the repository at this point in the history
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 <root>)),module class <empty>)),class Bar)))

and

ExprType(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),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.
  • Loading branch information
smarter committed Oct 27, 2020
1 parent 6098ec2 commit 212211d
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 49 deletions.
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i9994.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pkg

trait Foo:
def foo: this.type

final class Bar extends Foo:
def foo: this.type = this

0 comments on commit 212211d

Please sign in to comment.