diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index a2fd967759..62a50e9c2d 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -1291,7 +1291,7 @@ impl<'db> Type<'db> { self.filter_union(db, |elem| { !elem .when_disjoint_from(db, target, inferable) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, inferable) }) } @@ -1606,7 +1606,7 @@ impl<'db> Type<'db> { /// See [`TypeRelation::Subtyping`] for more details. pub(crate) fn is_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool { self.when_subtype_of(db, target, InferableTypeVars::None) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn when_subtype_of( @@ -1642,7 +1642,7 @@ impl<'db> Type<'db> { /// See [`TypeRelation::Assignability`] for more details. pub(crate) fn is_assignable_to(self, db: &'db dyn Db, target: Type<'db>) -> bool { self.when_assignable_to(db, target, InferableTypeVars::None) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn when_assignable_to( @@ -1660,7 +1660,7 @@ impl<'db> Type<'db> { #[salsa::tracked(cycle_initial=is_redundant_with_cycle_initial, heap_size=ruff_memory_usage::heap_size)] pub(crate) fn is_redundant_with(self, db: &'db dyn Db, other: Type<'db>) -> bool { self.has_relation_to(db, other, InferableTypeVars::None, TypeRelation::Redundancy) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn has_relation_to( @@ -2545,7 +2545,7 @@ impl<'db> Type<'db> { /// [equivalent to]: https://typing.python.org/en/latest/spec/glossary.html#term-equivalent pub(crate) fn is_equivalent_to(self, db: &'db dyn Db, other: Type<'db>) -> bool { self.when_equivalent_to(db, other, InferableTypeVars::None) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn when_equivalent_to( @@ -2672,7 +2672,7 @@ impl<'db> Type<'db> { /// `false` answers in some cases. pub(crate) fn is_disjoint_from(self, db: &'db dyn Db, other: Type<'db>) -> bool { self.when_disjoint_from(db, other, InferableTypeVars::None) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn when_disjoint_from( @@ -4864,7 +4864,7 @@ impl<'db> Type<'db> { Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked_set)) => { let constraints = tracked_set.constraints(db); - Truthiness::from(constraints.is_always_satisfied(db)) + Truthiness::from(constraints.satisfied_by_all_typevars(db, InferableTypeVars::None)) } Type::FunctionLiteral(_) diff --git a/crates/ty_python_semantic/src/types/call/bind.rs b/crates/ty_python_semantic/src/types/call/bind.rs index c017ee68d4..711d804ce2 100644 --- a/crates/ty_python_semantic/src/types/call/bind.rs +++ b/crates/ty_python_semantic/src/types/call/bind.rs @@ -1608,7 +1608,7 @@ impl<'db> CallableBinding<'db> { .unwrap_or(Type::unknown()); if argument_type .when_assignable_to(db, parameter_type, overload.inferable_typevars) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, overload.inferable_typevars) { is_argument_assignable_to_any_overload = true; break 'overload; @@ -1841,7 +1841,7 @@ impl<'db> CallableBinding<'db> { current_parameter_type, overload.inferable_typevars, ) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, overload.inferable_typevars) { participating_parameter_indexes.insert(parameter_index); } @@ -1964,7 +1964,7 @@ impl<'db> CallableBinding<'db> { first_overload_return_type, overload.inferable_typevars, ) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, overload.inferable_typevars) }) } else { // No matching overload @@ -2860,15 +2860,12 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> { argument_type = argument_type.apply_specialization(self.db, specialization); expected_ty = expected_ty.apply_specialization(self.db, specialization); } - // This is one of the few places where we want to check if there's _any_ specialization - // where assignability holds; normally we want to check that assignability holds for - // _all_ specializations. // TODO: Soon we will go further, and build the actual specializations from the // constraint set that we get from this assignability check, instead of inferring and // building them in an earlier separate step. - if argument_type + if !argument_type .when_assignable_to(self.db, expected_ty, self.inferable_typevars) - .is_never_satisfied(self.db) + .satisfied_by_all_typevars(self.db, self.inferable_typevars) { let positional = matches!(argument, Argument::Positional | Argument::Synthetic) && !parameter.is_variadic(); @@ -3002,7 +2999,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> { KnownClass::Str.to_instance(self.db), self.inferable_typevars, ) - .is_always_satisfied(self.db) + .satisfied_by_all_typevars(self.db, self.inferable_typevars) { self.errors.push(BindingError::InvalidKeyType { argument_index: adjusted_argument_index, diff --git a/crates/ty_python_semantic/src/types/class.rs b/crates/ty_python_semantic/src/types/class.rs index ee5c1b5cde..bfbc59396a 100644 --- a/crates/ty_python_semantic/src/types/class.rs +++ b/crates/ty_python_semantic/src/types/class.rs @@ -517,7 +517,7 @@ impl<'db> ClassType<'db> { /// Return `true` if `other` is present in this class's MRO. pub(super) fn is_subclass_of(self, db: &'db dyn Db, other: ClassType<'db>) -> bool { self.when_subclass_of(db, other, InferableTypeVars::None) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } pub(super) fn when_subclass_of( diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 732f19ddf8..3d2278ca05 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -1487,7 +1487,7 @@ impl<'db> SpecializationBuilder<'db> { let assignable_elements = (formal.elements(self.db).iter()).filter(|ty| { actual .when_subtype_of(self.db, **ty, self.inferable) - .is_always_satisfied(self.db) + .satisfied_by_all_typevars(self.db, self.inferable) }); if assignable_elements.exactly_one().is_ok() { return Ok(()); @@ -1518,7 +1518,7 @@ impl<'db> SpecializationBuilder<'db> { Some(TypeVarBoundOrConstraints::UpperBound(bound)) => { if !ty .when_assignable_to(self.db, bound, self.inferable) - .is_always_satisfied(self.db) + .satisfied_by_all_typevars(self.db, self.inferable) { return Err(SpecializationError::MismatchedBound { bound_typevar, @@ -1539,7 +1539,7 @@ impl<'db> SpecializationBuilder<'db> { for constraint in constraints.elements(self.db) { if ty .when_assignable_to(self.db, *constraint, self.inferable) - .is_always_satisfied(self.db) + .satisfied_by_all_typevars(self.db, self.inferable) { self.add_type_mapping(bound_typevar, *constraint, filter); return Ok(()); diff --git a/crates/ty_python_semantic/src/types/instance.rs b/crates/ty_python_semantic/src/types/instance.rs index 84f8ab07d0..f05e530c51 100644 --- a/crates/ty_python_semantic/src/types/instance.rs +++ b/crates/ty_python_semantic/src/types/instance.rs @@ -671,7 +671,7 @@ impl<'db> ProtocolInstanceType<'db> { &HasRelationToVisitor::default(), &IsDisjointVisitor::default(), ) - .is_always_satisfied(db) + .satisfied_by_all_typevars(db, InferableTypeVars::None) } fn initial<'db>(