[ty] don't iterate over a hashset (#21649)
## Summary
This caused "deterministic but chaotic" ordering of some intersection
types in diagnostics. When calling a union, we infer the argument type
once per matching parameter type, intersecting the inferred types for
the argument expression, and we did that in an unpredictable order.
We do need a hashset here for de-duplication. Sometimes we call large
unions where the type for a given parameter is the same across the
union, we should infer the argument once per parameter type, not once
per union element. So use an `FxIndexSet` instead of an `FxHashSet`.
## Test Plan
With this change, switching between `main` and
https://github.com/astral-sh/ruff/pull/21646 no longer changes the
ordering of the intersection type in the test in
cca3a8045d
This commit is contained in:
@@ -6894,10 +6894,14 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
// Infer the type of each argument once with each distinct parameter type as type context.
|
||||
let parameter_types = overloads_with_binding
|
||||
.iter()
|
||||
.filter_map(|(overload, binding)| parameter_type(overload, binding))
|
||||
.collect::<FxHashSet<_>>();
|
||||
.filter_map(|(overload, binding)| parameter_type(overload, binding));
|
||||
|
||||
let mut seen = FxHashSet::default();
|
||||
|
||||
for parameter_type in parameter_types {
|
||||
if !seen.insert(parameter_type) {
|
||||
continue;
|
||||
}
|
||||
let inferred_ty =
|
||||
self.infer_expression(ast_argument, TypeContext::new(Some(parameter_type)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user