Skip to content

Commit 3ba99d1

Browse files
committed
add generator type inference as TODO
1 parent 0bc1805 commit 3ba99d1

File tree

5 files changed

+53
-21
lines changed

5 files changed

+53
-21
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ty_python_semantic/resources/mdtest/function/return_type.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ def h(x: int, y: str):
209209
return y
210210

211211
reveal_type(h(1, "a")) # revealed: int | str | None
212+
213+
def generator():
214+
yield 1
215+
yield 2
216+
return None
217+
218+
# TODO: Should be `Generator[Literal[1, 2], Any, None]`
219+
reveal_type(generator()) # revealed: None
212220
```
213221

214222
## Invalid return type

crates/ty_python_semantic/src/types.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4200,8 +4200,8 @@ impl<'db> Type<'db> {
42004200
) -> Result<Bindings<'db>, CallError<'db>> {
42014201
let signatures = self.signatures(db);
42024202
let inferred_return_ty = || self.inferred_return_type(db).unwrap_or(Type::unknown());
4203-
Bindings::match_parameters(signatures, inferred_return_ty, &mut argument_types)
4204-
.check_types(db, &mut argument_types)
4203+
Bindings::match_parameters(signatures, inferred_return_ty, argument_types)
4204+
.check_types(db, argument_types)
42054205
}
42064206

42074207
/// Look up a dunder method on the meta-type of `self` and call it.
@@ -4245,8 +4245,8 @@ impl<'db> Type<'db> {
42454245
.unwrap_or(Type::unknown())
42464246
};
42474247
let bindings =
4248-
Bindings::match_parameters(signatures, inferred_return_ty, &mut argument_types)
4249-
.check_types(db, &mut argument_types)?;
4248+
Bindings::match_parameters(signatures, inferred_return_ty, argument_types)
4249+
.check_types(db, argument_types)?;
42504250
if boundness == Boundness::PossiblyUnbound {
42514251
return Err(CallDunderError::PossiblyUnbound(Box::new(bindings)));
42524252
}
@@ -4489,6 +4489,7 @@ impl<'db> Type<'db> {
44894489
}
44904490
}
44914491
Symbol::Unbound => None,
4492+
}
44924493
});
44934494

44944495
// Construct an instance type that we can use to look up the `__init__` instance method.

crates/ty_python_semantic/src/types/call/bind.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl<'db> Bindings<'db> {
5656
/// verify that each argument type is assignable to the corresponding parameter type.
5757
pub(crate) fn match_parameters(
5858
signatures: Signatures<'db>,
59+
inferred_return_ty: impl Fn() -> Type<'db> + Copy,
5960
arguments: &CallArguments<'_>,
6061
) -> Self {
6162
let mut argument_forms = vec![None; arguments.len()];
@@ -68,6 +69,7 @@ impl<'db> Bindings<'db> {
6869
arguments,
6970
&mut argument_forms,
7071
&mut conflicting_forms,
72+
inferred_return_ty,
7173
)
7274
})
7375
.collect();
@@ -892,6 +894,7 @@ impl<'db> CallableBinding<'db> {
892894
arguments: &CallArguments<'_>,
893895
argument_forms: &mut [Option<ParameterForm>],
894896
conflicting_forms: &mut [bool],
897+
inferred_return_ty: impl Fn() -> Type<'db> + Copy,
895898
) -> Self {
896899
// If this callable is a bound method, prepend the self instance onto the arguments list
897900
// before checking.
@@ -911,6 +914,7 @@ impl<'db> CallableBinding<'db> {
911914
arguments.as_ref(),
912915
argument_forms,
913916
conflicting_forms,
917+
inferred_return_ty,
914918
)
915919
})
916920
.collect();
@@ -1079,6 +1083,7 @@ impl<'db> Binding<'db> {
10791083
arguments: &CallArguments<'_>,
10801084
argument_forms: &mut [Option<ParameterForm>],
10811085
conflicting_forms: &mut [bool],
1086+
inferred_return_ty: impl Fn() -> Type<'db>,
10821087
) -> Self {
10831088
let parameters = signature.parameters();
10841089
// The parameter that each argument is matched with.
@@ -1195,7 +1200,7 @@ impl<'db> Binding<'db> {
11951200
}
11961201

11971202
Self {
1198-
return_ty: signature.return_ty.unwrap_or(Type::unknown()),
1203+
return_ty: signature.return_ty.unwrap_or_else(inferred_return_ty),
11991204
specialization: None,
12001205
inherited_specialization: None,
12011206
argument_parameters: argument_parameters.into_boxed_slice(),

crates/ty_python_semantic/src/types/infer.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4701,9 +4701,8 @@ impl<'db> TypeInferenceBuilder<'db> {
47014701
.inferred_return_type(self.db())
47024702
.unwrap_or(Type::unknown())
47034703
};
4704-
let bindings =
4705-
Bindings::match_parameters(signatures, inferred_return_ty, &mut call_arguments);
4706-
let mut call_argument_types =
4704+
let bindings = Bindings::match_parameters(signatures, inferred_return_ty, &call_arguments);
4705+
let call_argument_types =
47074706
self.infer_argument_types(arguments, call_arguments, &bindings.argument_forms);
47084707

47094708
match bindings.check_types(self.db(), &call_argument_types) {
@@ -6722,19 +6721,16 @@ impl<'db> TypeInferenceBuilder<'db> {
67226721
.inferred_return_type(self.db())
67236722
.unwrap_or(Type::unknown())
67246723
};
6725-
let bindings = match Bindings::match_parameters(
6726-
signatures,
6727-
inferred_return_ty,
6728-
&mut call_argument_types,
6729-
)
6730-
.check_types(self.db(), &mut call_argument_types)
6731-
{
6732-
Ok(bindings) => bindings,
6733-
Err(CallError(_, bindings)) => {
6734-
bindings.report_diagnostics(&self.context, subscript.into());
6735-
return Type::unknown();
6736-
}
6737-
};
6724+
let bindings =
6725+
match Bindings::match_parameters(signatures, inferred_return_ty, &call_argument_types)
6726+
.check_types(self.db(), &call_argument_types)
6727+
{
6728+
Ok(bindings) => bindings,
6729+
Err(CallError(_, bindings)) => {
6730+
bindings.report_diagnostics(&self.context, subscript.into());
6731+
return Type::unknown();
6732+
}
6733+
};
67386734
let callable = bindings
67396735
.into_iter()
67406736
.next()

0 commit comments

Comments
 (0)