diff --git a/pyrefly/lib/alt/solve.rs b/pyrefly/lib/alt/solve.rs index bb519fd536..3b42262eb5 100644 --- a/pyrefly/lib/alt/solve.rs +++ b/pyrefly/lib/alt/solve.rs @@ -4206,6 +4206,33 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> { errors: &ErrorCollector, ) -> Type { let result = self.expr_check(e, None, errors); + match special_export { + Some(SpecialExport::TypeVar) => { + self.error( + errors, + e.range(), + ErrorKind::InvalidTypeVar, + "TypeVar must be assigned to a variable".to_owned(), + ); + } + Some(SpecialExport::ParamSpec) => { + self.error( + errors, + e.range(), + ErrorKind::InvalidParamSpec, + "ParamSpec must be assigned to a variable".to_owned(), + ); + } + Some(SpecialExport::TypeVarTuple) => { + self.error( + errors, + e.range(), + ErrorKind::InvalidTypeVarTuple, + "TypeVarTuple must be assigned to a variable".to_owned(), + ); + } + _ => {} + } if special_export != Some(SpecialExport::AssertType) && let Type::ClassType(cls) = &result && self.is_coroutine(&result) diff --git a/pyrefly/lib/test/generic_legacy.rs b/pyrefly/lib/test/generic_legacy.rs index e27517ed22..d967579d0c 100644 --- a/pyrefly/lib/test/generic_legacy.rs +++ b/pyrefly/lib/test/generic_legacy.rs @@ -292,6 +292,16 @@ Ts = TypeVarTuple(name = "Ts") "#, ); +testcase!( + test_tvar_bare_call, + r#" +from typing import TypeVar, ParamSpec, TypeVarTuple +TypeVar("T") # E: TypeVar must be assigned to a variable +ParamSpec("P") # E: ParamSpec must be assigned to a variable +TypeVarTuple("Ts") # E: TypeVarTuple must be assigned to a variable + "#, +); + testcase!( test_tvar_unexpected_keyword, r#" diff --git a/pyrefly/lib/test/simple.rs b/pyrefly/lib/test/simple.rs index b414042ce4..65e9cf8119 100644 --- a/pyrefly/lib/test/simple.rs +++ b/pyrefly/lib/test/simple.rs @@ -1921,7 +1921,7 @@ testcase!( test_crash_on_decorator_assign, r#" from typing import TypeVar -@T=TypeVar() # E: Expected newline, found `=` # E: Missing argument `name` +@T=TypeVar() # E: Expected newline, found `=` # E: TypeVar must be assigned to a variable # E: Missing argument `name` "#, );