_use_ satisfies_all_typevars

This commit is contained in:
Douglas Creager 2025-10-28 15:12:47 -04:00
parent 60d16288c5
commit f2ebfe2c28
5 changed files with 18 additions and 21 deletions

View File

@ -1291,7 +1291,7 @@ impl<'db> Type<'db> {
self.filter_union(db, |elem| { self.filter_union(db, |elem| {
!elem !elem
.when_disjoint_from(db, target, inferable) .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. /// See [`TypeRelation::Subtyping`] for more details.
pub(crate) fn is_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool { pub(crate) fn is_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool {
self.when_subtype_of(db, target, InferableTypeVars::None) self.when_subtype_of(db, target, InferableTypeVars::None)
.is_always_satisfied(db) .satisfied_by_all_typevars(db, InferableTypeVars::None)
} }
fn when_subtype_of( fn when_subtype_of(
@ -1642,7 +1642,7 @@ impl<'db> Type<'db> {
/// See [`TypeRelation::Assignability`] for more details. /// See [`TypeRelation::Assignability`] for more details.
pub(crate) fn is_assignable_to(self, db: &'db dyn Db, target: Type<'db>) -> bool { pub(crate) fn is_assignable_to(self, db: &'db dyn Db, target: Type<'db>) -> bool {
self.when_assignable_to(db, target, InferableTypeVars::None) self.when_assignable_to(db, target, InferableTypeVars::None)
.is_always_satisfied(db) .satisfied_by_all_typevars(db, InferableTypeVars::None)
} }
fn when_assignable_to( 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)] #[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 { 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) 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( 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 /// [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 { pub(crate) fn is_equivalent_to(self, db: &'db dyn Db, other: Type<'db>) -> bool {
self.when_equivalent_to(db, other, InferableTypeVars::None) self.when_equivalent_to(db, other, InferableTypeVars::None)
.is_always_satisfied(db) .satisfied_by_all_typevars(db, InferableTypeVars::None)
} }
fn when_equivalent_to( fn when_equivalent_to(
@ -2672,7 +2672,7 @@ impl<'db> Type<'db> {
/// `false` answers in some cases. /// `false` answers in some cases.
pub(crate) fn is_disjoint_from(self, db: &'db dyn Db, other: Type<'db>) -> bool { pub(crate) fn is_disjoint_from(self, db: &'db dyn Db, other: Type<'db>) -> bool {
self.when_disjoint_from(db, other, InferableTypeVars::None) self.when_disjoint_from(db, other, InferableTypeVars::None)
.is_always_satisfied(db) .satisfied_by_all_typevars(db, InferableTypeVars::None)
} }
fn when_disjoint_from( fn when_disjoint_from(
@ -4864,7 +4864,7 @@ impl<'db> Type<'db> {
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked_set)) => { Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked_set)) => {
let constraints = tracked_set.constraints(db); 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(_) Type::FunctionLiteral(_)

View File

@ -1608,7 +1608,7 @@ impl<'db> CallableBinding<'db> {
.unwrap_or(Type::unknown()); .unwrap_or(Type::unknown());
if argument_type if argument_type
.when_assignable_to(db, parameter_type, overload.inferable_typevars) .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; is_argument_assignable_to_any_overload = true;
break 'overload; break 'overload;
@ -1841,7 +1841,7 @@ impl<'db> CallableBinding<'db> {
current_parameter_type, current_parameter_type,
overload.inferable_typevars, overload.inferable_typevars,
) )
.is_always_satisfied(db) .satisfied_by_all_typevars(db, overload.inferable_typevars)
{ {
participating_parameter_indexes.insert(parameter_index); participating_parameter_indexes.insert(parameter_index);
} }
@ -1964,7 +1964,7 @@ impl<'db> CallableBinding<'db> {
first_overload_return_type, first_overload_return_type,
overload.inferable_typevars, overload.inferable_typevars,
) )
.is_always_satisfied(db) .satisfied_by_all_typevars(db, overload.inferable_typevars)
}) })
} else { } else {
// No matching overload // No matching overload
@ -2860,15 +2860,12 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
argument_type = argument_type.apply_specialization(self.db, specialization); argument_type = argument_type.apply_specialization(self.db, specialization);
expected_ty = expected_ty.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 // 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 // constraint set that we get from this assignability check, instead of inferring and
// building them in an earlier separate step. // building them in an earlier separate step.
if argument_type if !argument_type
.when_assignable_to(self.db, expected_ty, self.inferable_typevars) .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) let positional = matches!(argument, Argument::Positional | Argument::Synthetic)
&& !parameter.is_variadic(); && !parameter.is_variadic();
@ -3002,7 +2999,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
KnownClass::Str.to_instance(self.db), KnownClass::Str.to_instance(self.db),
self.inferable_typevars, self.inferable_typevars,
) )
.is_always_satisfied(self.db) .satisfied_by_all_typevars(self.db, self.inferable_typevars)
{ {
self.errors.push(BindingError::InvalidKeyType { self.errors.push(BindingError::InvalidKeyType {
argument_index: adjusted_argument_index, argument_index: adjusted_argument_index,

View File

@ -517,7 +517,7 @@ impl<'db> ClassType<'db> {
/// Return `true` if `other` is present in this class's MRO. /// 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 { pub(super) fn is_subclass_of(self, db: &'db dyn Db, other: ClassType<'db>) -> bool {
self.when_subclass_of(db, other, InferableTypeVars::None) 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( pub(super) fn when_subclass_of(

View File

@ -1487,7 +1487,7 @@ impl<'db> SpecializationBuilder<'db> {
let assignable_elements = (formal.elements(self.db).iter()).filter(|ty| { let assignable_elements = (formal.elements(self.db).iter()).filter(|ty| {
actual actual
.when_subtype_of(self.db, **ty, self.inferable) .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() { if assignable_elements.exactly_one().is_ok() {
return Ok(()); return Ok(());
@ -1518,7 +1518,7 @@ impl<'db> SpecializationBuilder<'db> {
Some(TypeVarBoundOrConstraints::UpperBound(bound)) => { Some(TypeVarBoundOrConstraints::UpperBound(bound)) => {
if !ty if !ty
.when_assignable_to(self.db, bound, self.inferable) .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 { return Err(SpecializationError::MismatchedBound {
bound_typevar, bound_typevar,
@ -1539,7 +1539,7 @@ impl<'db> SpecializationBuilder<'db> {
for constraint in constraints.elements(self.db) { for constraint in constraints.elements(self.db) {
if ty if ty
.when_assignable_to(self.db, *constraint, self.inferable) .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); self.add_type_mapping(bound_typevar, *constraint, filter);
return Ok(()); return Ok(());

View File

@ -671,7 +671,7 @@ impl<'db> ProtocolInstanceType<'db> {
&HasRelationToVisitor::default(), &HasRelationToVisitor::default(),
&IsDisjointVisitor::default(), &IsDisjointVisitor::default(),
) )
.is_always_satisfied(db) .satisfied_by_all_typevars(db, InferableTypeVars::None)
} }
fn initial<'db>( fn initial<'db>(