Skip to content

f-bounds and wildcards don't mix? #6146

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
adriaanm opened this issue Mar 22, 2019 · 7 comments
Closed

f-bounds and wildcards don't mix? #6146

adriaanm opened this issue Mar 22, 2019 · 7 comments

Comments

@adriaanm
Copy link
Contributor

adriaanm commented Mar 22, 2019

I think the following should compile (it does in 2.13), but it produces the following errors (note the LazyRef in the error message):

  trait BS[T, S <: BS[T, S]]
  trait IS extends BS[Int, IS]

  sealed trait BSElem[T, S <: BS[_, S]] // we cannot make this S <: BS[T, S], as the `_` could be something else from T (that's what the `BSElem` implicit is for)

  /*
-- [E057] Type Mismatch Error: /Users/adriaan/git/scala/src/library/scala/collection/convert/StreamExtensions.scala:34:36 
34 |  sealed trait BSElem[T, S <: BS[_, S]]
   |                                    ^
   |Type argument S does not conform to upper bound StreamExtensions.this.BS[Any, LazyRef(S)] 
*/

  object BSElem {
    implicit val intStreamShape: BSElem[Int, IS] = ???
  }
  class Ops[A] {
    def asJavaSeqStream[S <: BS[_, S]](implicit s: BSElem[A, S]): S = ???
    /*
  -- [E057] Type Mismatch Error: /Users/adriaan/git/scala/src/library/scala/collection/convert/StreamExtensions.scala:39:35 
  39 |    def asJavaSeqStream[S <: BS[_, S]](implicit s: BSElem[A, S]): S = ???
     |                                   ^
     |Type argument S does not conform to upper bound StreamExtensions.this.BS[Any, LazyRef(S)] 
    */
  }
@adriaanm
Copy link
Contributor Author

This is blocking scala/scala#7458

smarter added a commit to dotty-staging/dotty that referenced this issue Mar 22, 2019
Don't map arguments to their upper bounds before doing the bound check.
There was a comment justifiying that by talking about non
fully-determined arguments, but this check is done in PostTyper when all
types should already be fully-determined. Given that this comment was
written in 2014 I'm assuming it's no longer relevant.
smarter added a commit to dotty-staging/dotty that referenced this issue Mar 22, 2019
Don't map arguments to their upper bounds before doing the bound check.
There was a comment justifiying that by talking about non
fully-determined arguments, but this check is done in PostTyper when all
types should already be fully-determined. Given that this comment was
written in 2014 I'm assuming it's no longer relevant.
@smarter
Copy link
Member

smarter commented Mar 22, 2019

@adriaanm @lrytz Any reason why the following wouldn't work:

trait BS[T, S <: BS[T, S]]
trait IS extends BS[Int, IS]

sealed trait BSElem[T, S <: BS[T, S]]

object BSElem {
  implicit val intStreamShape: BSElem[Int, IS] = ???
}
class Ops[A] {
  def asJavaSeqStream[S <: BS[A, S]](implicit s: BSElem[A, S]): S = ???
}

@adriaanm
Copy link
Contributor Author

adriaanm commented Mar 22, 2019 via email

@lrytz
Copy link
Member

lrytz commented Mar 22, 2019

Yes, I tried that as well...

@smarter
Copy link
Member

smarter commented Mar 22, 2019

A full example would be helpful

@lrytz
Copy link
Member

lrytz commented Mar 23, 2019

Here's a full example that, I think, reflects the situation. The source of the problem might be because of the use of Integer (BS/AS/IS are defined in Java in the original). The version below compiles with scalac, but not dotty. Use the two commented-out lines instead is what you suggest above, and then the implicit is not found. Maybe it's just a matter of adding more implicit instances (for Integer), I'll check later - don't have time right now anymore :-)

trait St[A]
trait IntSt extends St[Int]
trait AnySt[T] extends St[T]

trait StS[T, S <: St[_]]
trait StSL {
  implicit def anyStS[T]: StS[T, AnySt[T]] = ???
}
object StS extends StSL {
  implicit val intStS: StS[Int, IntSt] = ???
}

trait BS[T, S <: BS[T, S]]
trait AS[T] extends BS[T, AS[T]]
trait IS extends BS[java.lang.Integer, IS]

trait SS[T, S <: BS[_, S], Z <: St[_]]
// trait SS[T, S <: BS[T, S], Z <: St[_]]
trait SSL {
  implicit def anySS[T]: SS[T, AS[T], AnySt[T]] = ???
}
object SS extends SSL {
  implicit val iss: SS[Int, IS, IntSt] = ???
}

object T {
  implicit class ListExt[A](l: List[A]) {
    def ext[S <: BS[_, S], Z <: St[_]](implicit sh: SS[A, S, Z], sth: StS[A, Z]): S = ???
    // def ext[S <: BS[A, S], Z <: St[_]](implicit sh: SS[A, S, Z], sth: StS[A, Z]): S = ???
  }
}

object U {
  import T._
  List(1).ext: IS
}

@lrytz
Copy link
Member

lrytz commented Mar 23, 2019

Fixed in the PR by relaxing the bound

trait SS[T, S <: BS[_, _], Z <: St[_]]

...

    def ext[S <: BS[_, _], Z <: St[_]](implicit sh: SS[A, S, Z], sth: StS[A, Z]): S = ???

I cannot answer if dotty is right to report an error in the original example in the issue description.

odersky added a commit that referenced this issue Mar 25, 2019
Fix #6146: Fix bounds check involving wildcards and f-bounds
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