From dc802d31f2530bc3daa4aab65ac799b92233f25f Mon Sep 17 00:00:00 2001 From: Douglas Creager Date: Wed, 19 Nov 2025 17:56:23 -0500 Subject: [PATCH] build up constraint sets --- .../ty_python_semantic/src/types/generics.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 6f0a709cc7..eee232252a 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -1330,6 +1330,7 @@ pub(crate) struct SpecializationBuilder<'db> { db: &'db dyn Db, inferable: InferableTypeVars<'db, 'db>, types: FxHashMap, Type<'db>>, + constraints: ConstraintSet<'db>, } /// An assignment from a bound type variable to a given type, along with the variance of the outermost @@ -1342,6 +1343,7 @@ impl<'db> SpecializationBuilder<'db> { db, inferable, types: FxHashMap::default(), + constraints: ConstraintSet::from(true), } } @@ -1385,6 +1387,32 @@ impl<'db> SpecializationBuilder<'db> { return; }; + let constraint = match variance { + TypeVarVariance::Covariant => ConstraintSet::constrain_typevar( + self.db, + bound_typevar, + Type::Never, + ty, + TypeRelation::Assignability, + ), + TypeVarVariance::Contravariant => ConstraintSet::constrain_typevar( + self.db, + bound_typevar, + ty, + Type::object(), + TypeRelation::Assignability, + ), + TypeVarVariance::Invariant => ConstraintSet::constrain_typevar( + self.db, + bound_typevar, + ty, + ty, + TypeRelation::Assignability, + ), + TypeVarVariance::Bivariant => ConstraintSet::from(true), + }; + self.constraints.intersect(self.db, constraint); + match self.types.entry(identity) { Entry::Occupied(mut entry) => { *entry.get_mut() = UnionType::from_elements(self.db, [*entry.get(), ty]);