-
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
Cut the Gordian Knot: Don't widen unions to transparent #15642
Conversation
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit https://dotty-bench.epfl.ch/15642/ to see the changes. Benchmarks is based on merging with main (79d9a6f) |
ddd9a49
to
4f488bf
Compare
If that makes sense, then it probably makes sense to also treat Unrelated to the above: I expect this change to have a significant impact on source compatibility. Although we never promise source compatibility, perhaps this one is strong enough that it would warrant a minor release? |
@sjrd I agree it would need a minor release. It might need a SIP as well, even though so far we have not talked about type inference in the SIP committee, despite many changes and improvements that happened in Scala 2 and 3. That said, I am positively surprised how little code broke. All the tests that failed were simply testing for type inference predictions that are now improved. Nothing else in our code base or in the community build broke. I would not have expected that when I set out to try this change. |
6892f17
to
26e5f2a
Compare
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.
LGTM (commetting to avoid it being merged)
The idea is that some unions usually make more sense than others. For instance, if `Apply` and `Ident` are case classes that extend `Tree`, it makes sense to widen `Apply | Ident` to `Tree`. But it makes less sense to widen `String | Int` to `Matchable`. Making sense means: (1) Matches our intuitive understanding, and (2) choosing not to widen would usually not cause errors. To explain (2): In the `Tree` case it might well be that we define an implicits on `Inv[Tree]` for invariant class `Inv`, and then we would not find the implicit for `Inv[Apply | Ident]`. But it's much less likely that we are looking for an implicit of type `Inv[Any]`. This commit does two things: - add logic not to widen a union if the result is a product of only transparent traits or classes. - treat `Any`, `AnyVal`, `Object`, and `Matchable` as transparent.
- include js.Any and js.Object - include others ...Ops and Is... classes from collections - Change the implementation so that we don't have to load traits or classes that are assumed transparent.
They give test failures, and I don't know enough about the js class hierarchy to be able to fix them with confidence.
c1a6624
to
74c079f
Compare
@odersky happy to merge this now? |
I am OK with merging. I'll give this another 24 hours in case someone wants to object. |
I'm a bit wary of trying to solve our union inference issues by adding more special cases, in particular it might have the unintended consequence of encouraging people to add |
- Introduce hard and soft unions - Explain how transparency of base traits influences type inference - Drop outdated note on possible future changes
@smarter I updated the docs on union types. Do you want to take a look? |
Co-authored-by: Guillaume Martres <[email protected]>
add |
The idea is that some unions usually make more sense than others. For instance,
if
Apply
andIdent
are case classes that extendTree
, it makes sense towiden
Apply | Ident
toTree
. But it makes less sense to widenString | Int
to
Matchable
.Making sense means: (1) Matches our intuitive understanding, and (2) choosing not to
widen would usually not cause errors.
To explain (2): In the
Tree
case it might well be that we define a given forInv[Tree]
forinvariant class
Inv
, and then we would not find that given forInv[Apply | Ident]
.But it's much less likely that we are looking for a given of type
Inv[Any]
.This commit does two things:
Any
,AnyVal
,Object
, andMatchable
as transparent.