diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/invalid.md b/crates/ty_python_semantic/resources/mdtest/annotations/invalid.md index 5392e38c77..9dca3893b7 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/invalid.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/invalid.md @@ -91,6 +91,40 @@ async def outer(): # avoid unrelated syntax errors on yield, yield from, and aw reveal_type(p) # revealed: Unknown reveal_type(q) # revealed: int | Unknown reveal_type(r) # revealed: @Todo(unknown type subscript) + +class Mat: + def __init__(self, value: int): + self.value = value + + def __matmul__(self, other) -> int: + return 42 + +def invalid_binary_operators( + a: "1" + "2", # error: [invalid-type-form] "Invalid binary operator `+` in type annotation" + b: 3 - 5.0, # error: [invalid-type-form] "Invalid binary operator `-` in type annotation" + c: 4 * -2, # error: [invalid-type-form] "Invalid binary operator `*` in type annotation" + d: Mat(4) @ Mat(2), # error: [invalid-type-form] "Invalid binary operator `@` in type annotation" + e: 10 / 2, # error: [invalid-type-form] "Invalid binary operator `/` in type annotation" + f: 10 % 3, # error: [invalid-type-form] "Invalid binary operator `%` in type annotation" + g: 2**-0.5, # error: [invalid-type-form] "Invalid binary operator `**` in type annotation" + h: 10 // 3, # error: [invalid-type-form] "Invalid binary operator `//` in type annotation" + i: 1 << 2, # error: [invalid-type-form] "Invalid binary operator `<<` in type annotation" + j: 4 >> 42, # error: [invalid-type-form] "Invalid binary operator `>>` in type annotation" + k: 5 ^ 3, # error: [invalid-type-form] "Invalid binary operator `^` in type annotation" + l: 5 & 3, # error: [invalid-type-form] "Invalid binary operator `&` in type annotation" +): + reveal_type(a) # revealed: Unknown + reveal_type(b) # revealed: Unknown + reveal_type(c) # revealed: Unknown + reveal_type(d) # revealed: Unknown + reveal_type(e) # revealed: Unknown + reveal_type(f) # revealed: Unknown + reveal_type(g) # revealed: Unknown + reveal_type(h) # revealed: Unknown + reveal_type(i) # revealed: Unknown + reveal_type(j) # revealed: Unknown + reveal_type(k) # revealed: Unknown + reveal_type(l) # revealed: Unknown ``` ## Invalid Collection based AST nodes diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/string.md b/crates/ty_python_semantic/resources/mdtest/annotations/string.md index f44c000855..5777070441 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/string.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/string.md @@ -154,6 +154,7 @@ shouldn't panic. ```py a: "1 or 2" b: "(x := 1)" +# error: [invalid-type-form] c: "1 + 2" d: "lambda x: x" e: "x if True else y" diff --git a/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md b/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md index 9441cc1334..81231b4ad5 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md +++ b/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md @@ -251,7 +251,7 @@ static_assert(is_disjoint_from(Intersection[int, Any], Not[int])) static_assert(is_disjoint_from(Not[int], Intersection[int, Any])) # TODO https://github.com/astral-sh/ty/issues/216 -static_assert(is_disjoint_from(AlwaysFalsy, LiteralString & ~Literal[""])) # error: [static-assert-error] +static_assert(is_disjoint_from(AlwaysFalsy, Intersection[LiteralString, Not[Literal[""]]])) # error: [static-assert-error] ``` ## Special types diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index 689dbcf068..f7702b66f3 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -8416,8 +8416,17 @@ impl<'db> TypeInferenceBuilder<'db, '_> { UnionType::from_elements(self.db(), [left_ty, right_ty]) } // anything else is an invalid annotation: - _ => { + op => { self.infer_binary_expression(binary); + if let Some(mut diag) = self.report_invalid_type_expression( + expression, + format_args!( + "Invalid binary operator `{}` in type annotation", + op.as_str() + ), + ) { + diag.info("Did you mean to use `|`?"); + } Type::unknown() } }