Skip to content

Subtyping info lost when pattern matching on type of expression #15735

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
prolativ opened this issue Jul 22, 2022 · 6 comments
Closed

Subtyping info lost when pattern matching on type of expression #15735

prolativ opened this issue Jul 22, 2022 · 6 comments
Assignees
Labels
area:metaprogramming:quotes Issues related to quotes and splices area:typer

Comments

@prolativ
Copy link
Contributor

Compiler version

3.2.1-RC1-bin-20220721-634c580-NIGHTLY and earlier

Minimized code

//> using scala "3.2.1-RC1-bin-20220721-634c580-NIGHTLY"

import scala.quoted.*

trait Foo:
  type Number <: Int

trait Bar[T <: Int]

private def collectImpl[T : Type](using Quotes) =
  val expr: Expr[Foo] = ???
  expr match
    case '{ $enc: Foo { type Number = num } } =>
      Type.of[T] match
        case '[Bar[`num`]] => '{}

Output

[error] Macro.scala:15:20: Type argument num does not conform to upper bound Int
[error]         case '[Bar[`num`]] => '{}
[error]                    ^

Expectation

The compiler should be aware that num has to be a subtype of Int and the compilation should succeed

@nightscape
Copy link

@prolativ I'm just looking at the code of iskra, trying to implement the *.
Is this the reason the effort got stuck?

@prolativ
Copy link
Contributor Author

No, this should not be a blocker. I believe this problem could be worked around by replacing

case '[Bar[`num`]] =>

with

case '[Bar[n]] if Type.of[n] == Type.of[num] =>

@nicolasstucki
Copy link
Contributor

You probably need something like

Type.of[n] =:= Type.of[num]

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Feb 16, 2023

Solution

-    case '{ $enc: Foo { type Number = num } } =>
+    case '{ type num <: Int; $enc: Foo { type Number = `num` } } =>

@prolativ
Copy link
Contributor Author

@nicolasstucki was there any code changed in the compiler to fix this (there's no PR linked here)? Or is your SIP supposed to actually solve the problem?

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Jul 12, 2023

It is not a feature that is intended to work. In general, we have many issues related to type variable bound inference. We know that we should not be inferring those bounds because this kind of inference goes beyond what Scala is supposed to be able to do. A second issue is that this inference can infer useless bounds such as <: Nothing, while correct it makes the patterns not match the intended cases.

I am still working on a migration path out of this issue. I will open a SIP once I have all the pieces figured out.

This ability to infer type variable bounds was added as a workaround to be able have type matches with the variables that are bounded. Now we solved the original limitation with SIP-53. This SIP was the first step toward fixing this problem.

I also need to revisit #16932 (now revisited in #18195).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:quotes Issues related to quotes and splices area:typer
Projects
None yet
Development

No branches or pull requests

3 participants