mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 13:30:49 -05:00
[ty] Use IntersectionType::from_elements more (#22329)
This commit is contained in:
@@ -7631,13 +7631,13 @@ impl<'db> Type<'db> {
|
||||
// but it appears to be what users often expect, and it improves compatibility with
|
||||
// other type checkers such as mypy.
|
||||
// See conversation in https://github.com/astral-sh/ruff/pull/19915.
|
||||
SpecialFormType::NamedTuple => Ok(IntersectionBuilder::new(db)
|
||||
.positive_elements([
|
||||
SpecialFormType::NamedTuple => Ok(IntersectionType::from_elements(
|
||||
db,
|
||||
[
|
||||
Type::homogeneous_tuple(db, Type::object()),
|
||||
KnownClass::NamedTupleLike.to_instance(db),
|
||||
])
|
||||
.build()),
|
||||
|
||||
],
|
||||
)),
|
||||
SpecialFormType::TypingSelf => {
|
||||
let index = semantic_index(db, scope_id.file(db));
|
||||
let Some(class) = nearest_enclosing_class(db, index, scope_id) else {
|
||||
@@ -15035,16 +15035,10 @@ pub(crate) mod tests {
|
||||
// salsa, but that would mean we would have to pass in `db` everywhere.
|
||||
|
||||
// A union of several `Todo` types collapses to a single `Todo` type:
|
||||
assert!(UnionType::from_elements(&db, vec![todo1, todo2]).is_todo());
|
||||
assert!(UnionType::from_elements(&db, [todo1, todo2]).is_todo());
|
||||
|
||||
// And similar for intersection types:
|
||||
assert!(
|
||||
IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
.add_positive(todo2)
|
||||
.build()
|
||||
.is_todo()
|
||||
);
|
||||
assert!(IntersectionType::from_elements(&db, [todo1, todo2]).is_todo());
|
||||
assert!(
|
||||
IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
@@ -15129,16 +15123,10 @@ pub(crate) mod tests {
|
||||
assert_eq!(normalized.display(&db).to_string(), "int");
|
||||
|
||||
// The same can be said about intersections for the `Never` type.
|
||||
let intersection = IntersectionBuilder::new(&db)
|
||||
.add_positive(Type::Never)
|
||||
.add_positive(div)
|
||||
.build();
|
||||
let intersection = IntersectionType::from_elements(&db, [Type::Never, div]);
|
||||
assert_eq!(intersection.display(&db).to_string(), "Never");
|
||||
|
||||
let intersection = IntersectionBuilder::new(&db)
|
||||
.add_positive(div)
|
||||
.add_positive(Type::Never)
|
||||
.build();
|
||||
let intersection = IntersectionType::from_elements(&db, [div, Type::Never]);
|
||||
assert_eq!(intersection.display(&db).to_string(), "Never");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use super::TypeVarVariance;
|
||||
use super::{
|
||||
BoundTypeVarInstance, IntersectionBuilder, MemberLookupPolicy, Mro, MroError, MroIterator,
|
||||
SpecialFormType, SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase,
|
||||
BoundTypeVarInstance, MemberLookupPolicy, Mro, MroError, MroIterator, SpecialFormType,
|
||||
SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase,
|
||||
function::FunctionType,
|
||||
};
|
||||
use crate::place::TypeOrigin;
|
||||
@@ -37,11 +37,11 @@ use crate::types::visitor::{TypeCollector, TypeVisitor, walk_type_with_recursion
|
||||
use crate::types::{
|
||||
ApplyTypeMappingVisitor, Binding, BindingContext, BoundSuperType, CallableType,
|
||||
CallableTypeKind, CallableTypes, DATACLASS_FLAGS, DataclassFlags, DataclassParams,
|
||||
DeprecatedInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor, IsDisjointVisitor,
|
||||
IsEquivalentVisitor, KnownInstanceType, ManualPEP695TypeAliasType, MaterializationKind,
|
||||
NormalizedVisitor, PropertyInstanceType, TypeAliasType, TypeContext, TypeMapping, TypeRelation,
|
||||
TypedDictParams, UnionBuilder, VarianceInferable, binding_type, declaration_type,
|
||||
determine_upper_bound,
|
||||
DeprecatedInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor, IntersectionType,
|
||||
IsDisjointVisitor, IsEquivalentVisitor, KnownInstanceType, ManualPEP695TypeAliasType,
|
||||
MaterializationKind, NormalizedVisitor, PropertyInstanceType, TypeAliasType, TypeContext,
|
||||
TypeMapping, TypeRelation, TypedDictParams, UnionBuilder, VarianceInferable, binding_type,
|
||||
declaration_type, determine_upper_bound,
|
||||
};
|
||||
use crate::{
|
||||
Db, FxIndexMap, FxIndexSet, FxOrderSet, Program,
|
||||
@@ -2252,13 +2252,8 @@ impl<'db> ClassLiteral<'db> {
|
||||
qualifiers,
|
||||
},
|
||||
Some(dynamic_type),
|
||||
) => Place::bound(
|
||||
IntersectionBuilder::new(db)
|
||||
.add_positive(ty)
|
||||
.add_positive(dynamic_type)
|
||||
.build(),
|
||||
)
|
||||
.with_qualifiers(qualifiers),
|
||||
) => Place::bound(IntersectionType::from_elements(db, [ty, dynamic_type]))
|
||||
.with_qualifiers(qualifiers),
|
||||
|
||||
(
|
||||
PlaceAndQualifiers {
|
||||
|
||||
@@ -15,9 +15,9 @@ use crate::types::typed_dict::{
|
||||
SynthesizedTypedDictType, TypedDictFieldBuilder, TypedDictSchema, TypedDictType,
|
||||
};
|
||||
use crate::types::{
|
||||
CallableType, ClassLiteral, ClassType, IntersectionBuilder, KnownClass, KnownInstanceType,
|
||||
SpecialFormType, SubclassOfInner, SubclassOfType, Truthiness, Type, TypeContext,
|
||||
TypeVarBoundOrConstraints, UnionBuilder, infer_expression_types,
|
||||
CallableType, ClassLiteral, ClassType, IntersectionBuilder, IntersectionType, KnownClass,
|
||||
KnownInstanceType, SpecialFormType, SubclassOfInner, SubclassOfType, Truthiness, Type,
|
||||
TypeContext, TypeVarBoundOrConstraints, UnionBuilder, infer_expression_types,
|
||||
};
|
||||
|
||||
use ruff_db::parsed::{ParsedModuleRef, parsed_module};
|
||||
@@ -343,18 +343,12 @@ impl<'db> NarrowingConstraint<'db> {
|
||||
};
|
||||
|
||||
let new_regular_disjunct = self.regular_disjunct.map(|regular_disjunct| {
|
||||
IntersectionBuilder::new(db)
|
||||
.add_positive(regular_disjunct)
|
||||
.add_positive(other_regular_disjunct)
|
||||
.build()
|
||||
IntersectionType::from_elements(db, [regular_disjunct, other_regular_disjunct])
|
||||
});
|
||||
|
||||
let additional_typeguard_disjuncts =
|
||||
self.typeguard_disjuncts.iter().map(|typeguard_disjunct| {
|
||||
IntersectionBuilder::new(db)
|
||||
.add_positive(*typeguard_disjunct)
|
||||
.add_positive(other_regular_disjunct)
|
||||
.build()
|
||||
IntersectionType::from_elements(db, [*typeguard_disjunct, other_regular_disjunct])
|
||||
});
|
||||
|
||||
let mut new_typeguard_disjuncts = other.typeguard_disjuncts;
|
||||
@@ -954,10 +948,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||
match op {
|
||||
ast::CmpOp::IsNot => {
|
||||
if rhs_ty.is_singleton(self.db) {
|
||||
let ty = IntersectionBuilder::new(self.db)
|
||||
.add_negative(rhs_ty)
|
||||
.build();
|
||||
Some(ty)
|
||||
Some(rhs_ty.negate(self.db))
|
||||
} else {
|
||||
// Non-singletons cannot be safely narrowed using `is not`
|
||||
None
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::place::{builtins_symbol, known_module_symbol};
|
||||
use crate::types::enums::is_single_member_enum;
|
||||
use crate::types::tuple::TupleType;
|
||||
use crate::types::{
|
||||
BoundMethodType, EnumLiteralType, IntersectionBuilder, KnownClass, Parameter, Parameters,
|
||||
Signature, SpecialFormType, SubclassOfType, Type, UnionType,
|
||||
BoundMethodType, EnumLiteralType, IntersectionBuilder, IntersectionType, KnownClass, Parameter,
|
||||
Parameters, Signature, SpecialFormType, SubclassOfType, Type, UnionType,
|
||||
};
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
use ruff_python_ast::name::Name;
|
||||
@@ -579,11 +579,7 @@ pub(crate) fn intersection<'db>(
|
||||
db: &'db TestDb,
|
||||
tys: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Type<'db> {
|
||||
let mut builder = IntersectionBuilder::new(db);
|
||||
for ty in tys {
|
||||
builder = builder.add_positive(ty);
|
||||
}
|
||||
builder.build()
|
||||
IntersectionType::from_elements(db, tys)
|
||||
}
|
||||
|
||||
pub(crate) fn union<'db>(db: &'db TestDb, tys: impl IntoIterator<Item = Type<'db>>) -> Type<'db> {
|
||||
|
||||
Reference in New Issue
Block a user