-
Notifications
You must be signed in to change notification settings - Fork 1.1k
More consistent results for union types in pickling #15515
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
More consistent results for union types in pickling #15515
Conversation
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit https://dotty-bench.epfl.ch/15515/ to see the changes. Benchmarks is based on merging with main (5a8a61d) |
For the statement: I'm confused because with I agree that |
Oh, I see, it's with A desirable property (though it might not be achievable) would be for unsafeNulls to not affect computed lubs. More generally, for unsafeNulls to not affect inferred types, but only to relax certain subtyping checks. |
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.
I don't think lub should call simplified. That's really not supported by the architecture.
It is difficult to relax the pickling test just for unsafe nulls. We are not comparing the individual types in the test, because the strings of the two trees are compared directly. It is also difficult to trick the printer to ignore |
Could the printer ignore |
I don't think it is a good idea for explicit nulls (without unsafe nulls). The nullable types are important in this case. |
Could we canonicalize the types in the trees before printing them to strings in the unpickler testing code? This would require a tree transformation that creates a new tree with transformed types. |
We can call |
e940726
to
9611cb5
Compare
9611cb5
to
48562d1
Compare
I don't think adding a TreeMap and running it on the whole tree twice is a good idea. So I delete it and add type simplify to PostTyper, which should achieve the same result. The tests here are all passed, then I tested #14946 based on this PR. There are still some pickling errors. If a tree is loaded by For example:
MainGenericRunner.processClasspath("")
import scala.language.unsafeNulls
object MainGenericRunner {
def processClasspath(cp: String) =
val singleEntryClasspath: Boolean = ???
// The type of the If node is `String | Null`,
// it should be simplified to `String` in unsafe nulls
val globdir: String = if singleEntryClasspath then cp.replaceAll("[\\\\/][^\\\\/]*$", "") else ""
globdir
} If we compile If we compile I tried to read Imports in |
Good catch. I thought the TreeMap just for the pickling tests was fine, but if simplifying in PostTyper can fix all the failures, I agree that's less clunky. So this is another example in the line of issues caused by language imports not being considered everywhere. I don't know enough about the deferred unpickling to suggest how to fix this. Is the cyclic reference specific for unsafeNulls (after you already know that the import is unsafeNulls) or does it happen when trying to resolve the symbol in the import? More generally, I wonder whether language imports should be pickled as something more specific than just general imports. |
48562d1
to
f8aa09e
Compare
f8aa09e
to
83a60b6
Compare
Hey @noti0na1, it's been a while here. Do you plan on returning, or are you waiting for a review from someone? How can I help you move this forward? |
Close this PR for now. Plan to revisite this bug soon. |
This PR tries to fix some of the pickling errors in #14946.
#15105 was an attempt to solve the errors of different union types in unpickler, by simplifying the type of match and try nodes.
We thought Typer performs a simplification step after type assigning a tree, so we should do the same step in unpickler. But this is not correct, because the tree before Pickler phase is posttyper, which does not perform a simplification.
The reason why #15105 fixes some of the errors because
lub
does not return a consistant result. But this also introduces more errors in the test.Let's consider a case:
lub(List(String | Null, String, Null))
. Insidelub
we have:So, depends on the order of arguments, we may get
String
orString | Null
.This PR adds a TreeTransformer to the Pickling, so it can overwrite the types of If, Match, and Try nodes before and after pickling with the simplified version. Hopefully, we can always get consistent types during comparison.