Skip to content

Commit

Permalink
handle unions properly
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood committed Aug 21, 2024
1 parent 8e8e0d9 commit 698de48
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
10 changes: 10 additions & 0 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,16 @@ pub enum UnknownTypeKind {
SecondOrder,
}

impl UnknownTypeKind {
pub(crate) fn union(self, other: Self) -> Self {
if self == other {
self
} else {
UnknownTypeKind::SecondOrder
}
}
}

#[salsa::interned]
pub struct FunctionType<'db> {
/// name of the function at definition
Expand Down
14 changes: 12 additions & 2 deletions crates/red_knot_python_semantic/src/types/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
//! * 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::types::{IntersectionType, Type, UnionType, UnknownTypeKind};
use crate::{Db, FxOrderSet};

pub(crate) struct UnionBuilder<'db> {
elements: FxOrderSet<Type<'db>>,
unknown_elements: Option<UnknownTypeKind>,
db: &'db dyn Db,
}

Expand All @@ -38,6 +39,7 @@ impl<'db> UnionBuilder<'db> {
Self {
db,
elements: FxOrderSet::default(),
unknown_elements: None,
}
}

Expand All @@ -48,6 +50,12 @@ impl<'db> UnionBuilder<'db> {
self.elements.extend(&union.elements(self.db));
}
Type::Never => {}
Type::Unknown(kind) => {
self.unknown_elements = Some(
self.unknown_elements
.map_or(kind, |existing| existing.union(kind)),
);
}
_ => {
self.elements.insert(ty);
}
Expand All @@ -56,7 +64,9 @@ impl<'db> UnionBuilder<'db> {
self
}

pub(crate) fn build(self) -> Type<'db> {
pub(crate) fn build(mut self) -> Type<'db> {
self.elements
.extend(self.unknown_elements.map(Type::Unknown));
match self.elements.len() {
0 => Type::Never,
1 => self.elements[0],
Expand Down

0 comments on commit 698de48

Please sign in to comment.