[ty] Handle various invalid explicit specializations for ParamSpec (#21821)

## Summary

fixes: https://github.com/astral-sh/ty/issues/1788

## Test Plan

Add new mdtests.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Dhruv Manilawala
2025-12-08 10:50:41 +05:30
committed by GitHub
parent 857fd4f683
commit ac882f7e63
3 changed files with 65 additions and 13 deletions

View File

@@ -3472,17 +3472,13 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
));
}
ast::Expr::Tuple(_) if !exactly_one_paramspec => {
// Tuple expression is only allowed when the generic context contains only one
// `ParamSpec` type variable and no other type variables.
}
ast::Expr::Tuple(ast::ExprTuple { elts, .. })
| ast::Expr::List(ast::ExprList { elts, .. }) => {
// This should be taken care of by the caller.
if expr.is_tuple_expr() {
assert!(
exactly_one_paramspec,
"Inferring ParamSpec value during explicit specialization for a \
tuple expression should only happen when it contains exactly one ParamSpec"
);
}
let mut parameter_types = Vec::with_capacity(elts.len());
// Whether to infer `Todo` for the parameters
@@ -3519,7 +3515,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
return Ok(Type::paramspec_value_callable(db, Parameters::todo()));
}
ast::Expr::Name(_) => {
ast::Expr::Name(name) => {
if name.is_invalid() {
return Err(());
}
let param_type = self.infer_type_expression(expr);
match param_type {
@@ -11632,7 +11632,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
let exactly_one_paramspec = generic_context.exactly_one_paramspec(db);
let (type_arguments, store_inferred_type_arguments) = match slice_node {
ast::Expr::Tuple(tuple) => {
if exactly_one_paramspec {
if exactly_one_paramspec && !tuple.elts.is_empty() {
(std::slice::from_ref(slice_node), false)
} else {
(tuple.elts.as_slice(), true)