-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Regression in getkyo/kyo
for match types / type inference
#22661
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
Comments
fyi @fwbrasil |
cc @dwijnand |
I'm not sure this is a bug. The same code before #19761 wouldn't have compiled (that I could find) and there's nothing wrong about the avoidance. The reason it widens all the way to
|
The |
Here's original implementation: https://github.com/getkyo/kyo/blob/c060b4164b24868beaa05b6d01078c6b8b1d3f88/kyo-data/shared/src/main/scala/kyo/internal/TypeIntersection.scala#L68-L85 That's also what I initially thought, but the results were the same either if rhs was only ??? or calling an Inliner[R] returning |
I have minimized it to //> using scala 3.6.4-RC1-bin-20241209-1775d0b-NIGHTLY
case class Field[Name](name: Name)
opaque type AsField[Name] = Field[Name] // is compiling without opaque
def toField[Name](as: AsField[Name]): Unit = ()
type HasAsField[f] /*<: AsField[?]*/ = // is compiling with bound
f match
case Field[name] => AsField[name]
def x: List[HasAsField[Any]] = ???
x.map(toField)
/* compiler error:
Found: (as : tagadt$_.this.HasAsField[Any])
[error] Required: tagadt$_.this.AsField[Name]
*/
def y: HasAsField[Any] = ???
toField(y) // is not compiling even with upper bound Upper type bound also fixes the original issue in this particular case. |
Yeah |
I wonder if we should make |
I'm pretty sure that's what it does. But here it's hidden behind an |
My point is, given an opaque type alias, applied to wildcard args, where all args end up as args of a class type constructor, is that one of those dangerous akin-to-an-existential that we're trying to protect against? Because if it's not, then perhaps we can allow things like AsField. |
I think it is. You can't find a non-existential form for this which does not reveal the opaque type alias, which is also not allowed. |
Surely it's allowed within the compiler's calculations? I'm not suggesting we dealias away the opaque type, i.e. return I guess I don't understand the existential types problem. I thought it was similar or related to the bad type bounds can lead to unsoundness, but here I don't understand how the opaqueness of AsField can lead to unsoundness. I feel like match aliases are in a similar spot, and there we're swinging all the way the other way and just exempting them - Oh, and btw I checked and |
The thing is we don't have a theory for existential types in the Scala context. We don't know how they should behave. So we have to reduce a seemingly existential type to something we do know how to reason about. And we can't in this case. |
we talked about this a bit at core meeting and somebody was supposed to comment here with further details... but I don't remember who... was it @sjrd? |
I think we should close this (as mentioned before). |
Ah yes, me. So yes, after discussion, we consider this a progression. Previously, the type checker was inferring an unsound bound for the match type. That unsound bound leaked a type variable outside of its defining scope, namely For this case, though, the solution today is to explicitly annotate the desired bound, which is Eventually, though, we expect that we will have to rule out wildcard arguments to opaque type aliases altogether, because they're also basically unsound (although it's less obvious than a type variable escaping its scope). So |
Thank you everyone for working on this regression. @sjrd I'm attempting to upgrade to private type HasAsField[Field] <: AsField[?, ?] =
Field match
case name ~ value => AsField[name, value]
inline def summonAsField[Fields](using ev: TypeIntersection[Fields]): Set[Field[?, ?]] =
TypeIntersection.summonAll[Fields, HasAsField].map(Record.AsField.toField).toSet
|
Fixes problem from scala/scala3#22661 (comment) Also I have got new compiler warnings that inner (inside `def`) types `cannot be checked at runtime because it's a local class`, so I moved It to internal object.
@road21 already fixed it on our side. Thank you! getkyo/kyo#1091 |
Based on OpenCB failure in
getkyo/kyo
Compiler version
Last good release: 3.6.4-RC1-bin-20241205-c61897d-NIGHTLY
First bad release: 3.6.4-RC1-bin-20241209-1775d0b-NIGHTLY
Affects 3.6.4-RC1
Bisect points to 2f6e60d
Minimized code
Output
Expectation
Should probably compile
The text was updated successfully, but these errors were encountered: