diff --git a/crates/ty_python_semantic/src/types/constraints.rs b/crates/ty_python_semantic/src/types/constraints.rs index 9deb1c87be..4c9a55f6ed 100644 --- a/crates/ty_python_semantic/src/types/constraints.rs +++ b/crates/ty_python_semantic/src/types/constraints.rs @@ -360,6 +360,18 @@ impl<'db> ConstraintSet<'db> { self.node.satisfied_by_all_typevars(db, inferable) } + pub(crate) fn limit_to_valid_specializations(self, db: &'db dyn Db) -> Self { + let mut result = self.node; + let mut seen = FxHashSet::default(); + self.node.for_each_constraint(db, &mut |constraint| { + let bound_typevar = constraint.typevar(db); + if seen.insert(bound_typevar) { + result = result.and(db, bound_typevar.valid_specializations(db)); + } + }); + Self { node: result } + } + /// Updates this constraint set to hold the union of itself and another constraint set. pub(crate) fn union(&mut self, db: &'db dyn Db, other: Self) -> Self { self.node = self.node.or(db, other.node); diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 034dcf0520..d0a0682b17 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -1569,6 +1569,7 @@ impl<'db> SpecializationBuilder<'db> { constraints: ConstraintSet<'db>, mut f: impl FnMut(TypeVarAssignment<'db>) -> Option>, ) { + let constraints = constraints.limit_to_valid_specializations(self.db); constraints.for_each_path(self.db, |path| { for constraint in path.positive_constraints() { let typevar = constraint.typevar(self.db);