Skip to content

Commit 3b57c64

Browse files
committed
[ty] Move the location of more invalid-overload diagnostics
1 parent 89b88c5 commit 3b57c64

4 files changed

Lines changed: 40 additions & 49 deletions

File tree

crates/ty_python_semantic/resources/mdtest/overloads.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,8 @@ At least two `@overload`-decorated definitions must be present.
329329
from typing import overload
330330

331331
@overload
332-
def func(x: int) -> int: ...
333-
334332
# error: [invalid-overload]
333+
def func(x: int) -> int: ...
335334
def func(x: int | str) -> int | str:
336335
return x
337336
```
@@ -357,16 +356,16 @@ non-`@overload`-decorated definition (for the same function/method).
357356
from typing import overload
358357

359358
@overload
359+
# error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
360360
def func(x: int) -> int: ...
361361
@overload
362-
# error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
363362
def func(x: str) -> str: ...
364363

365364
class Foo:
366365
@overload
366+
# error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation function"
367367
def method(self, x: int) -> int: ...
368368
@overload
369-
# error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation function"
370369
def method(self, x: str) -> str: ...
371370
```
372371

@@ -433,10 +432,10 @@ class Fine(metaclass=CustomAbstractMetaclass):
433432
class Foo:
434433
@overload
435434
@abstractmethod
435+
# error: [invalid-overload]
436436
def f(self, x: int) -> int: ...
437437
@overload
438438
@abstractmethod
439-
# error: [invalid-overload]
440439
def f(self, x: str) -> str: ...
441440
```
442441

@@ -446,17 +445,17 @@ And, the `@abstractmethod` decorator must be present on all the `@overload`-ed m
446445
class PartialFoo1(ABC):
447446
@overload
448447
@abstractmethod
448+
# error: [invalid-overload]
449449
def f(self, x: int) -> int: ...
450450
@overload
451-
# error: [invalid-overload]
452451
def f(self, x: str) -> str: ...
453452

454453
class PartialFoo(ABC):
455454
@overload
455+
# error: [invalid-overload]
456456
def f(self, x: int) -> int: ...
457457
@overload
458458
@abstractmethod
459-
# error: [invalid-overload]
460459
def f(self, x: str) -> str: ...
461460
```
462461

@@ -498,11 +497,10 @@ if TYPE_CHECKING:
498497

499498
if TYPE_CHECKING:
500499
@overload
501-
def c() -> None: ...
500+
# not all overloads are in a `TYPE_CHECKING` block, so this is an error
501+
def c() -> None: ... # error: [invalid-overload]
502502

503-
# not all overloads are in a `TYPE_CHECKING` block, so this is an error
504503
@overload
505-
# error: [invalid-overload]
506504
def c(x: int) -> int: ...
507505
```
508506

crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Invalid_-_At_least_two_overloa…_(84dadf8abd8f2f2).snap

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/overloads.md
1616
1 | from typing import overload
1717
2 |
1818
3 | @overload
19-
4 | def func(x: int) -> int: ...
20-
5 |
21-
6 | # error: [invalid-overload]
22-
7 | def func(x: int | str) -> int | str:
23-
8 | return x
19+
4 | # error: [invalid-overload]
20+
5 | def func(x: int) -> int: ...
21+
6 | def func(x: int | str) -> int | str:
22+
7 | return x
2423
```
2524

2625
## mdtest_snippet.pyi
@@ -37,16 +36,14 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/overloads.md
3736

3837
```
3938
error[invalid-overload]: Overloaded function `func` requires at least two overloads
40-
--> src/mdtest_snippet.py:4:5
39+
--> src/mdtest_snippet.py:5:5
4140
|
4241
3 | @overload
43-
4 | def func(x: int) -> int: ...
44-
| ---- Only one overload defined here
45-
5 |
46-
6 | # error: [invalid-overload]
47-
7 | def func(x: int | str) -> int | str:
48-
| ^^^^
49-
8 | return x
42+
4 | # error: [invalid-overload]
43+
5 | def func(x: int) -> int: ...
44+
| ^^^^ Only one overload defined here
45+
6 | def func(x: int | str) -> int | str:
46+
7 | return x
5047
|
5148
info: rule `invalid-overload` is enabled by default
5249
@@ -59,9 +56,7 @@ error[invalid-overload]: Overloaded function `func` requires at least two overlo
5956
3 | @overload
6057
4 | # error: [invalid-overload]
6158
5 | def func(x: int) -> int: ...
62-
| ----
63-
| |
64-
| Only one overload defined here
59+
| ^^^^ Only one overload defined here
6560
|
6661
info: rule `invalid-overload` is enabled by default
6762

crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Invalid_-_Overload_without_an_…_-_Regular_modules_(5c8e81664d1c7470).snap

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,31 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/overloads.md
1616
1 | from typing import overload
1717
2 |
1818
3 | @overload
19-
4 | def func(x: int) -> int: ...
20-
5 | @overload
21-
6 | # error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
19+
4 | # error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
20+
5 | def func(x: int) -> int: ...
21+
6 | @overload
2222
7 | def func(x: str) -> str: ...
2323
8 |
2424
9 | class Foo:
2525
10 | @overload
26-
11 | def method(self, x: int) -> int: ...
27-
12 | @overload
28-
13 | # error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation function"
26+
11 | # error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation function"
27+
12 | def method(self, x: int) -> int: ...
28+
13 | @overload
2929
14 | def method(self, x: str) -> str: ...
3030
```
3131

3232
# Diagnostics
3333

3434
```
3535
error[invalid-overload]: Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function
36-
--> src/mdtest_snippet.py:7:5
36+
--> src/mdtest_snippet.py:5:5
3737
|
38-
5 | @overload
39-
6 | # error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
40-
7 | def func(x: str) -> str: ...
38+
3 | @overload
39+
4 | # error: [invalid-overload] "Overloads for function `func` must be followed by a non-`@overload`-decorated implementation function"
40+
5 | def func(x: int) -> int: ...
4141
| ^^^^
42-
8 |
43-
9 | class Foo:
42+
6 | @overload
43+
7 | def func(x: str) -> str: ...
4444
|
4545
info: Attempting to call `func` will raise `TypeError` at runtime
4646
info: Overloaded functions without implementations are only permitted:
@@ -55,12 +55,14 @@ info: rule `invalid-overload` is enabled by default
5555

5656
```
5757
error[invalid-overload]: Overloads for function `method` must be followed by a non-`@overload`-decorated implementation function
58-
--> src/mdtest_snippet.py:14:9
58+
--> src/mdtest_snippet.py:12:9
5959
|
60-
12 | @overload
61-
13 | # error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation functi…
62-
14 | def method(self, x: str) -> str: ...
60+
10 | @overload
61+
11 | # error: [invalid-overload] "Overloads for function `method` must be followed by a non-`@overload`-decorated implementation functi…
62+
12 | def method(self, x: int) -> int: ...
6363
| ^^^^^^
64+
13 | @overload
65+
14 | def method(self, x: str) -> str: ...
6466
|
6567
info: Attempting to call `method` will raise `TypeError` at runtime
6668
info: Overloaded functions without implementations are only permitted:

crates/ty_python_semantic/src/types/infer/builder.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
14971497

14981498
// Check that the overloaded function has at least two overloads
14991499
if let [single_overload] = overloads {
1500-
let function_node = function.node(self.db(), self.file(), self.module());
1500+
let function_node = single_overload.node(self.db(), self.file(), self.module());
15011501
if let Some(builder) = self
15021502
.context
15031503
.report_lint(&INVALID_OVERLOAD, &function_node.name)
@@ -1506,11 +1506,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
15061506
"Overloaded function `{}` requires at least two overloads",
15071507
&function_node.name
15081508
));
1509-
diagnostic.annotate(
1510-
self.context
1511-
.secondary(single_overload.focus_range(self.db(), self.module()))
1512-
.message(format_args!("Only one overload defined here")),
1513-
);
1509+
diagnostic.set_primary_message("Only one overload defined here");
15141510
}
15151511
}
15161512

@@ -1552,7 +1548,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
15521548
}
15531549

15541550
if implementation_required {
1555-
let function_node = function.node(self.db(), self.file(), self.module());
1551+
let function_node = overloads[0].node(self.db(), self.file(), self.module());
15561552
if let Some(builder) = self
15571553
.context
15581554
.report_lint(&INVALID_OVERLOAD, &function_node.name)

0 commit comments

Comments
 (0)