Conversation
|
|
Hmm, this is indeed painful and also increases the work necessary to normalize types (because it's now necessary to perform a deep comparison).
I wonder if this is actually a problem. I'm not sure if it will be when we start garbage collecting interned values but is it today? |
I don't understand? astral-sh/ty#369 (comment) definitely feels like an actual problem to me. It's not just non-deterministic, it's also incorrect (sometimes). |
cd6a2d3 to
6e83ce9
Compare
The benchmarks seem completely neutral: https://codspeed.io/astral-sh/ruff/branches/david%2Fstable-ordering |
|
I'm not sure I fully understand yet whether the problem is:
|
I don't fully understand this point. Could you possibly give an example? |
| } | ||
| } | ||
|
|
||
| pub(crate) fn ordering(self, db: &'db dyn Db, other: Self) -> std::cmp::Ordering { |
There was a problem hiding this comment.
I guess this would be tricky to enforce unless salsa avoids adding PartialOrd, Ord to the interned structs as pointed out by Micha and in the linked salsa discussion.
| } | ||
|
|
||
| pub(crate) fn ordering(self, db: &'db dyn Db, other: Self) -> Ordering { | ||
| self.variables(db) |
There was a problem hiding this comment.
Do we need to implement .ordering for TypeVarInstance as it's interned?
I'm mainly questioning whether we need to override everywhere. We definitely should override it if it otherwise leads to incorrect ordering. I don't think we have to override in cases where it's only about determinism because ids are then a very convenient and fast way to arbitrarily sort items (if the only goal is that they have a fixed ordering but don't require a specific semantic ordering) It's not quite clear to me what you're fixing in this pr (at least one case seems semantic) |
|
I think our prior assumption was that ordering of types need only be deterministic within a given run of |
Until we implement persistent caching :-) |
Haha, fair. Although salsa might solve this if the rematerialized structs retain their relative order |
Summary
Our type ordering/normalization previously relied on
PartialOrd/Ordinstances that were auto-generated forsalsa::internedstructs. These implementations compare by salsa ID, which is not necessarily deterministic (depends on when a particular type has been interned, and can therefore depend on file checking order).Besides not being deterministic, it was also incorrect. When comparing two equal unions
A1 | B1andA2 | B2, it was possible for one union to be ordered incorrectly (e.g. if bothA1andB1were interned nominal instances), leading to incorrect type-relation results.Writing these
orderingfunctions by hand is exhausting and error-prone. This is why I only went so far as to fix the linked bug. Much more work would be involved to implement this for structs likeFunctionTypeorCallableType. We should probably look into auto-generating these methods somehow?Related salsa discussion
fixes astral-sh/ty#369
Test Plan
Ran the following command for a while and saw no flaky behavior (on the MRE from the linked ticket):