Scala Programming Language
  1. Scala Programming Language
  2. SI-2385

Expansion of wildcard to existential type ignores bound

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Not a Bug
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Misc Compiler
    • Labels:
      None

      Description

      Given the following:

      abstract class A[T <: A[T]] {
        def foo: X[T]
      }
      
      class B extends A[B] {
        def foo = new X[B]
      } 
      
      class X[T <: A[T]]
      
      object Test {
        def test: X[_] = {
          val a: A[_] = new B
      
          def f[T <: A[T]](x: X[T]) = x
      
          f(a.foo)
        }
      }
      

      compilation fails as:

      Test.scala:18: error: inferred type arguments [_$$2] do not conform to method f's type parameter bounds [T <: A[T]]
          f(a.foo)
          ^
      

      even though it is not possible for any instance of A to fail to satisfy this bound. Explicitly specifying the existential type allows correct compilation:

      object Test {
        def test: X[_] = {
          val a: A[T] forSome {type T <: A[T]} = new B
      
          def f[T <: A[T]](x: X[T]) = x
      
          f(a.foo)
        }
      }
      

      It seems like A[_] is naively being expanded to A[T] forSome

      {type T}

      instead of respecting the bound declared in A. Minor, but unexpected.

        Issue Links

          Activity

          Hide
          Antonio Cunei added a comment -

          What you write corresponds to what is stated in the Scala specification (section "Placeholder Syntax for Existential Types").

          The syntax A[_] is equivalent to {{A[T] forsome

          { type T >: scala.Nothing <: scala.Any }

          }}. When you explicitly specify {{ val a:A[_] }} you are telling the compiler to assume that that one is the type of a.

          You can just write {{ val a = new B }} instead, and type inference will give you the specific type you are looking for.

          Show
          Antonio Cunei added a comment - What you write corresponds to what is stated in the Scala specification (section "Placeholder Syntax for Existential Types"). The syntax A [_] is equivalent to {{A [T] forsome { type T >: scala.Nothing <: scala.Any } }}. When you explicitly specify {{ val a:A [_] }} you are telling the compiler to assume that that one is the type of a . You can just write {{ val a = new B }} instead, and type inference will give you the specific type you are looking for.
          Hide
          Kris Nuttycombe added a comment -
          The syntax A[_] is equivalent to A[T] forsome { type T >: scala.Nothing <: scala.Any }.
          

          In this case, shouldn't the declaration

          val a: A[_]
          }}
          be a type error?

          Show
          Kris Nuttycombe added a comment - The syntax A[_] is equivalent to A[T] forsome { type T >: scala.Nothing <: scala.Any }. In this case, shouldn't the declaration val a: A [_] }} be a type error?
          Hide
          Antonio Cunei added a comment -

          No, in this case{{ A[T] forsome

          { type T >: scala.Nothing <: scala.Any }

          }}only means that there is one such T, you don't know what it is. The fact that in reality it can only be within a subset of the whole set of types doesn't make the declaration any less valid.

          To make an analogy, if I tell you "I will arrive on Monday, because I can only arrive on Mondays", and in turn you tell to someone else "He will arrive on some weekday", your assertion is still valid.

          Show
          Antonio Cunei added a comment - No, in this case{{ A [T] forsome { type T >: scala.Nothing <: scala.Any } }}only means that there is one such T, you don't know what it is. The fact that in reality it can only be within a subset of the whole set of types doesn't make the declaration any less valid. To make an analogy, if I tell you "I will arrive on Monday, because I can only arrive on Mondays", and in turn you tell to someone else "He will arrive on some weekday", your assertion is still valid.

            People

            • Assignee:
              Unassigned
              Reporter:
              Kris Nuttycombe
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development