[red-knot] Unpacker: Make invariant explicit and directly return a Type (#16018)

## Summary

- Do not return `Option<Type<…>>` from `Unpacker::get`, but just `Type`.
Panic otherwise.
- Rename `Unpacker::get` to `Unpacker::expression_type`
This commit is contained in:
David Peter 2025-02-07 13:00:04 +01:00 committed by GitHub
parent 618bfaf884
commit 1f7a29d347
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 12 additions and 7 deletions

View File

@ -4254,9 +4254,8 @@ impl<'db> Class<'db> {
// (.., self.name, ..) = <value>
// [.., self.name, ..] = <value>
let inferred_ty = infer_unpack_types(db, *unpack)
.get(*attribute_expression_id)
.expect("Failed to look up type of attribute in unpack assignment");
let inferred_ty =
infer_unpack_types(db, *unpack).expression_type(*attribute_expression_id);
union_of_inferred_types = union_of_inferred_types.add(inferred_ty);
}
}

View File

@ -2085,7 +2085,7 @@ impl<'db> TypeInferenceBuilder<'db> {
}
let name_ast_id = name.scoped_expression_id(self.db(), self.scope());
unpacked.get(name_ast_id).unwrap_or(Type::unknown())
unpacked.expression_type(name_ast_id)
}
TargetKind::Name => {
if self.in_stub() && value.is_ellipsis_literal_expr() {
@ -2356,7 +2356,7 @@ impl<'db> TypeInferenceBuilder<'db> {
self.context.extend(unpacked);
}
let name_ast_id = name.scoped_expression_id(self.db(), self.scope());
unpacked.get(name_ast_id).unwrap_or(Type::unknown())
unpacked.expression_type(name_ast_id)
}
TargetKind::Name => iterable_ty
.iterate(self.db())

View File

@ -268,8 +268,14 @@ pub(crate) struct UnpackResult<'db> {
}
impl<'db> UnpackResult<'db> {
pub(crate) fn get(&self, expr_id: ScopedExpressionId) -> Option<Type<'db>> {
self.targets.get(&expr_id).copied()
/// Returns the inferred type for a given sub-expression of the left-hand side target
/// of an unpacking assignment.
///
/// Panics if a scoped expression ID is passed in that does not correspond to a sub-
/// expression of the target.
#[track_caller]
pub(crate) fn expression_type(&self, expr_id: ScopedExpressionId) -> Type<'db> {
self.targets[&expr_id]
}
}