Skip to content

Commit 1fd3d21

Browse files
committed
wip
1 parent 0868e73 commit 1fd3d21

File tree

6 files changed

+47
-21
lines changed

6 files changed

+47
-21
lines changed

crates/red_knot_python_semantic/src/symbol.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,10 +549,11 @@ fn symbol_from_bindings_impl<'db>(
549549
};
550550

551551
if let Some(second) = types.next() {
552-
Symbol::Type(
553-
UnionType::from_elements(db, [first, second].into_iter().chain(types)),
554-
boundness,
555-
)
552+
let ty = UnionBuilder::new(db)
553+
.extend([first, second])
554+
.extend(types)
555+
.build();
556+
Symbol::Type(ty, boundness)
556557
} else {
557558
Symbol::Type(first, boundness)
558559
}

crates/red_knot_python_semantic/src/types.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4172,16 +4172,15 @@ impl<'db> UnionType<'db> {
41724172

41734173
/// Create a union from a list of elements
41744174
/// (which may be eagerly simplified into a different variant of [`Type`] altogether).
4175-
pub fn from_elements<I, T>(db: &'db dyn Db, elements: I) -> Type<'db>
4175+
pub fn from_elements<I, E, T>(db: &'db dyn Db, elements: I) -> Type<'db>
41764176
where
4177-
I: IntoIterator<Item = T>,
4177+
I: IntoIterator<IntoIter = E>,
4178+
E: ExactSizeIterator<Item = T>,
41784179
T: Into<Type<'db>>,
41794180
{
4180-
elements
4181-
.into_iter()
4182-
.fold(UnionBuilder::new(db), |builder, element| {
4183-
builder.add(element.into())
4184-
})
4181+
let elements = elements.into_iter();
4182+
UnionBuilder::with_capacity(db, elements.len())
4183+
.extend(elements)
41854184
.build()
41864185
}
41874186

crates/red_knot_python_semantic/src/types/builder.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@ impl<'db> UnionBuilder<'db> {
4343
}
4444
}
4545

46+
pub(crate) fn with_capacity(db: &'db dyn Db, capacity: usize) -> Self {
47+
Self {
48+
db,
49+
elements: Vec::with_capacity(capacity),
50+
}
51+
}
52+
53+
pub(crate) fn extend<I, T>(mut self, types: I) -> Self
54+
where
55+
I: IntoIterator<Item = T>,
56+
T: Into<Type<'db>>,
57+
{
58+
let types = types.into_iter();
59+
self.elements.reserve(types.size_hint().0);
60+
for ty in types {
61+
self = self.add(ty.into());
62+
}
63+
self
64+
}
65+
4666
/// Collapse the union to a single type: `object`.
4767
fn collapse_to_object(mut self) -> Self {
4868
self.elements.clear();

crates/red_knot_python_semantic/src/types/call.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::context::InferContext;
2-
use super::{Signature, Type};
2+
use super::{Signature, Type, UnionBuilder};
33
use crate::types::UnionType;
44
use crate::Db;
55

@@ -128,13 +128,13 @@ impl<'db> CallError<'db> {
128128
// combined with `Type::Unknown`
129129
CallError::Union {
130130
errors, bindings, ..
131-
} => Some(UnionType::from_elements(
132-
db,
133-
bindings
134-
.iter()
135-
.map(CallBinding::return_type)
136-
.chain(errors.iter().map(|err| err.fallback_return_type(db))),
137-
)),
131+
} => Some(
132+
UnionBuilder::new(db)
133+
.extend(bindings.iter().map(CallBinding::return_type))
134+
.extend(errors.iter().map(|err| err.fallback_return_type(db)))
135+
.build(),
136+
),
137+
138138
Self::PossiblyUnboundDunderCall { outcome, .. } => Some(outcome.return_type(db)),
139139
Self::BindingError { binding } => Some(binding.return_type()),
140140
}

crates/red_knot_python_semantic/src/types/infer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4079,7 +4079,9 @@ impl<'db> TypeInferenceBuilder<'db> {
40794079
}
40804080
});
40814081

4082-
UnionType::from_elements(db, elements)
4082+
UnionBuilder::with_capacity(db, n_values)
4083+
.extend(elements)
4084+
.build()
40834085
}
40844086

40854087
fn infer_compare_expression(&mut self, compare: &ast::ExprCompare) -> Type<'db> {

crates/red_knot_python_semantic/src/types/property_tests.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,11 @@ fn intersection<'db>(db: &'db TestDb, tys: impl IntoIterator<Item = Type<'db>>)
323323
builder.build()
324324
}
325325

326-
fn union<'db>(db: &'db TestDb, tys: impl IntoIterator<Item = Type<'db>>) -> Type<'db> {
326+
fn union<'db, I, E>(db: &'db TestDb, tys: I) -> Type<'db>
327+
where
328+
I: IntoIterator<IntoIter = E>,
329+
E: ExactSizeIterator<Item = Type<'db>>,
330+
{
327331
UnionType::from_elements(db, tys)
328332
}
329333

0 commit comments

Comments
 (0)