diff --git a/crates/ty_python_semantic/resources/corpus/callable_invalid.py b/crates/ty_python_semantic/resources/corpus/callable_invalid.py new file mode 100644 index 0000000000..0c776bfe3f --- /dev/null +++ b/crates/ty_python_semantic/resources/corpus/callable_invalid.py @@ -0,0 +1,5 @@ +from typing import Callable + +def a(x: Callable[.., None]): ... + +def b(x: Callable[.. diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/callable.md b/crates/ty_python_semantic/resources/mdtest/annotations/callable.md index 709e446493..1a7974089e 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/callable.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/callable.md @@ -58,8 +58,6 @@ def _(c: Callable[[int, 42, str, False], None]): ### Missing return type - - Using a parameter list: ```py @@ -90,6 +88,21 @@ def _(c: Callable[ # error: [invalid-type-form] "Special form `typing.Callable` reveal_type(c) # revealed: (...) -> Unknown ``` +### Invalid parameters and return type + +```py +from typing import Callable + +# fmt: off + +def _(c: Callable[ + # error: [invalid-type-form] "Int literals are not allowed in this context in a type expression" + {1, 2}, 2 # error: [invalid-type-form] "The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`" + ] + ): + reveal_type(c) # revealed: (...) -> Unknown +``` + ### More than two arguments We can't reliably infer the callable type if there are more then 2 arguments because we don't know diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index a1f96104ff..ea58ab10eb 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -452,14 +452,9 @@ impl<'db> ScopeInference<'db> { self.extra.as_deref().map(|extra| &extra.diagnostics) } - #[track_caller] pub(crate) fn expression_type(&self, expression: impl Into) -> Type<'db> { - self.try_expression_type(expression).expect( - "Failed to retrieve the inferred type for an `ast::Expr` node \ - passed to `TypeInference::expression_type()`. The `TypeInferenceBuilder` \ - should infer and store types for all `ast::Expr` nodes in any `TypeInference` \ - region it analyzes.", - ) + self.try_expression_type(expression) + .unwrap_or_else(Type::unknown) } pub(crate) fn try_expression_type( @@ -541,14 +536,9 @@ impl<'db> DefinitionInference<'db> { } } - #[track_caller] pub(crate) fn expression_type(&self, expression: impl Into) -> Type<'db> { - self.try_expression_type(expression).expect( - "Failed to retrieve the inferred type for an `ast::Expr` node \ - passed to `TypeInference::expression_type()`. The `TypeInferenceBuilder` \ - should infer and store types for all `ast::Expr` nodes in any `TypeInference` \ - region it analyzes.", - ) + self.try_expression_type(expression) + .unwrap_or_else(Type::unknown) } pub(crate) fn try_expression_type( @@ -675,14 +665,9 @@ impl<'db> ExpressionInference<'db> { .or_else(|| self.fallback_type()) } - #[track_caller] pub(crate) fn expression_type(&self, expression: impl Into) -> Type<'db> { - self.try_expression_type(expression).expect( - "Failed to retrieve the inferred type for an `ast::Expr` node \ - passed to `TypeInference::expression_type()`. The `TypeInferenceBuilder` \ - should infer and store types for all `ast::Expr` nodes in any `TypeInference` \ - region it analyzes.", - ) + self.try_expression_type(expression) + .unwrap_or_else(Type::unknown) } fn is_cycle_callback(&self) -> bool { @@ -959,19 +944,9 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { self.context.in_stub() } - /// Get the already-inferred type of an expression node. - /// - /// ## Panics - /// If the expression is not within this region, or if no type has yet been inferred for - /// this node. - #[track_caller] + /// Get the already-inferred type of an expression node, or Unknown. fn expression_type(&self, expr: &ast::Expr) -> Type<'db> { - self.try_expression_type(expr).expect( - "Failed to retrieve the inferred type for an `ast::Expr` node \ - passed to `TypeInference::expression_type()`. The `TypeInferenceBuilder` \ - should infer and store types for all `ast::Expr` nodes in any `TypeInference` \ - region it analyzes.", - ) + self.try_expression_type(expr).unwrap_or_else(Type::unknown) } fn try_expression_type(&self, expr: &ast::Expr) -> Option> {