mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] Various minor cleanups to tuple internals (#19891)
This commit is contained in:
parent
2f3c7ad1fc
commit
5725c4b17f
7 changed files with 57 additions and 60 deletions
|
@ -4826,7 +4826,7 @@ impl<'db> Type<'db> {
|
|||
// with each individual character, instead of just an array of
|
||||
// `LiteralString`, but there would be a cost and it's not clear that
|
||||
// it's worth it.
|
||||
return Ok(Cow::Owned(TupleSpec::from_elements(std::iter::repeat_n(
|
||||
return Ok(Cow::Owned(TupleSpec::heterogeneous(std::iter::repeat_n(
|
||||
Type::LiteralString,
|
||||
string_literal_ty.python_len(db),
|
||||
))));
|
||||
|
|
|
@ -237,7 +237,7 @@ fn expand_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<Vec<Type<'db>>> {
|
|||
}
|
||||
})
|
||||
.multi_cartesian_product()
|
||||
.map(|types| Type::tuple(TupleType::from_elements(db, types)))
|
||||
.map(|types| Type::tuple(TupleType::heterogeneous(db, types)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if expanded.len() == 1 {
|
||||
|
|
|
@ -1349,7 +1349,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
semantic_index(db, self.file(db)).expect_single_definition(class_stmt);
|
||||
|
||||
if self.is_known(db, KnownClass::VersionInfo) {
|
||||
let tuple_type = TupleType::new(db, TupleSpec::version_info_spec(db))
|
||||
let tuple_type = TupleType::new(db, &TupleSpec::version_info_spec(db))
|
||||
.expect("sys.version_info tuple spec should always be a valid tuple");
|
||||
|
||||
Box::new([
|
||||
|
|
|
@ -241,7 +241,7 @@ impl<'db> GenericContext<'db> {
|
|||
db,
|
||||
self,
|
||||
partial.types(db),
|
||||
TupleType::homogeneous(db, Type::unknown()),
|
||||
Some(TupleType::homogeneous(db, Type::unknown())),
|
||||
)
|
||||
} else {
|
||||
partial
|
||||
|
|
|
@ -8561,8 +8561,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
}
|
||||
|
||||
let tuple_generic_alias = |db: &'db dyn Db, tuple: Option<TupleType<'db>>| {
|
||||
let tuple =
|
||||
tuple.unwrap_or_else(|| TupleType::homogeneous(db, Type::unknown()).unwrap());
|
||||
let tuple = tuple.unwrap_or_else(|| TupleType::homogeneous(db, Type::unknown()));
|
||||
Type::from(tuple.to_class_type(db))
|
||||
};
|
||||
|
||||
|
@ -10075,8 +10074,8 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
self.infer_expression(ellipsis);
|
||||
let result =
|
||||
TupleType::homogeneous(self.db(), self.infer_type_expression(element));
|
||||
self.store_expression_type(tuple_slice, Type::tuple(result));
|
||||
return result;
|
||||
self.store_expression_type(tuple_slice, Type::tuple(Some(result)));
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
let mut element_types = TupleSpecBuilder::with_capacity(elements.len());
|
||||
|
@ -10102,9 +10101,9 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
}
|
||||
|
||||
let ty = if return_todo {
|
||||
TupleType::homogeneous(self.db(), todo_type!("PEP 646"))
|
||||
Some(TupleType::homogeneous(self.db(), todo_type!("PEP 646")))
|
||||
} else {
|
||||
TupleType::new(self.db(), element_types.build())
|
||||
TupleType::new(self.db(), &element_types.build())
|
||||
};
|
||||
|
||||
// Here, we store the type for the inner `int, str` tuple-expression,
|
||||
|
@ -10118,9 +10117,9 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
let single_element_ty = self.infer_type_expression(single_element);
|
||||
if element_could_alter_type_of_whole_tuple(single_element, single_element_ty, self)
|
||||
{
|
||||
TupleType::homogeneous(self.db(), todo_type!("PEP 646"))
|
||||
Some(TupleType::homogeneous(self.db(), todo_type!("PEP 646")))
|
||||
} else {
|
||||
TupleType::from_elements(self.db(), std::iter::once(single_element_ty))
|
||||
TupleType::heterogeneous(self.db(), std::iter::once(single_element_ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,30 @@ impl<'db> Type<'db> {
|
|||
let Some(tuple) = tuple else {
|
||||
return Type::Never;
|
||||
};
|
||||
Type::tuple_instance(tuple)
|
||||
}
|
||||
|
||||
pub(crate) fn homogeneous_tuple(db: &'db dyn Db, element: Type<'db>) -> Self {
|
||||
Type::tuple_instance(TupleType::homogeneous(db, element))
|
||||
}
|
||||
|
||||
pub(crate) fn heterogeneous_tuple<I, T>(db: &'db dyn Db, elements: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<Type<'db>>,
|
||||
{
|
||||
Type::tuple(TupleType::heterogeneous(
|
||||
db,
|
||||
elements.into_iter().map(Into::into),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn empty_tuple(db: &'db dyn Db) -> Self {
|
||||
Type::tuple_instance(TupleType::empty(db))
|
||||
}
|
||||
|
||||
/// **Private** helper function to create a `Type::NominalInstance` from a tuple.
|
||||
fn tuple_instance(tuple: TupleType<'db>) -> Self {
|
||||
Type::NominalInstance(NominalInstanceType(NominalInstanceInner::ExactTuple(tuple)))
|
||||
}
|
||||
|
||||
|
@ -275,11 +299,9 @@ impl<'db> NominalInstanceType<'db> {
|
|||
other: Self,
|
||||
visitor: &PairVisitor<'db>,
|
||||
) -> bool {
|
||||
let self_spec = self.tuple_spec(db);
|
||||
if let Some(self_spec) = self_spec.as_deref() {
|
||||
let other_spec = other.tuple_spec(db);
|
||||
if let Some(other_spec) = other_spec.as_deref() {
|
||||
if self_spec.is_disjoint_from_impl(db, other_spec, visitor) {
|
||||
if let Some(self_spec) = self.tuple_spec(db) {
|
||||
if let Some(other_spec) = other.tuple_spec(db) {
|
||||
if self_spec.is_disjoint_from_impl(db, &other_spec, visitor) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
//! that adds that "collapse `Never`" behavior, whereas [`TupleSpec`] allows you to add any element
|
||||
//! types, including `Never`.)
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
@ -145,44 +144,18 @@ pub(super) fn walk_tuple_type<'db, V: super::visitor::TypeVisitor<'db> + ?Sized>
|
|||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for TupleType<'_> {}
|
||||
|
||||
impl<'db> Type<'db> {
|
||||
pub(crate) fn homogeneous_tuple(db: &'db dyn Db, element: Type<'db>) -> Self {
|
||||
Type::tuple(TupleType::homogeneous(db, element))
|
||||
}
|
||||
|
||||
pub(crate) fn heterogeneous_tuple<I, T>(db: &'db dyn Db, elements: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<Type<'db>>,
|
||||
{
|
||||
Type::tuple(TupleType::from_elements(
|
||||
db,
|
||||
elements.into_iter().map(Into::into),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn empty_tuple(db: &'db dyn Db) -> Self {
|
||||
Type::tuple(Some(TupleType::empty(db)))
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl<'db> TupleType<'db> {
|
||||
pub(crate) fn new<T>(db: &'db dyn Db, tuple_key: T) -> Option<Self>
|
||||
where
|
||||
T: Borrow<TupleSpec<'db>> + Hash + salsa::plumbing::interned::Lookup<TupleSpec<'db>>,
|
||||
TupleSpec<'db>: salsa::plumbing::interned::HashEqLike<T>,
|
||||
{
|
||||
pub(crate) fn new(db: &'db dyn Db, spec: &TupleSpec<'db>) -> Option<Self> {
|
||||
// If a fixed-length (i.e., mandatory) element of the tuple is `Never`, then it's not
|
||||
// possible to instantiate the tuple as a whole.
|
||||
let tuple = tuple_key.borrow();
|
||||
if tuple.fixed_elements().any(Type::is_never) {
|
||||
if spec.fixed_elements().any(Type::is_never) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// If the variable-length portion is Never, it can only be instantiated with zero elements.
|
||||
// That means this isn't a variable-length tuple after all!
|
||||
if let TupleSpec::Variable(tuple) = tuple {
|
||||
if let TupleSpec::Variable(tuple) = spec {
|
||||
if tuple.variable.is_never() {
|
||||
let tuple = TupleSpec::Fixed(FixedLengthTuple::from_elements(
|
||||
tuple.prefix.iter().chain(&tuple.suffix).copied(),
|
||||
|
@ -191,19 +164,18 @@ impl<'db> TupleType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
Some(TupleType::new_internal(db, tuple_key))
|
||||
Some(TupleType::new_internal(db, spec))
|
||||
}
|
||||
|
||||
pub(crate) fn empty(db: &'db dyn Db) -> Self {
|
||||
TupleType::new(db, TupleSpec::from(FixedLengthTuple::empty()))
|
||||
.expect("TupleType::new() should always return `Some` for an empty `TupleSpec`")
|
||||
TupleType::new_internal(db, TupleSpec::from(FixedLengthTuple::empty()))
|
||||
}
|
||||
|
||||
pub(crate) fn from_elements(
|
||||
pub(crate) fn heterogeneous(
|
||||
db: &'db dyn Db,
|
||||
types: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Option<Self> {
|
||||
TupleType::new(db, TupleSpec::from_elements(types))
|
||||
TupleType::new(db, &TupleSpec::heterogeneous(types))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -213,11 +185,14 @@ impl<'db> TupleType<'db> {
|
|||
variable: Type<'db>,
|
||||
suffix: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Option<Self> {
|
||||
TupleType::new(db, VariableLengthTuple::mixed(prefix, variable, suffix))
|
||||
TupleType::new(db, &VariableLengthTuple::mixed(prefix, variable, suffix))
|
||||
}
|
||||
|
||||
pub(crate) fn homogeneous(db: &'db dyn Db, element: Type<'db>) -> Option<Self> {
|
||||
TupleType::new(db, TupleSpec::homogeneous(element))
|
||||
pub(crate) fn homogeneous(db: &'db dyn Db, element: Type<'db>) -> Self {
|
||||
match element {
|
||||
Type::Never => TupleType::empty(db),
|
||||
_ => TupleType::new_internal(db, TupleSpec::homogeneous(element)),
|
||||
}
|
||||
}
|
||||
|
||||
// N.B. If this method is not Salsa-tracked, we take 10 minutes to check
|
||||
|
@ -248,11 +223,11 @@ impl<'db> TupleType<'db> {
|
|||
db: &'db dyn Db,
|
||||
visitor: &TypeTransformer<'db>,
|
||||
) -> Option<Self> {
|
||||
TupleType::new(db, self.tuple(db).normalized_impl(db, visitor))
|
||||
TupleType::new(db, &self.tuple(db).normalized_impl(db, visitor))
|
||||
}
|
||||
|
||||
pub(crate) fn materialize(self, db: &'db dyn Db, variance: TypeVarVariance) -> Option<Self> {
|
||||
TupleType::new(db, self.tuple(db).materialize(db, variance))
|
||||
TupleType::new(db, &self.tuple(db).materialize(db, variance))
|
||||
}
|
||||
|
||||
pub(crate) fn apply_type_mapping_impl<'a>(
|
||||
|
@ -263,7 +238,8 @@ impl<'db> TupleType<'db> {
|
|||
) -> Option<Self> {
|
||||
TupleType::new(
|
||||
db,
|
||||
self.tuple(db)
|
||||
&self
|
||||
.tuple(db)
|
||||
.apply_type_mapping_impl(db, type_mapping, visitor),
|
||||
)
|
||||
}
|
||||
|
@ -935,7 +911,7 @@ impl<T> Tuple<T> {
|
|||
VariableLengthTuple::homogeneous(element)
|
||||
}
|
||||
|
||||
pub(crate) fn from_elements(elements: impl IntoIterator<Item = T>) -> Self {
|
||||
pub(crate) fn heterogeneous(elements: impl IntoIterator<Item = T>) -> Self {
|
||||
FixedLengthTuple::from_elements(elements).into()
|
||||
}
|
||||
|
||||
|
@ -1182,7 +1158,7 @@ impl<'db> Tuple<Type<'db>> {
|
|||
Type::Union(UnionType::new(db, elements))
|
||||
};
|
||||
|
||||
TupleSpec::from_elements([
|
||||
TupleSpec::heterogeneous([
|
||||
Type::IntLiteral(python_version.major.into()),
|
||||
Type::IntLiteral(python_version.minor.into()),
|
||||
int_instance_ty,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue