Skip to content

Unnecessary widening of type parameter with path dependency #9531

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
nicolasstucki opened this issue Aug 11, 2020 · 2 comments · Fixed by #12099
Closed

Unnecessary widening of type parameter with path dependency #9531

nicolasstucki opened this issue Aug 11, 2020 · 2 comments · Fixed by #12099

Comments

@nicolasstucki
Copy link
Contributor

Minimized example

trait Scope:
  type Expr[+T]

def exprQuote[T](x: T)(using s: Scope): s.Expr[T] = ???

def test(using s: Scope): Unit =
  val t1: s.Expr[1] = exprQuote(1)
  val t2 = exprQuote(1)
  val t3: s.Expr[1] = t2

Output

-- [E007] Type Mismatch Error: Foo.scala:9:22 ----------------------------------
9 |  val t1: s.Expr[1] = exprQuote(1)
  |                      ^^^^^^^^^^^^
  |                      Found:    s.Expr[Int]
  |                      Required: s.Expr[(1 : Int)]
-- [E007] Type Mismatch Error: Foo.scala:11:22 ---------------------------------
11 |  val t3: s.Expr[1] = t2
   |                      ^^
   |                      Found:    (t2 : s.Expr[Int])
   |                      Required: s.Expr[(1 : Int)]

Expectation

Should be able to infer the precise type

@nicolasstucki
Copy link
Contributor Author

Similarly for

trait Scope {
  type Expr[+T]
}

object Test {
  def exprQuote[T](x: T)(implicit s: Scope): s.Expr[T] = ???

  def run[T](expr: (s: Scope) ?=> s.Expr[T]): T = ???

  def stage1(using s1: Scope)(x: s1.Expr[Int]): s1.Expr[(s2: Scope) ?=> s2.Expr[Int]] = ???

  def test(implicit s: Scope): Unit = {
    run[(s2: Scope) ?=> s2.Expr[Int]](stage1(exprQuote(1)))
  }
}
-- [E007] Type Mismatch Error: Foo.scala:15:47 ---------------------------------
15 |    val t1 = run[(s2: Scope) ?=> s2.Expr[Int]](stage1(exprQuote(1)) )
   |                                               ^^^^^^^^^^^^^^^^^^^^
   |           Found:    Scope#Expr[(s2: Scope) ?=> Scope#Expr[Int]]
   |           Required: (s: Scope) ?=> s.Expr[(s2: Scope) ?=> s2.Expr[Int]]

@odersky
Copy link
Contributor

odersky commented Aug 14, 2020

You can use two overloaded versions of exprQuote, like this:

def exprQuote[T](x: T)(using s: Scope, dummy: Null = null): s.Expr[T] = ???
def exprQuote[T <: Singleton](x: T)(using s: Scope): s.Expr[T] = ???

Then the example compiles.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 15, 2021
michelou pushed a commit to michelou/scala3 that referenced this issue Apr 16, 2021
@Kordyjan Kordyjan added this to the 3.0.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants