Skip to content

Commit

Permalink
fixup! [red-knot] feat: introduce a new [Type::Todo] variant
Browse files Browse the repository at this point in the history
  • Loading branch information
Slyces committed Sep 30, 2024
1 parent 8febe10 commit 28cbcce
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 14 deletions.
19 changes: 10 additions & 9 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,13 @@ pub enum Type<'db> {
/// The None object -- TODO remove this in favor of Instance(types.NoneType)
None,
/// Temporary type for symbols that can't be inferred yet because of missing implementations.
/// Behaves equivalently to `Any`.
///
/// This variant should eventually be removed once red-knot is spec-compliant.
///
/// General rule: `Todo` should only propagate when the presence of the input `Todo` caused the
/// output to be unknown. An output should only be `Todo` if fixing the input to be correctly
/// inferred would cause the output to be known - this is not the case with `[Type::Any]` or
/// `[Type::Unknown]`.
/// output to be unknown. An output should only be `Todo` if fixing all `Todo` inputs to be not
/// `Todo` would change the output type.
Todo,
/// A specific function object
Function(FunctionType<'db>),
Expand Down Expand Up @@ -540,7 +541,9 @@ impl<'db> Type<'db> {
/// when `bool(x)` is called on an object `x`.
fn bool(&self, db: &'db dyn Db) -> Truthiness {
match self {
Type::Any | Type::Never | Type::Unknown | Type::Unbound => Truthiness::Ambiguous,
Type::Any | Type::Todo | Type::Never | Type::Unknown | Type::Unbound => {
Truthiness::Ambiguous
}
Type::None => Truthiness::AlwaysFalse,
Type::Function(_) | Type::RevealTypeFunction(_) => Truthiness::AlwaysTrue,
Type::Module(_) => Truthiness::AlwaysTrue,
Expand Down Expand Up @@ -579,7 +582,6 @@ impl<'db> Type<'db> {
Type::LiteralString => Truthiness::Ambiguous,
Type::BytesLiteral(bytes) => Truthiness::from(!bytes.value(db).is_empty()),
Type::Tuple(items) => Truthiness::from(!items.elements(db).is_empty()),
Type::Todo => Truthiness::Ambiguous,
}
}

Expand Down Expand Up @@ -618,6 +620,8 @@ impl<'db> Type<'db> {
// `Any` is callable, and its return type is also `Any`.
Type::Any => CallOutcome::callable(Type::Any),

Type::Todo => CallOutcome::callable(Type::Todo),

Type::Unknown => CallOutcome::callable(Type::Unknown),

Type::Union(union) => CallOutcome::union(
Expand All @@ -632,9 +636,6 @@ impl<'db> Type<'db> {
// TODO: intersection types
Type::Intersection(_) => CallOutcome::callable(Type::Todo),

// `Todo` is callable, and its return type is also `Todo`.
Type::Todo => CallOutcome::callable(Type::Todo),

_ => CallOutcome::not_callable(self),
}
}
Expand Down Expand Up @@ -706,6 +707,7 @@ impl<'db> Type<'db> {
pub fn to_instance(&self, db: &'db dyn Db) -> Type<'db> {
match self {
Type::Any => Type::Any,
Type::Todo => Type::Todo,
Type::Unknown => Type::Unknown,
Type::Unbound => Type::Unknown,
Type::Never => Type::Never,
Expand All @@ -726,7 +728,6 @@ impl<'db> Type<'db> {
| Type::Tuple(_)
| Type::LiteralString
| Type::None => Type::Unknown,
Type::Todo => Type::Todo,
}
}

Expand Down
7 changes: 2 additions & 5 deletions crates/red_knot_python_semantic/src/types/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl<'db> InnerIntersectionBuilder<'db> {

/// Adds a positive type to this intersection.
fn add_positive(&mut self, db: &'db dyn Db, ty: Type<'db>) {
// TODO `Any`/`Unknown`/`Todo` actually should not self-cancel
match ty {
Type::Intersection(inter) => {
let pos = inter.positive(db);
Expand All @@ -224,8 +225,6 @@ impl<'db> InnerIntersectionBuilder<'db> {
self.positive.retain(|elem| !neg.contains(elem));
self.negative.retain(|elem| !pos.contains(elem));
}
// Note: `[Type::Todo]` is included to show that an unimplemented type was added, but
// this can lead to cases where separate `Type::Todo` cancel eachother
_ => {
if !self.negative.remove(&ty) {
self.positive.insert(ty);
Expand All @@ -236,7 +235,7 @@ impl<'db> InnerIntersectionBuilder<'db> {

/// Adds a negative type to this intersection.
fn add_negative(&mut self, db: &'db dyn Db, ty: Type<'db>) {
// TODO Any/Unknown actually should not self-cancel
// TODO `Any`/`Unknown`/`Todo` actually should not self-cancel
match ty {
Type::Intersection(intersection) => {
let pos = intersection.negative(db);
Expand All @@ -248,8 +247,6 @@ impl<'db> InnerIntersectionBuilder<'db> {
}
Type::Never => {}
Type::Unbound => {}
// Note: `[Type::Todo]` is included to show that an unimplemented type was added, but
// this can lead to cases where separate `Type::Todo` cancel eachother
_ => {
if !self.positive.remove(&ty) {
self.negative.insert(ty);
Expand Down

0 comments on commit 28cbcce

Please sign in to comment.