diff --git a/crates/ty_project/resources/test/corpus/ty_extensions.py b/crates/ty_project/resources/test/corpus/ty_extensions.py new file mode 100644 index 0000000000..64810a6307 --- /dev/null +++ b/crates/ty_project/resources/test/corpus/ty_extensions.py @@ -0,0 +1,30 @@ +""" +Make sure that types are inferred for all subexpressions of the following +annotations involving ty_extension `_SpecialForm`s. + +This is a regression test for https://github.com/astral-sh/ty/issues/366 +""" + +from ty_extensions import CallableTypeOf, Intersection, Not, TypeOf + + +class A: ... + + +class B: ... + + +def _(x: Not[A]): + pass + + +def _(x: Intersection[A], y: Intersection[A, B]): + pass + + +def _(x: TypeOf[1j]): + pass + + +def _(x: CallableTypeOf[str]): + pass diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index bddbe9f836..b60ac4c9ba 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -8648,11 +8648,16 @@ impl<'db> TypeInferenceBuilder<'db> { element => Either::Right(std::iter::once(element)), }; - elements + let ty = elements .fold(IntersectionBuilder::new(db), |builder, element| { builder.add_positive(self.infer_type_expression(element)) }) - .build() + .build(); + + if matches!(arguments_slice, ast::Expr::Tuple(_)) { + self.store_expression_type(arguments_slice, ty); + } + ty } KnownInstanceType::TypeOf => match arguments_slice { ast::Expr::Tuple(_) => {