mirror of https://github.com/astral-sh/ruff
test fixes from codex
This commit is contained in:
parent
290868b71d
commit
2d301b63bb
|
|
@ -1756,6 +1756,24 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
match (self, target) {
|
||||
// Pretend that instances of `dataclasses.Field` are assignable to their default type.
|
||||
// This allows field definitions like `name: str = field(default="")` in dataclasses
|
||||
// to pass the assignability check of the inferred type to the declared type.
|
||||
(Type::KnownInstance(KnownInstanceType::Field(field)), right)
|
||||
if relation.is_assignability() =>
|
||||
{
|
||||
field.default_type(db).when_none_or(|default_type| {
|
||||
default_type.has_relation_to_impl(
|
||||
db,
|
||||
right,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Two identical typevars must always solve to the same type, so they are always
|
||||
// subtypes of each other and assignable to each other.
|
||||
//
|
||||
|
|
@ -1766,6 +1784,30 @@ impl<'db> Type<'db> {
|
|||
{
|
||||
ConstraintSet::from(true)
|
||||
}
|
||||
(Type::TypeVar(lhs_bound_typevar), Type::TypeVar(rhs_bound_typevar))
|
||||
if relation.is_assignability()
|
||||
&& lhs_bound_typevar.typevar(db).identity(db)
|
||||
== rhs_bound_typevar.typevar(db).identity(db) =>
|
||||
{
|
||||
ConstraintSet::from(true)
|
||||
}
|
||||
|
||||
// Typevars with non-fully-static bounds or constraints do not participate in
|
||||
// subtyping while they are in a non-inferable position.
|
||||
(Type::TypeVar(bound_typevar), _)
|
||||
if relation.is_subtyping()
|
||||
&& !bound_typevar.is_inferable(db, inferable)
|
||||
&& !bound_typevar.has_fully_static_bound_or_constraints(db) =>
|
||||
{
|
||||
ConstraintSet::from(false)
|
||||
}
|
||||
(_, Type::TypeVar(bound_typevar))
|
||||
if relation.is_subtyping()
|
||||
&& !bound_typevar.is_inferable(db, inferable)
|
||||
&& !bound_typevar.has_fully_static_bound_or_constraints(db) =>
|
||||
{
|
||||
ConstraintSet::from(false)
|
||||
}
|
||||
|
||||
// A typevar satisfies a relation when...it satisfies the relation. Yes that's a
|
||||
// tautology! We're moving the caller's subtyping/assignability requirement into a
|
||||
|
|
@ -1825,24 +1867,6 @@ impl<'db> Type<'db> {
|
|||
})
|
||||
}
|
||||
|
||||
// Pretend that instances of `dataclasses.Field` are assignable to their default type.
|
||||
// This allows field definitions like `name: str = field(default="")` in dataclasses
|
||||
// to pass the assignability check of the inferred type to the declared type.
|
||||
(Type::KnownInstance(KnownInstanceType::Field(field)), right)
|
||||
if relation.is_assignability() =>
|
||||
{
|
||||
field.default_type(db).when_none_or(|default_type| {
|
||||
default_type.has_relation_to_impl(
|
||||
db,
|
||||
right,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Dynamic is only a subtype of `object` and only a supertype of `Never`; both were
|
||||
// handled above. It's always assignable, though.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -142,6 +142,25 @@ impl<'db> BoundTypeVarInstance<'db> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if all bounds or constraints on this typevar are fully static.
|
||||
///
|
||||
/// A type is fully static if its top and bottom materializations are the same; dynamic types
|
||||
/// (like `Any`) will have different materializations.
|
||||
pub(crate) fn has_fully_static_bound_or_constraints(self, db: &'db dyn Db) -> bool {
|
||||
match self.typevar(db).bound_or_constraints(db) {
|
||||
None => true,
|
||||
Some(TypeVarBoundOrConstraints::UpperBound(bound)) => {
|
||||
bound.top_materialization(db) == bound.bottom_materialization(db)
|
||||
}
|
||||
Some(TypeVarBoundOrConstraints::Constraints(constraints)) => constraints
|
||||
.elements(db)
|
||||
.iter()
|
||||
.all(|constraint| {
|
||||
constraint.top_materialization(db) == constraint.bottom_materialization(db)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'db> InferableTypeVars<'a, 'db> {
|
||||
|
|
@ -1521,6 +1540,20 @@ impl<'db> SpecializationBuilder<'db> {
|
|||
let bound_typevars =
|
||||
(formal.elements(self.db).iter()).filter_map(|ty| ty.as_typevar());
|
||||
if let Ok(bound_typevar) = bound_typevars.exactly_one() {
|
||||
// If the actual argument can be satisfied by a non-typevar element of the
|
||||
// union, then prefer that element and avoid inferring a mapping for the
|
||||
// typevar. This lets other occurrences of the typevar (if any) drive the
|
||||
// specialization instead of opportunistically binding it here.
|
||||
let matches_non_typevar = formal.elements(self.db).iter().any(|ty| {
|
||||
!ty.has_typevar(self.db)
|
||||
&& actual
|
||||
.when_subtype_of(self.db, *ty, self.inferable)
|
||||
.satisfied_by_all_typevars(self.db, self.inferable)
|
||||
});
|
||||
if matches_non_typevar {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.add_type_mapping(bound_typevar, actual, polarity, f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue