Skip to content

(tp1 =:= tp2) != (tp1 <:< tp2) && (tp2 <:< tp1) #530

Open
@adriaanm

Description

@adriaanm

isSameType does not correspond to isSubtype the way you'd expected. Specifically, the case for refined types looks wrong (though compact):

case (RefinedType(ps1, ds1), RefinedType(ps2, ds2)) => 
  (ps1 corresponds ps2)(_ =:= _) && (ds1 isSameScope ds2)

Inlining the case for refined types of the definition of subtyping (in both directions), you'd expect something equivalent to:

    ps1.forall(p1 => ps2.exists(p2 => p2 <:< p1)) &&
    ps2.forall(p2 => ps1.exists(p1 => p1 <:< p2)) &&
    ds1.forall(d1 => specializesSym(tp2, d1)) &&
    ds2.forall(d2 => specializesSym(tp1, d2))

The above uses a more restricted form of scope equality:

    def isSameScope(other: Scope) = (
         (size == other.size)     // optimization - size is cached
      && (this isSubScope other)
      && (other isSubScope this)
    )

    def isSubScope(other: Scope) = {
      def scopeContainsSym(sym: Symbol): Boolean = {
        @tailrec def entryContainsSym(e: ScopeEntry): Boolean = e match {
          case null => false
          case _    =>
            val comparableInfo = sym.info.substThis(sym.owner, e.sym.owner)
            (e.sym.info =:= comparableInfo) || entryContainsSym(lookupNextEntry(e))
        }
        entryContainsSym(this lookupEntry sym.name)
      }
      other.toList forall scopeContainsSym
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions