Skip to content

Requirements for type bounds stricter than scalac #525

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
smarter opened this issue May 2, 2015 · 5 comments
Closed

Requirements for type bounds stricter than scalac #525

smarter opened this issue May 2, 2015 · 5 comments

Comments

@smarter
Copy link
Member

smarter commented May 2, 2015

Not sure if this is something that we want to change or not, but:

class Foo[T] {
  def foo[A, B >: T <: A] = {}
}

fails with:

try/tv.scala:2: error: lower bound Foo$$T does not conform to upper bound A
  def foo[A, B >: T <: A] = {}
               ^
one error found

But it compiles with scalac.

The code can easily be changed to also compile with dotty:

def foo[A >: T, B >: T <: A] = {}

Do we want to be compatible with scalac here? I came across this because ./tests/pending/pos/strip-tvars-for-lubbasetypes.scala relies on it, but we could modify that test.

@smarter smarter changed the title Requirement for type bounds stricter than scalac Requirements for type bounds stricter than scalac May 2, 2015
@odersky
Copy link
Contributor

odersky commented May 3, 2015

I'd like to leave that open for a while. It would be good to get input from theory (DOT) on that question.

@samuelgruetter
Copy link
Contributor

From a soundness point of view, this shouldn't matter, because at use site, bounds conformance is checked anyways, and if a function is never used, nothing can go wrong.

But from a language design point of view, I find it more consistent to reject this example, because if you do "the same" with type members, it's also rejected:

class Foo[T] {
  type A
  type B >: T <: A
}

@odersky
Copy link
Contributor

odersky commented May 3, 2015

@samuelgruetter Good point. So I think we can leave it as it is.

@odersky odersky closed this as completed May 3, 2015
smarter added a commit to smarter/dotty that referenced this issue May 3, 2015
The test had to be slightly modified because of dotty's stricter
checking of type bounds validity, see scala#525 where this was discussed.
@odersky
Copy link
Contributor

odersky commented May 20, 2015

I agree now that soundness is not the issue. The problems I was thinking of before all had to do with null being handled specially or with lazy values. In short, we manufactured an empty type plus a value that had that type. The value was either null or a lazy val. Without this trick I do not see how empty bounds could cause us a problem.

@samuelgruetter
Copy link
Contributor

Turns out it's not a soundness issue, but an expressiveness issue: The test in tests/pending/pos/t4853.scala seems to do something "useful":

object Animal {
  def main(args: Array[String]): Unit = { new Animal[Awake].goToSleep }
}

class Animal[A <: AwakeOrAsleep] {
  def goToSleep[B >: A <: Awake]: Animal[Asleep] = new Animal[Asleep]
  def wakeUp[B >: A <: Asleep]: Animal[Awake] = new Animal[Awake]
}

sealed trait AwakeOrAsleep
trait Awake extends AwakeOrAsleep
trait Asleep extends AwakeOrAsleep

but it's rejected with the error lower bound Animal$$A does not conform to upper bound Awake.
One could rewrite this example to use a parameter (implicit evidence: A <:< Awake), though.

odersky added a commit to dotty-staging/dotty that referenced this issue Nov 5, 2015
As discussed in scala#780 and scala#525, the test is not needed. This makes
t1279a compile, which got moved now to pos. Fixes scala#780 and scala#915.
It also makes scala.List compile. Review by @smarter.
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

3 participants