Skip to content

Treating local class definitions as prefix-less is unsound #9693

Open
@scabug

Description

@scabug

As a fallout from scala/scala#4974 I ran into the following case:

According to http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#type-patterns prefix paths in type patterns need to be checked (i.e. they lead to outer ref checks). This is perfectly fine for prefixes that start at the top level scope, where it is impossible to have a static subtype of a non-static supertype.

By admitting class definitions inside of methods, however, one can construct a case where just that happens: A static (prefix-less, outer refs ignored) subtype of a non-static (with checked prefix) supertype, such that for types C <: B a value can match a type pattern \_: C but not \_: B:

object Outer4 extends App {
  var c: AnyRef = null
  class A {
    class B
    def f {
      class C extends B
      if(c ne null) {
        c match {
          case _: C => println("C")
          case _ => println("not C")
        }
        c match {
          case _: B => println("B")
          case _ => println("not B")
        }
      } else c = new C
    }
  }
  (new A).f
  (new A).f
}

In accordance with the spec, and under both outer ref check implementations (before and after #4974), this prints:

C
not B

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions