Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expansion of wildcard to existential type ignores bound #2385

Closed
scabug opened this issue Sep 24, 2009 · 4 comments
Closed

Expansion of wildcard to existential type ignores bound #2385

scabug opened this issue Sep 24, 2009 · 4 comments

Comments

@scabug
Copy link

scabug commented Sep 24, 2009

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.

@scabug
Copy link
Author

scabug commented Sep 24, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2385?orig=1
Reporter: Kris Nuttycombe (nuttycom)

@scabug
Copy link
Author

scabug commented Sep 28, 2009

@cunei said:
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.

@scabug
Copy link
Author

scabug commented Sep 28, 2009

Kris Nuttycombe (nuttycom) said:

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?

@scabug
Copy link
Author

scabug commented Sep 28, 2009

@cunei said:
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant