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

Upper bound lost from Int to Any on Scala 3.1.2 and later #18253

Closed
soronpo opened this issue Jul 20, 2023 · 6 comments · Fixed by #18419
Closed

Upper bound lost from Int to Any on Scala 3.1.2 and later #18253

soronpo opened this issue Jul 20, 2023 · 6 comments · Fixed by #18419
Assignees
Labels
area:default-parameters area:typer itype:bug regression This worked in a previous version but doesn't anymore

Comments

@soronpo
Copy link
Contributor

soronpo commented Jul 20, 2023

Pretty weird error. It disappears when removing the clue parameter from check.

Compiler version

3.1.1 - compiles
3.1.2 and later - compilation error

Minimized code

import compiletime.ops.int.Max

trait DFSInt[W <: Int]
trait Candidate[R]:
  type OutW <: Int
object Candidate:
  given [W <: Int, R <: DFSInt[W]]: Candidate[R] with
    type OutW = W

def foo[R](rhs: R)(using icR: Candidate[R]): DFSInt[Max[8, icR.OutW]] = ???

object Test:
  def check[A](a: A, clue: Int = 1): Unit = ???
  val x: DFSInt[8] = ???
  check(foo(x))

Output

Type argument Any does not conform to upper bound Int in subpart compiletime.ops.int.Max[(8 : Int), Any] of inferred type 
  Playground.DFSInt[?
     >: compiletime.ops.int.Max[(8 : Int), Any] & (8 : Int) <: 
      compiletime.ops.int.Max[(8 : Int), Any]
     | (8 : Int)
  ]

Expectation

Should compile.

@soronpo soronpo added itype:bug regression This worked in a previous version but doesn't anymore stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 20, 2023
@soronpo
Copy link
Contributor Author

soronpo commented Jul 20, 2023

First bad nightly: 3.1.2-RC1-bin-20211217-b3ab102-NIGHTLY

@jchyb jchyb added area:typer and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 20, 2023
@Kordyjan
Copy link
Contributor

@soronpo You have mentioned elsewhere that this issue manifested to you as you bumped the compiler version from 3.3.0 to 3.3.1-RCx. Did it happen in https://github.com/DFiantHDL/DFiant or another project? Which branch was that? I wanted to investigate what exactly changed between 3.3.0 and 3.3.1-RCx.

BTW. Since there is at least one released version on Maven Central, DFiant will be part of the Open CB starting this weekend, so new regressions will be detected (and even bisected) automatically.

@soronpo
Copy link
Contributor Author

soronpo commented Aug 11, 2023

@Kordyjan Thank you for looking into this. I'm hesitant on putting the library in the OpenCB since it's still a WIP, but I see the benefit since it's a regression magnet 😄. I created a branch that will be stable for the community build: scala_opencb
https://github.com/DFiantHDL/DFiant/tree/scala_opencb

Locally just check out the branch and run sbt test. You should see the tests pass.
If you update to 3.3.1-RC5, you will hit issue #18171, so until that is backported you won't be seeing the other issues that I mentioned like this one and #18263. You can see them if you use the 3.3.2-nightly release. I hope this makes things clearer.

@SethTisue
Copy link
Member

SethTisue commented Aug 17, 2023

Dale and I are digging into this, at least experimentally. No idea yet what a fix might look like.

Here's the test code minimized a bit further:

import scala.compiletime.ops.int.Max

trait Foo[A]
trait Bar[B]:
  type Out <: Int
object Bar:
  given inst[C <: Int]: Bar[C] with
    type Out = C

class Test:
  def mkFoo(using bx: Bar[2]): Foo[Max[1, bx.Out]] = ???
  def check[Y](yy: Y, clue: Int = 1): Unit = ()

  def test: Unit = check(mkFoo)

it's a bit less noisy, but all the big pieces are still there, despite our best efforts 😕

@SethTisue
Copy link
Member

Note that a default getter always has all the same type parameters as the method it comes from, even if they aren't used. So the getter for clue has the type parameter Y. So that helps explain why the default argument is even relevant here.

@soronpo
Copy link
Contributor Author

soronpo commented Aug 17, 2023

Note that a default getter always has all the same type parameters as the method it comes from, even if they aren't used. So the getter for clue has the type parameter Y. So that helps explain why the default argument is even relevant here.

Oh, finally it make some sense. I was really surprised when I got this minimization.

@dwijnand dwijnand linked a pull request Aug 17, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:default-parameters area:typer itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants