From cb6ba23b0a1ce223dd6d896d4e28ff1f93dba6fb Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Thu, 18 Dec 2025 09:17:00 +0100 Subject: [PATCH] More lazy negated computations --- .../ty_python_semantic/src/types/builder.rs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/ty_python_semantic/src/types/builder.rs b/crates/ty_python_semantic/src/types/builder.rs index 65396d04e9..b5042d41be 100644 --- a/crates/ty_python_semantic/src/types/builder.rs +++ b/crates/ty_python_semantic/src/types/builder.rs @@ -365,7 +365,7 @@ impl<'db> UnionBuilder<'db> { Type::StringLiteral(literal) => { let mut found = None; let mut to_remove = None; - let ty_negated = ty.negate(self.db); + let mut ty_negated = None; for (index, element) in self.elements.iter_mut().enumerate() { match element { UnionElement::StringLiterals(literals) => { @@ -383,8 +383,10 @@ impl<'db> UnionBuilder<'db> { } if existing.is_subtype_of(self.db, ty) { to_remove = Some(index); + continue; } - if ty_negated.is_subtype_of(self.db, *existing) { + let negated = ty_negated.get_or_insert_with(|| ty.negate(self.db)); + if negated.is_subtype_of(self.db, *existing) { // The type that includes both this new element, and its negation // (or a supertype of its negation), must be simply `object`. self.collapse_to_object(); @@ -410,7 +412,7 @@ impl<'db> UnionBuilder<'db> { Type::BytesLiteral(literal) => { let mut found = None; let mut to_remove = None; - let ty_negated = ty.negate(self.db); + let mut ty_negated = None; for (index, element) in self.elements.iter_mut().enumerate() { match element { UnionElement::BytesLiterals(literals) => { @@ -428,8 +430,11 @@ impl<'db> UnionBuilder<'db> { } if existing.is_subtype_of(self.db, ty) { to_remove = Some(index); + continue; } - if ty_negated.is_subtype_of(self.db, *existing) { + + let negated = ty_negated.get_or_insert_with(|| ty.negate(self.db)); + if negated.is_subtype_of(self.db, *existing) { // The type that includes both this new element, and its negation // (or a supertype of its negation), must be simply `object`. self.collapse_to_object(); @@ -455,7 +460,7 @@ impl<'db> UnionBuilder<'db> { Type::IntLiteral(literal) => { let mut found = None; let mut to_remove = None; - let ty_negated = ty.negate(self.db); + let mut ty_negated = None; for (index, element) in self.elements.iter_mut().enumerate() { match element { UnionElement::IntLiterals(literals) => { @@ -473,8 +478,11 @@ impl<'db> UnionBuilder<'db> { } if existing.is_subtype_of(self.db, ty) { to_remove = Some(index); + continue; } - if ty_negated.is_subtype_of(self.db, *existing) { + + let negated = ty_negated.get_or_insert_with(|| ty.negate(self.db)); + if negated.is_subtype_of(self.db, *existing) { // The type that includes both this new element, and its negation // (or a supertype of its negation), must be simply `object`. self.collapse_to_object();