Skip to content

Commit f4d0273

Browse files
authored
[ty] Combine CallArguments and CallArgumentTypes (#19337)
We previously had separate `CallArguments` and `CallArgumentTypes` types in support of our two-phase call binding logic. `CallArguments` would store only the arity/kind of each argument (positional, keyword, variadic, etc). We then performed parameter matching using only this arity/kind information, and then infered the type of each argument, placing the result of this second phase into a new `CallArgumentTypes`. In #18996, we will need to infer the types of splatted arguments _before_ performing parameter matching, since we need to know the argument type to accurately infer its length, which informs how many parameters the splatted argument is matched against. That makes this separation of Rust types no longer useful. This PR merges everything back into a single `CallArguments`. In the case where we are performing two-phase call binding, the types will be initialized to `None`, and updated to the actual argument type during the second `check_types` phase. _[This is a refactoring in support of fixing the merge conflicts on #18996. I've pulled this out into a separate PR to make it easier to review in isolation.]_
1 parent e9cac36 commit f4d0273

File tree

7 files changed

+182
-232
lines changed

7 files changed

+182
-232
lines changed

crates/ty_python_semantic/src/types.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::semantic_index::definition::Definition;
3535
use crate::semantic_index::place::{ScopeId, ScopedPlaceId};
3636
use crate::semantic_index::{imported_modules, place_table, semantic_index};
3737
use crate::suppression::check_suppressions;
38-
use crate::types::call::{Binding, Bindings, CallArgumentTypes, CallableBinding};
38+
use crate::types::call::{Binding, Bindings, CallArguments, CallableBinding};
3939
pub(crate) use crate::types::class_base::ClassBase;
4040
use crate::types::context::{LintDiagnosticGuard, LintDiagnosticGuardBuilder};
4141
use crate::types::diagnostic::{INVALID_TYPE_FORM, UNSUPPORTED_BOOL_CONVERSION};
@@ -2683,7 +2683,7 @@ impl<'db> Type<'db> {
26832683

26842684
if let Place::Type(descr_get, descr_get_boundness) = descr_get {
26852685
let return_ty = descr_get
2686-
.try_call(db, &CallArgumentTypes::positional([self, instance, owner]))
2686+
.try_call(db, &CallArguments::positional([self, instance, owner]))
26872687
.map(|bindings| {
26882688
if descr_get_boundness == Boundness::Bound {
26892689
bindings.return_type(db)
@@ -3134,7 +3134,7 @@ impl<'db> Type<'db> {
31343134
self.try_call_dunder(
31353135
db,
31363136
"__getattr__",
3137-
CallArgumentTypes::positional([Type::string_literal(db, &name)]),
3137+
CallArguments::positional([Type::string_literal(db, &name)]),
31383138
)
31393139
.map(|outcome| Place::bound(outcome.return_type(db)))
31403140
// TODO: Handle call errors here.
@@ -3153,7 +3153,7 @@ impl<'db> Type<'db> {
31533153
self.try_call_dunder_with_policy(
31543154
db,
31553155
"__getattribute__",
3156-
&mut CallArgumentTypes::positional([Type::string_literal(db, &name)]),
3156+
&mut CallArguments::positional([Type::string_literal(db, &name)]),
31573157
MemberLookupPolicy::MRO_NO_OBJECT_FALLBACK,
31583158
)
31593159
.map(|outcome| Place::bound(outcome.return_type(db)))
@@ -3275,7 +3275,7 @@ impl<'db> Type<'db> {
32753275
// runtime there is a fallback to `__len__`, since `__bool__` takes precedence
32763276
// and a subclass could add a `__bool__` method.
32773277

3278-
match self.try_call_dunder(db, "__bool__", CallArgumentTypes::none()) {
3278+
match self.try_call_dunder(db, "__bool__", CallArguments::none()) {
32793279
Ok(outcome) => {
32803280
let return_type = outcome.return_type(db);
32813281
if !return_type.is_assignable_to(db, KnownClass::Bool.to_instance(db)) {
@@ -3474,7 +3474,7 @@ impl<'db> Type<'db> {
34743474
return usize_len.try_into().ok().map(Type::IntLiteral);
34753475
}
34763476

3477-
let return_ty = match self.try_call_dunder(db, "__len__", CallArgumentTypes::none()) {
3477+
let return_ty = match self.try_call_dunder(db, "__len__", CallArguments::none()) {
34783478
Ok(bindings) => bindings.return_type(db),
34793479
Err(CallDunderError::PossiblyUnbound(bindings)) => bindings.return_type(db),
34803480

@@ -4394,7 +4394,7 @@ impl<'db> Type<'db> {
43944394
fn try_call(
43954395
self,
43964396
db: &'db dyn Db,
4397-
argument_types: &CallArgumentTypes<'_, 'db>,
4397+
argument_types: &CallArguments<'_, 'db>,
43984398
) -> Result<Bindings<'db>, CallError<'db>> {
43994399
self.bindings(db)
44004400
.match_parameters(argument_types)
@@ -4409,7 +4409,7 @@ impl<'db> Type<'db> {
44094409
self,
44104410
db: &'db dyn Db,
44114411
name: &str,
4412-
mut argument_types: CallArgumentTypes<'_, 'db>,
4412+
mut argument_types: CallArguments<'_, 'db>,
44134413
) -> Result<Bindings<'db>, CallDunderError<'db>> {
44144414
self.try_call_dunder_with_policy(
44154415
db,
@@ -4430,7 +4430,7 @@ impl<'db> Type<'db> {
44304430
self,
44314431
db: &'db dyn Db,
44324432
name: &str,
4433-
argument_types: &mut CallArgumentTypes<'_, 'db>,
4433+
argument_types: &mut CallArguments<'_, 'db>,
44344434
policy: MemberLookupPolicy,
44354435
) -> Result<Bindings<'db>, CallDunderError<'db>> {
44364436
// Implicit calls to dunder methods never access instance members, so we pass
@@ -4492,19 +4492,19 @@ impl<'db> Type<'db> {
44924492
self.try_call_dunder(
44934493
db,
44944494
"__getitem__",
4495-
CallArgumentTypes::positional([KnownClass::Int.to_instance(db)]),
4495+
CallArguments::positional([KnownClass::Int.to_instance(db)]),
44964496
)
44974497
.map(|dunder_getitem_outcome| dunder_getitem_outcome.return_type(db))
44984498
};
44994499

45004500
let try_call_dunder_next_on_iterator = |iterator: Type<'db>| {
45014501
iterator
4502-
.try_call_dunder(db, "__next__", CallArgumentTypes::none())
4502+
.try_call_dunder(db, "__next__", CallArguments::none())
45034503
.map(|dunder_next_outcome| dunder_next_outcome.return_type(db))
45044504
};
45054505

45064506
let dunder_iter_result = self
4507-
.try_call_dunder(db, "__iter__", CallArgumentTypes::none())
4507+
.try_call_dunder(db, "__iter__", CallArguments::none())
45084508
.map(|dunder_iter_outcome| dunder_iter_outcome.return_type(db));
45094509

45104510
match dunder_iter_result {
@@ -4588,11 +4588,11 @@ impl<'db> Type<'db> {
45884588
/// pass
45894589
/// ```
45904590
fn try_enter(self, db: &'db dyn Db) -> Result<Type<'db>, ContextManagerError<'db>> {
4591-
let enter = self.try_call_dunder(db, "__enter__", CallArgumentTypes::none());
4591+
let enter = self.try_call_dunder(db, "__enter__", CallArguments::none());
45924592
let exit = self.try_call_dunder(
45934593
db,
45944594
"__exit__",
4595-
CallArgumentTypes::positional([Type::none(db), Type::none(db), Type::none(db)]),
4595+
CallArguments::positional([Type::none(db), Type::none(db), Type::none(db)]),
45964596
);
45974597

45984598
// TODO: Make use of Protocols when we support it (the manager be assignable to `contextlib.AbstractContextManager`).
@@ -4627,7 +4627,7 @@ impl<'db> Type<'db> {
46274627
fn try_call_constructor(
46284628
self,
46294629
db: &'db dyn Db,
4630-
argument_types: CallArgumentTypes<'_, 'db>,
4630+
argument_types: CallArguments<'_, 'db>,
46314631
) -> Result<Type<'db>, ConstructorCallError<'db>> {
46324632
debug_assert!(matches!(
46334633
self,
@@ -6428,11 +6428,11 @@ impl<'db> ContextManagerError<'db> {
64286428
Ok(_) | Err(CallDunderError::CallError(..)),
64296429
Ok(_) | Err(CallDunderError::CallError(..)),
64306430
) = (
6431-
context_expression_type.try_call_dunder(db, "__aenter__", CallArgumentTypes::none()),
6431+
context_expression_type.try_call_dunder(db, "__aenter__", CallArguments::none()),
64326432
context_expression_type.try_call_dunder(
64336433
db,
64346434
"__aexit__",
6435-
CallArgumentTypes::positional([Type::unknown(), Type::unknown(), Type::unknown()]),
6435+
CallArguments::positional([Type::unknown(), Type::unknown(), Type::unknown()]),
64366436
),
64376437
) {
64386438
diag.info(format_args!(
@@ -6495,7 +6495,7 @@ impl<'db> IterationError<'db> {
64956495

64966496
Self::IterCallError(_, dunder_iter_bindings) => dunder_iter_bindings
64976497
.return_type(db)
6498-
.try_call_dunder(db, "__next__", CallArgumentTypes::none())
6498+
.try_call_dunder(db, "__next__", CallArguments::none())
64996499
.map(|dunder_next_outcome| Some(dunder_next_outcome.return_type(db)))
65006500
.unwrap_or_else(|dunder_next_call_error| dunder_next_call_error.return_type(db)),
65016501

crates/ty_python_semantic/src/types/call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::Db;
44

55
mod arguments;
66
pub(crate) mod bind;
7-
pub(super) use arguments::{Argument, CallArgumentTypes, CallArguments};
7+
pub(super) use arguments::{Argument, CallArguments};
88
pub(super) use bind::{Binding, Bindings, CallableBinding};
99

1010
/// Wraps a [`Bindings`] for an unsuccessful call with information about why the call was

0 commit comments

Comments
 (0)