diff --git a/crates/ty_python_semantic/src/types/constraints.rs b/crates/ty_python_semantic/src/types/constraints.rs index b29e1364c1..8482934e1c 100644 --- a/crates/ty_python_semantic/src/types/constraints.rs +++ b/crates/ty_python_semantic/src/types/constraints.rs @@ -1093,7 +1093,8 @@ impl<'db> Node<'db> { // typevar depends on, and existentially abstract them away. let inferable_dependencies = interior .sequent_map(db) - .get_typevar_dependencies(typevar.identity(db)); + .get_typevar_dependencies(typevar.identity(db)) + .filter(|dependency| dependency.is_inferable(db, inferable)); let restricted = self.exists(db, inferable_dependencies); // Complicating things, the typevar might have gradual constraints. For those, we diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 3e1f817b62..a9f0fc6c8e 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -128,7 +128,7 @@ pub(crate) enum InferableTypeVars<'a, 'db> { ), } -impl<'db> BoundTypeVarInstance<'db> { +impl<'db> BoundTypeVarIdentity<'db> { pub(crate) fn is_inferable( self, db: &'db dyn Db, @@ -136,12 +136,22 @@ impl<'db> BoundTypeVarInstance<'db> { ) -> bool { match inferable { InferableTypeVars::None => false, - InferableTypeVars::One(typevars) => typevars.contains(&self.identity(db)), + InferableTypeVars::One(typevars) => typevars.contains(&self), InferableTypeVars::Two(left, right) => { self.is_inferable(db, *left) || self.is_inferable(db, *right) } } } +} + +impl<'db> BoundTypeVarInstance<'db> { + pub(crate) fn is_inferable( + self, + db: &'db dyn Db, + inferable: InferableTypeVars<'_, 'db>, + ) -> bool { + self.identity(db).is_inferable(db, inferable) + } /// Returns `true` if all bounds or constraints on this typevar are fully static. /// @@ -153,12 +163,11 @@ impl<'db> BoundTypeVarInstance<'db> { Some(TypeVarBoundOrConstraints::UpperBound(bound)) => { bound.top_materialization(db) == bound.bottom_materialization(db) } - Some(TypeVarBoundOrConstraints::Constraints(constraints)) => constraints - .elements(db) - .iter() - .all(|constraint| { + Some(TypeVarBoundOrConstraints::Constraints(constraints)) => { + constraints.elements(db).iter().all(|constraint| { constraint.top_materialization(db) == constraint.bottom_materialization(db) - }), + }) + } } } }