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
|
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) {
|
fn add_subdiagnostics(self, db: &'db dyn Db, mut diagnostic: LintDiagnosticGuard) {
|
||||||
if let InvalidTypeExpression::InvalidType(ty, scope) = self {
|
if let InvalidTypeExpression::InvalidType(Type::Never, _) = self {
|
||||||
let Type::ModuleLiteral(module_type) = ty else {
|
diagnostic.help(
|
||||||
return;
|
"The variable may have been inferred as `Never` because \
|
||||||
};
|
its definition was inferred as being unreachable",
|
||||||
let module = module_type.module(db);
|
);
|
||||||
|
} 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 {
|
let Some(module_name_final_part) = module.name(db).components().next_back() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue