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

type resolution with path-dependent types fails (works in Scala 2) #22210

Open
yurique opened this issue Dec 15, 2024 · 2 comments
Open

type resolution with path-dependent types fails (works in Scala 2) #22210

yurique opened this issue Dec 15, 2024 · 2 comments

Comments

@yurique
Copy link

yurique commented Dec 15, 2024

Compiler version

3.3.4, 3.6.2

Minimized code

trait Module {
  trait Reader[T]
}

class Builder[M <: Module](val m: M) {

  def json[Receive](implicit
                    reader: m.Reader[Receive], // path-dependent type here
                   ): Unit = {}

}

object mod extends Module

object Main {

  implicit val stringReader: mod.Reader[String] = new mod.Reader[String] {}

  def builder[M <: Module](m: M): Builder[M] = new Builder[M](m)

  def main(args: Array[String]): Unit = {
    builder(mod).json[String](stringReader) // the expected type of the reader parameter is Nothing  
   
  }

}

Output

$ scala-cli --scala 3.6.2 test.sc
Compiling project (Scala 3.6.2, JVM (17))
[error] ./test.sc:22:31
[error] Found:    (test$_.Main.stringReader : test$_.this.mod.Reader[String])
[error] Required: Nothing
[error]     builder(mod).json[String](stringReader) // the expected type of the reader parameter is Nothing
[error]                               ^^^^^^^^^^^^
Error compiling project (Scala 3.6.2, JVM (17))
Compilation failed
$ scala-cli --scala 2.13.15 test.sc
Compiling project (Scala 2.13.15, JVM (17))
Compiled project (Scala 2.13.15, JVM (17))

Expectation

I was expecting this to compile in Scala 3, since it compiles and works in Scala 2.13.
But I don't know if this is supposed to work, or if I'm doing it wrong, or if there is a workaround.

@yurique yurique added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 15, 2024
@Gedochao Gedochao added area:typer regression:scala2 and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 16, 2024
@KacperFKorban
Copy link
Member

This would be a workaround. i.e. Adding a type parameter with an upper bound.

//> using scala 3.nightly

trait Module {
  trait Reader[T]
}

class Builder[M <: Module](val m: M) {
  def json[Receive, R <: m.Reader[Receive]](using reader: R): Unit = {}
}

object mod extends Module

given stringReader: mod.Reader[String] = new mod.Reader[String] {}

def main(args: Array[String]): Unit = {
  new Builder(mod).json(using stringReader) // the expected type of the reader parameter is Nothing  
}

@yurique
Copy link
Author

yurique commented Dec 17, 2024

@KacperFKorban thank you for the suggestion!

The problem with this is I'll have to add that extra type parameter (R) and it will make it hard to use.

The real code where I encountered this has two type parameters, so it's even worse: https://github.com/tulz-app/laminext/blob/series/0.16.x/modules/websocket-upickle/src/main/scala/io/laminext/websocket/upickle/WebSocketReceiveBuilderUpickleOps.scala#L12

The usage would have to change from

val ws = 
  WebSocket
    .url("wss://echo.websocket.events")
    .upickle(OptionPickler)
    .json[DataToSend, DataToReceive]
    .build()

to

val ws = 
  WebSocket
    .url("wss://echo.websocket.events")
    .upickle(OptionPickler)
    .json[DataToSend, DataToReceive, OptionPickler.Reader[DataToSend], OptionPickler.Writer[DataToReceive]]
    .build()

which is far from perfect :)

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