mirror of https://github.com/astral-sh/ruff
[ty] Add subdiagnostic hint if a variable with type `Never` is used in a type expression (#21660)
This commit is contained in:
parent
77f8fa6906
commit
a7d48ffd40
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: unreachable.md - Unreachable code - `Never`-inferred variables in type expressions
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/unreachable.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## module.py
|
||||
|
||||
```
|
||||
1 | import sys
|
||||
2 |
|
||||
3 | if sys.version_info >= (3, 14):
|
||||
4 | raise RuntimeError("this library doesn't support 3.14 yet!!!")
|
||||
5 |
|
||||
6 | class AwesomeAPI: ...
|
||||
```
|
||||
|
||||
## main.py
|
||||
|
||||
```
|
||||
1 | import module
|
||||
2 |
|
||||
3 | def f(x: module.AwesomeAPI): ... # error: [invalid-type-form]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Variable of type `Never` is not allowed in a type expression
|
||||
--> src/main.py:3:10
|
||||
|
|
||||
1 | import module
|
||||
2 |
|
||||
3 | def f(x: module.AwesomeAPI): ... # error: [invalid-type-form]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: The variable may have been inferred as `Never` because its definition was inferred as being unreachable
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
|
@ -581,3 +581,35 @@ if False:
|
|||
|
||||
1 / number
|
||||
```
|
||||
|
||||
## `Never`-inferred variables in type expressions
|
||||
|
||||
We offer a helpful subdiagnostic if a variable in a type expression is inferred as having type
|
||||
`Never`, since this almost certainly resulted in the definition of the type being inferred by ty as
|
||||
being unreachable:
|
||||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.14"
|
||||
```
|
||||
|
||||
`module.py`:
|
||||
|
||||
```py
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (3, 14):
|
||||
raise RuntimeError("this library doesn't support 3.14 yet!!!")
|
||||
|
||||
class AwesomeAPI: ...
|
||||
```
|
||||
|
||||
`main.py`:
|
||||
|
||||
```py
|
||||
import module
|
||||
|
||||
def f(x: module.AwesomeAPI): ... # error: [invalid-type-form]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8879,11 +8879,15 @@ impl<'db> InvalidTypeExpression<'db> {
|
|||
}
|
||||
|
||||
fn add_subdiagnostics(self, db: &'db dyn Db, mut diagnostic: LintDiagnosticGuard) {
|
||||
if let InvalidTypeExpression::InvalidType(ty, scope) = self {
|
||||
let Type::ModuleLiteral(module_type) = ty else {
|
||||
return;
|
||||
};
|
||||
let module = module_type.module(db);
|
||||
if let InvalidTypeExpression::InvalidType(Type::Never, _) = self {
|
||||
diagnostic.help(
|
||||
"The variable may have been inferred as `Never` because \
|
||||
its definition was inferred as being unreachable",
|
||||
);
|
||||
} else if let InvalidTypeExpression::InvalidType(ty @ Type::ModuleLiteral(module), scope) =
|
||||
self
|
||||
{
|
||||
let module = module.module(db);
|
||||
let Some(module_name_final_part) = module.name(db).components().next_back() else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue