Skip to content

Commit

Permalink
Avoid allocating OrderedSet in UnionBuilder::simplify (#13206)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Waygood <[email protected]>
  • Loading branch information
MichaReiser and AlexWaygood committed Sep 2, 2024
1 parent 58c641c commit 9986397
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions crates/red_knot_python_semantic/src/types/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
//! * No type in an intersection can be a supertype of any other type in the intersection (just
//! eliminate the supertype from the intersection).
//! * An intersection containing two non-overlapping types should simplify to [`Type::Never`].

use crate::types::{IntersectionType, Type, UnionType};
use crate::{Db, FxOrderSet};
use ordermap::set::MutableValues;

use super::builtins_symbol_ty_by_name;

Expand Down Expand Up @@ -63,23 +65,31 @@ impl<'db> UnionBuilder<'db> {
/// - TODO For enums `E` with members `X1`,...,`Xn`, replaces
/// `Literal[E.X1,...,E.Xn]` with `E`.
fn simplify(&mut self) {
if self
.elements
.is_superset(&[Type::BooleanLiteral(true), Type::BooleanLiteral(false)].into())
{
let bool_ty = builtins_symbol_ty_by_name(self.db, "bool");
self.elements.remove(&Type::BooleanLiteral(true));
self.elements.remove(&Type::BooleanLiteral(false));
self.elements.insert(bool_ty);
if let Some(true_index) = self.elements.get_index_of(&Type::BooleanLiteral(true)) {
if self.elements.contains(&Type::BooleanLiteral(false)) {
*self.elements.get_index_mut2(true_index).unwrap() =
builtins_symbol_ty_by_name(self.db, "bool");
self.elements.remove(&Type::BooleanLiteral(false));
}
}
}

pub(crate) fn build(mut self) -> Type<'db> {
self.simplify();
match self.elements.len() {
0 => Type::Never,
1 => self.elements[0],
_ => Type::Union(UnionType::new(self.db, self.elements)),
_ => {
self.simplify();

match self.elements.len() {
0 => Type::Never,
1 => self.elements[0],
_ => {
self.elements.shrink_to_fit();
Type::Union(UnionType::new(self.db, self.elements))
}
}
}
}
}
}
Expand Down Expand Up @@ -360,7 +370,7 @@ mod tests {
panic!("expected a union");
};

assert_eq!(union.elements_vec(&db), &[t3, bool_ty]);
assert_eq!(union.elements_vec(&db), &[bool_ty, t3]);
}

#[test]
Expand Down

0 comments on commit 9986397

Please sign in to comment.