mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[ty] add doc-comments for some variance stuff (#20189)
This commit is contained in:
parent
fdfb51b595
commit
eb6154f792
2 changed files with 31 additions and 1 deletions
|
@ -6551,6 +6551,7 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
|
||||||
}
|
}
|
||||||
Type::GenericAlias(generic_alias) => generic_alias.variance_of(db, typevar),
|
Type::GenericAlias(generic_alias) => generic_alias.variance_of(db, typevar),
|
||||||
Type::Callable(callable_type) => callable_type.signatures(db).variance_of(db, typevar),
|
Type::Callable(callable_type) => callable_type.signatures(db).variance_of(db, typevar),
|
||||||
|
// A type variable is always covariant in itself.
|
||||||
Type::TypeVar(other_typevar) | Type::NonInferableTypeVar(other_typevar)
|
Type::TypeVar(other_typevar) | Type::NonInferableTypeVar(other_typevar)
|
||||||
if other_typevar == typevar =>
|
if other_typevar == typevar =>
|
||||||
{
|
{
|
||||||
|
@ -6560,11 +6561,19 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
|
||||||
Type::ProtocolInstance(protocol_instance_type) => {
|
Type::ProtocolInstance(protocol_instance_type) => {
|
||||||
protocol_instance_type.variance_of(db, typevar)
|
protocol_instance_type.variance_of(db, typevar)
|
||||||
}
|
}
|
||||||
|
// unions are covariant in their disjuncts
|
||||||
Type::Union(union_type) => union_type
|
Type::Union(union_type) => union_type
|
||||||
.elements(db)
|
.elements(db)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| ty.variance_of(db, typevar))
|
.map(|ty| ty.variance_of(db, typevar))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
||||||
|
// Products are covariant in their conjuncts. For negative
|
||||||
|
// conjuncts, they're contravariant. To see this, suppose we have
|
||||||
|
// `B` a subtype of `A`. A value of type `~B` could be some non-`B`
|
||||||
|
// `A`, and so is not assignable to `~A`. On the other hand, a value
|
||||||
|
// of type `~A` excludes all `A`s, and thus all `B`s, and so _is_
|
||||||
|
// assignable to `~B`.
|
||||||
Type::Intersection(intersection_type) => intersection_type
|
Type::Intersection(intersection_type) => intersection_type
|
||||||
.positive(db)
|
.positive(db)
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -108,9 +108,30 @@ impl std::iter::FromIterator<Self> for TypeVarVariance {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait VarianceInferable<'db>: Sized {
|
pub(crate) trait VarianceInferable<'db>: Sized {
|
||||||
|
/// The variance of `typevar` in `self`
|
||||||
|
///
|
||||||
|
/// Generally, one will implement this by traversing any types within `self`
|
||||||
|
/// in which `typevar` could occur, and calling `variance_of` recursively on
|
||||||
|
/// them.
|
||||||
|
///
|
||||||
|
/// Sometimes the recursive calls will be in positions where you need to
|
||||||
|
/// specify a non-covariant polarity. See `with_polarity` for more details.
|
||||||
fn variance_of(self, db: &'db dyn Db, typevar: BoundTypeVarInstance<'db>) -> TypeVarVariance;
|
fn variance_of(self, db: &'db dyn Db, typevar: BoundTypeVarInstance<'db>) -> TypeVarVariance;
|
||||||
|
|
||||||
fn with_polarity(self, polarity: TypeVarVariance) -> WithPolarity<Self> {
|
/// Creates a `VarianceInferable` that applies `polarity` (see
|
||||||
|
/// `TypeVarVariance::compose`) to the result of variance inference on the
|
||||||
|
/// underlying value.
|
||||||
|
///
|
||||||
|
/// In some cases, we need to apply a polarity to the recursive call.
|
||||||
|
/// You can do this with `ty.with_polarity(polarity).variance_of(typevar)`.
|
||||||
|
/// Generally, this will be whenever the type occurs in argument-position,
|
||||||
|
/// in which case you will want `TypeVarVariance::Contravariant`, or
|
||||||
|
/// `TypeVarVariance::Invariant` if the value(s) being annotated is known to
|
||||||
|
/// be mutable, such as `T` in `list[T]`. See the [typing spec][typing-spec]
|
||||||
|
/// for more details.
|
||||||
|
///
|
||||||
|
/// [typing-spec]: https://typing.python.org/en/latest/spec/generics.html#variance
|
||||||
|
fn with_polarity(self, polarity: TypeVarVariance) -> impl VarianceInferable<'db> {
|
||||||
WithPolarity {
|
WithPolarity {
|
||||||
variance_inferable: self,
|
variance_inferable: self,
|
||||||
polarity,
|
polarity,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue