Skip to content

Commit 1e0580b

Browse files
committed
ty_python_semantic: improve failed overloaded function call
The diagnostic now includes a pointer to the implementation definition along with each possible overload. This doesn't include information about *why* each overload failed.
1 parent ce3a2f1 commit 1e0580b

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

crates/ty_python_semantic/resources/mdtest/snapshots/no_matching_overload…_-_No_matching_overload…_-_Calls_to_overloaded_…_(3553d085684e16a0).snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ error[no-matching-overload]: No overload of function `f` matches arguments
3737
12 | f(b"foo") # error: [no-matching-overload]
3838
| ^^^^^^^^^
3939
|
40+
info: Unmatched overload defined here
41+
--> src/mdtest_snippet.py:4:5
42+
|
43+
3 | @overload
44+
4 | def f(x: int) -> int: ...
45+
| ^
46+
5 |
47+
6 | @overload
48+
|
49+
info: Unmatched overload defined here
50+
--> src/mdtest_snippet.py:7:5
51+
|
52+
6 | @overload
53+
7 | def f(x: str) -> str: ...
54+
| ^
55+
8 |
56+
9 | def f(x: int | str) -> int | str:
57+
|
58+
info: Overload implementation defined here
59+
--> src/mdtest_snippet.py:9:5
60+
|
61+
7 | def f(x: str) -> str: ...
62+
8 |
63+
9 | def f(x: int | str) -> int | str:
64+
| ^
65+
10 | return x
66+
|
4067
info: rule `no-matching-overload` is enabled by default
4168
4269
```

crates/ty_python_semantic/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6913,7 +6913,7 @@ impl<'db> FunctionType<'db> {
69136913
///
69146914
/// An example of a good use case is to improve
69156915
/// a diagnostic.
6916-
fn return_type_span(&self, db: &'db dyn Db) -> Option<(Span, Span)> {
6916+
fn return_type_span(self, db: &'db dyn Db) -> Option<(Span, Span)> {
69176917
let function_scope = self.body_scope(db);
69186918
let span = Span::from(function_scope.file(db));
69196919
let node = function_scope.node(db);
@@ -6948,7 +6948,7 @@ impl<'db> FunctionType<'db> {
69486948
/// An example of a good use case is to improve
69496949
/// a diagnostic.
69506950
fn parameter_span(
6951-
&self,
6951+
self,
69526952
db: &'db dyn Db,
69536953
parameter_index: Option<usize>,
69546954
) -> Option<(Span, Span)> {

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,35 @@ impl<'db> CallableBinding<'db> {
11131113
String::new()
11141114
}
11151115
));
1116+
if let Some(overloaded_types) = self
1117+
.signature_type
1118+
.into_function_literal()
1119+
.and_then(|funty| funty.to_overloaded(context.db()))
1120+
{
1121+
for overload_type in &overloaded_types.overloads {
1122+
if let Some((name_span, _)) =
1123+
overload_type.parameter_span(context.db(), None)
1124+
{
1125+
let mut sub = SubDiagnostic::new(
1126+
Severity::Info,
1127+
"Unmatched overload defined here",
1128+
);
1129+
sub.annotate(Annotation::primary(name_span));
1130+
diag.sub(sub);
1131+
}
1132+
}
1133+
if let Some((name_span, _)) = overloaded_types
1134+
.implementation
1135+
.and_then(|funty| funty.parameter_span(context.db(), None))
1136+
{
1137+
let mut sub = SubDiagnostic::new(
1138+
Severity::Info,
1139+
"Overload implementation defined here",
1140+
);
1141+
sub.annotate(Annotation::primary(name_span));
1142+
diag.sub(sub);
1143+
}
1144+
}
11161145
if let Some(union_diag) = union_diag {
11171146
union_diag.add_union_context(context.db(), &mut diag);
11181147
}

0 commit comments

Comments
 (0)