-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Reimplement support for type aliases in SAM types #18317
Conversation
Missing the test case? |
This was dropped in scala#18201 which restricted SAM types to valid parent types, but it turns out that there is code in the wild that relies on refinements being allowed here. To support this properly, we had to enhance ExpandSAMs to move refinements into type members to pass Ycheck (previous Scala 3 releases would accept the code in tests/run/i18315.scala but fail Ycheck). Fixes scala#18315.
oops yes |
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val s1: Sam1 { type T = String } = x => x.trim |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I'm asking for too much but I thought it would be nice if the type member of a SAM type could be inferred based on an explicitly provided type in a lambda, which led me to suggesting 2 additional test cases:
def foo[S <: Sam1](s: S): S = s
foo { (x: String) => x.trim }
def bar[A](s: Sam1 { type T = A }): s.type = s
bar { (x: String) => x.trim }
bar
works as expected but the application of foo
doesn't compile:
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |foo { (x: String) => x.trim }
| ^^^^^^
| Found: String
| Required: Sam1#T
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| Tree: x.trim()
| I tried to show that
| String
| conforms to
| Sam1#T
| but the comparison trace ended with `false`:
|
| ==> String <: Sam1#T
| <== String <: Sam1#T = false
|
| The tests were made under a constraint with:
| uninstantiated variables:
| constrained types: [S <: Sam1](s: S): S
| bounds:
| S <: Sam1
| ordering:
| co-deps:
| contra-deps:
-----------------------------------------------------------------------------
Would it be a big deal to make foo
work?
Otherwise LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely not make more things work in this space. What this PR "fixes" is already off-spec, because it is not legal to put a refinement type in an extends
clause. It happened to work in 3.3.0 by accident, and so we're preserving the status quo in the name of backward compatibility within a patch series. But we should in fact make it an error in 3.4.x.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I wouldn't want to add more than this and definitely not in a PR that fixes a regression
This was dropped in #18201 which restricted SAM types to valid parent types, but it turns out that there is code in the wild that relies on refinements being allowed here.
To support this properly, we had to enhance ExpandSAMs to move refinements into type members to pass Ycheck (previous Scala 3 releases would accept the code in tests/run/i18315.scala but fail Ycheck).
Fixes #18315.
This should be backported to any branch where #18201 is backported.