Skip to content

Commit a7b8cc0

Browse files
authored
[red-knot] Fix .to_instance() for union types (#13319)
1 parent b93d0ab commit a7b8cc0

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

crates/red_knot_python_semantic/src/types.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,12 +445,28 @@ impl<'db> Type<'db> {
445445
}
446446

447447
#[must_use]
448-
pub fn to_instance(&self) -> Type<'db> {
448+
pub fn to_instance(&self, db: &'db dyn Db) -> Type<'db> {
449449
match self {
450450
Type::Any => Type::Any,
451451
Type::Unknown => Type::Unknown,
452+
Type::Unbound => Type::Unknown,
453+
Type::Never => Type::Never,
452454
Type::Class(class) => Type::Instance(*class),
453-
_ => Type::Unknown, // TODO type errors
455+
Type::Union(union) => union.map(db, |element| element.to_instance(db)),
456+
// TODO: we can probably do better here: --Alex
457+
Type::Intersection(_) => Type::Unknown,
458+
// TODO: calling `.to_instance()` on any of these should result in a diagnostic,
459+
// since they already indicate that the object is an instance of some kind:
460+
Type::BooleanLiteral(_)
461+
| Type::BytesLiteral(_)
462+
| Type::Function(_)
463+
| Type::Instance(_)
464+
| Type::Module(_)
465+
| Type::IntLiteral(_)
466+
| Type::StringLiteral(_)
467+
| Type::Tuple(_)
468+
| Type::LiteralString
469+
| Type::None => Type::Unknown,
454470
}
455471
}
456472

crates/red_knot_python_semantic/src/types/infer.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,9 +1457,11 @@ impl<'db> TypeInferenceBuilder<'db> {
14571457
ast::Number::Int(n) => n
14581458
.as_i64()
14591459
.map(Type::IntLiteral)
1460-
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance()),
1461-
ast::Number::Float(_) => builtins_symbol_ty(self.db, "float").to_instance(),
1462-
ast::Number::Complex { .. } => builtins_symbol_ty(self.db, "complex").to_instance(),
1460+
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance(self.db)),
1461+
ast::Number::Float(_) => builtins_symbol_ty(self.db, "float").to_instance(self.db),
1462+
ast::Number::Complex { .. } => {
1463+
builtins_symbol_ty(self.db, "complex").to_instance(self.db)
1464+
}
14631465
}
14641466
}
14651467

@@ -1573,7 +1575,7 @@ impl<'db> TypeInferenceBuilder<'db> {
15731575
}
15741576

15751577
// TODO generic
1576-
builtins_symbol_ty(self.db, "list").to_instance()
1578+
builtins_symbol_ty(self.db, "list").to_instance(self.db)
15771579
}
15781580

15791581
fn infer_set_expression(&mut self, set: &ast::ExprSet) -> Type<'db> {
@@ -1584,7 +1586,7 @@ impl<'db> TypeInferenceBuilder<'db> {
15841586
}
15851587

15861588
// TODO generic
1587-
builtins_symbol_ty(self.db, "set").to_instance()
1589+
builtins_symbol_ty(self.db, "set").to_instance(self.db)
15881590
}
15891591

15901592
fn infer_dict_expression(&mut self, dict: &ast::ExprDict) -> Type<'db> {
@@ -1596,7 +1598,7 @@ impl<'db> TypeInferenceBuilder<'db> {
15961598
}
15971599

15981600
// TODO generic
1599-
builtins_symbol_ty(self.db, "dict").to_instance()
1601+
builtins_symbol_ty(self.db, "dict").to_instance(self.db)
16001602
}
16011603

16021604
/// Infer the type of the `iter` expression of the first comprehension.
@@ -2067,22 +2069,22 @@ impl<'db> TypeInferenceBuilder<'db> {
20672069
(Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::Add) => n
20682070
.checked_add(m)
20692071
.map(Type::IntLiteral)
2070-
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance()),
2072+
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance(self.db)),
20712073

20722074
(Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::Sub) => n
20732075
.checked_sub(m)
20742076
.map(Type::IntLiteral)
2075-
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance()),
2077+
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance(self.db)),
20762078

20772079
(Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::Mult) => n
20782080
.checked_mul(m)
20792081
.map(Type::IntLiteral)
2080-
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance()),
2082+
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance(self.db)),
20812083

20822084
(Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::Div) => n
20832085
.checked_div(m)
20842086
.map(Type::IntLiteral)
2085-
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance()),
2087+
.unwrap_or_else(|| builtins_symbol_ty(self.db, "int").to_instance(self.db)),
20862088

20872089
(Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::Mod) => n
20882090
.checked_rem(m)
@@ -2311,7 +2313,7 @@ impl<'db> TypeInferenceBuilder<'db> {
23112313
name.ctx
23122314
);
23132315

2314-
self.infer_name_expression(name).to_instance()
2316+
self.infer_name_expression(name).to_instance(self.db)
23152317
}
23162318

23172319
ast::Expr::NoneLiteral(_literal) => Type::None,

0 commit comments

Comments
 (0)