mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:43 +00:00
[red-knot] Infer Todo
, not Unknown
, for PEP-604 unions in annotations (#13908)
This commit is contained in:
parent
085a43a262
commit
5eb87aa56e
3 changed files with 32 additions and 5 deletions
|
@ -22,3 +22,13 @@ x: int = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` i
|
||||||
x: int
|
x: int
|
||||||
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## PEP-604 annotations not yet supported
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f() -> str | None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# TODO: should be `str | None` (but Todo is better than `Unknown`)
|
||||||
|
reveal_type(f()) # revealed: @Todo
|
||||||
|
```
|
||||||
|
|
|
@ -211,7 +211,13 @@ fn declarations_ty<'db>(
|
||||||
let declared_ty = if let Some(second) = all_types.next() {
|
let declared_ty = if let Some(second) = all_types.next() {
|
||||||
let mut builder = UnionBuilder::new(db).add(first);
|
let mut builder = UnionBuilder::new(db).add(first);
|
||||||
for other in [second].into_iter().chain(all_types) {
|
for other in [second].into_iter().chain(all_types) {
|
||||||
if !first.is_equivalent_to(db, other) {
|
// Make sure not to emit spurious errors relating to `Type::Todo`,
|
||||||
|
// since we only infer this type due to a limitation in our current model.
|
||||||
|
//
|
||||||
|
// `Unknown` is different here, since we might infer `Unknown`
|
||||||
|
// for one of these due to a variable being defined in one possible
|
||||||
|
// control-flow branch but not another one.
|
||||||
|
if !first.is_equivalent_to(db, other) && !first.is_todo() && !other.is_todo() {
|
||||||
conflicting.push(other);
|
conflicting.push(other);
|
||||||
}
|
}
|
||||||
builder = builder.add(other);
|
builder = builder.add(other);
|
||||||
|
@ -292,6 +298,10 @@ impl<'db> Type<'db> {
|
||||||
matches!(self, Type::Never)
|
matches!(self, Type::Never)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn is_todo(&self) -> bool {
|
||||||
|
matches!(self, Type::Todo)
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn into_class_literal_type(self) -> Option<ClassType<'db>> {
|
pub const fn into_class_literal_type(self) -> Option<ClassType<'db>> {
|
||||||
match self {
|
match self {
|
||||||
Type::ClassLiteral(class_type) => Some(class_type),
|
Type::ClassLiteral(class_type) => Some(class_type),
|
||||||
|
|
|
@ -3471,6 +3471,17 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
Type::Todo
|
Type::Todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO PEP-604 unions
|
||||||
|
ast::Expr::BinOp(binary) => {
|
||||||
|
self.infer_binary_expression(binary);
|
||||||
|
match binary.op {
|
||||||
|
// PEP-604 unions are okay
|
||||||
|
ast::Operator::BitOr => Type::Todo,
|
||||||
|
// anything else is an invalid annotation:
|
||||||
|
_ => Type::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Forms which are invalid in the context of annotation expressions: we infer their
|
// Forms which are invalid in the context of annotation expressions: we infer their
|
||||||
// nested expressions as normal expressions, but the type of the top-level expression is
|
// nested expressions as normal expressions, but the type of the top-level expression is
|
||||||
// always `Type::Unknown` in these cases.
|
// always `Type::Unknown` in these cases.
|
||||||
|
@ -3482,10 +3493,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
self.infer_named_expression(named);
|
self.infer_named_expression(named);
|
||||||
Type::Unknown
|
Type::Unknown
|
||||||
}
|
}
|
||||||
ast::Expr::BinOp(binary) => {
|
|
||||||
self.infer_binary_expression(binary);
|
|
||||||
Type::Unknown
|
|
||||||
}
|
|
||||||
ast::Expr::UnaryOp(unary) => {
|
ast::Expr::UnaryOp(unary) => {
|
||||||
self.infer_unary_expression(unary);
|
self.infer_unary_expression(unary);
|
||||||
Type::Unknown
|
Type::Unknown
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue