Skip to content

Compiling collections: dotty deviation: scalac seems to assume that class tparams are always subtypes of AnyREf #780

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

Closed
DarkDimius opened this issue Sep 1, 2015 · 5 comments

Comments

@DarkDimius
Copy link
Contributor

dotc List.scala
List.scala:162: error: lower bound scala$collection$immutable$List$$A does not conform to upper bound AnyRef
  @inline final def mapConserve[B >: A <: AnyRef](f: A => B): List[B] = {
                                  ^
@smarter
Copy link
Member

smarter commented Sep 1, 2015

This is not specific to AnyRef, scalac just does not require the lower bound to conform to the upper bound at the declaration site, it's only required at the use site:

class Foo[A] {
  def foo[B >: A <: Int] = 0 // scalac: works, dotc: lower bound does not conform to upper bound
}

This was reported as #525

@smarter
Copy link
Member

smarter commented Sep 1, 2015

@DarkDimius, @odersky : note that unlike what we discussed, scalac does have transitive subtyping:

class Foo[A](x: A) {
  def foo[B >: A <: AnyRef] = {
    x eq null // error: value eq is not a member of type parameter A
  }
}

The issue that @DarkDimius was seeing after removing the <: AnyRef bound was that B itself was no longer a subtype of AnyRef: https://github.com/scala/scala/blob/2.11.x/src/library/scala/collection/immutable/List.scala#L175 (the type of head1 is B).

If we remove the conformance check in dotty (https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/typer/Typer.scala#L846-L847, this is not a proper fix because we need to keep the check to disallow things like type A <: Int >: String) the remaining errors in List are:

List.scala:417: error: object creation impossible, since:
it has 2 unimplemented members.
/** As seen from module class Nil$, the missing signatures are as follows.
 *  For convenience, these are usable as stub implementations.
 */
  def productArity: => Int = ???
  def productElement: (n: Int)Any = ???

case object Nil extends List[Nothing] {
                  ^

This is because of issue #723. We can work around this issue by adding productArity and productElement ourselves, and at this point List.scala compiles!

@DarkDimius
Copy link
Contributor Author

@smarter, on my local setup, I am not seeing second error. Are you sure that you are running on master?

@smarter
Copy link
Member

smarter commented Sep 1, 2015

Yes, I'm on master, here's my List.scala: http://sprunge.us/NhCC . I created an empty directory, put List.scala in there and ran dotc List.scala

@odersky
Copy link
Contributor

odersky commented Nov 5, 2015

@smarter scalac also accepts type A >: Int <: String. Furthermore, subtyping does not seem to be transitive either. The following fails:

def f[B >: A <: AnyRef](x: A): AnyRef = x

Whereas this one succeeds:

def f[B >: A <: AnyRef](x: A): AnyRef = (x: B)

I don't know what the deal with eq is.

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

No branches or pull requests

3 participants