[ty] Rename MRO structs to match static nomenclature (#22549)

## Summary

I didn't want to make the "dynamic" `type(...)` PR any larger, but it
probably makes sense to rename these now that we have `Dynamic`
variants.
This commit is contained in:
Charlie Marsh
2026-01-13 08:53:49 -05:00
committed by GitHub
parent 990d0a8999
commit 6d8f2864c3
5 changed files with 48 additions and 38 deletions

View File

@@ -64,7 +64,7 @@ use crate::types::generics::{
ApplySpecialization, InferableTypeVars, Specialization, SpecializationBuilder, bind_typevar,
typing_self, walk_generic_context,
};
use crate::types::mro::{Mro, MroError, MroIterator};
use crate::types::mro::{Mro, MroIterator, StaticMroError};
pub(crate) use crate::types::narrow::{NarrowingConstraint, infer_narrowing_constraint};
use crate::types::newtype::NewType;
pub(crate) use crate::types::signatures::{Parameter, Parameters};

View File

@@ -5,7 +5,7 @@ use std::sync::{LazyLock, Mutex};
use super::TypeVarVariance;
use super::{
BoundTypeVarInstance, MemberLookupPolicy, Mro, MroError, MroIterator, SpecialFormType,
BoundTypeVarInstance, MemberLookupPolicy, Mro, MroIterator, SpecialFormType, StaticMroError,
SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase,
function::FunctionType,
};
@@ -128,8 +128,8 @@ fn try_mro_cycle_initial<'db>(
_id: salsa::Id,
self_: StaticClassLiteral<'db>,
specialization: Option<Specialization<'db>>,
) -> Result<Mro<'db>, MroError<'db>> {
Err(MroError::cycle(
) -> Result<Mro<'db>, StaticMroError<'db>> {
Err(StaticMroError::cycle(
db,
self_.apply_optional_specialization(db, specialization),
))
@@ -2498,7 +2498,7 @@ impl<'db> StaticClassLiteral<'db> {
self,
db: &'db dyn Db,
specialization: Option<Specialization<'db>>,
) -> Result<Mro<'db>, MroError<'db>> {
) -> Result<Mro<'db>, StaticMroError<'db>> {
tracing::trace!("StaticClassLiteral::try_mro: {}", self.name(db));
Mro::of_static_class(db, self, specialization)
}
@@ -2605,7 +2605,7 @@ impl<'db> StaticClassLiteral<'db> {
return Ok((SubclassOfType::subclass_of_unknown(), None));
}
if self.try_mro(db, None).is_err_and(MroError::is_cycle) {
if self.try_mro(db, None).is_err_and(StaticMroError::is_cycle) {
return Ok((SubclassOfType::subclass_of_unknown(), None));
}

View File

@@ -6,7 +6,7 @@ use crate::types::mro::MroIterator;
use crate::types::tuple::TupleType;
use crate::types::{
ApplyTypeMappingVisitor, ClassLiteral, ClassType, DynamicType, KnownClass, KnownInstanceType,
MaterializationKind, MroError, NormalizedVisitor, SpecialFormType, Type, TypeContext,
MaterializationKind, NormalizedVisitor, SpecialFormType, StaticMroError, Type, TypeContext,
TypeMapping, todo_type,
};
@@ -381,7 +381,7 @@ impl<'db> ClassBase<'db> {
};
class_literal
.try_mro(db, specialization)
.is_err_and(MroError::is_cycle)
.is_err_and(StaticMroError::is_cycle)
}
ClassBase::Dynamic(_)
| ClassBase::Generic

View File

@@ -102,7 +102,7 @@ use crate::types::generics::{
};
use crate::types::infer::nearest_enclosing_function;
use crate::types::instance::SliceLiteral;
use crate::types::mro::{DynamicMroErrorKind, MroErrorKind};
use crate::types::mro::{DynamicMroErrorKind, StaticMroErrorKind};
use crate::types::newtype::NewType;
use crate::types::subclass_of::SubclassOfInner;
use crate::types::tuple::{Tuple, TupleLength, TupleSpec, TupleType};
@@ -797,13 +797,13 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
// (4) Check that the class's MRO is resolvable
match class.try_mro(self.db(), None) {
Err(mro_error) => match mro_error.reason() {
MroErrorKind::DuplicateBases(duplicates) => {
StaticMroErrorKind::DuplicateBases(duplicates) => {
let base_nodes = class_node.bases();
for duplicate in duplicates {
report_duplicate_bases(&self.context, class, duplicate, base_nodes);
}
}
MroErrorKind::InvalidBases(bases) => {
StaticMroErrorKind::InvalidBases(bases) => {
let base_nodes = class_node.bases();
for (index, base_ty) in bases {
report_invalid_or_unsupported_base(
@@ -814,7 +814,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
);
}
}
MroErrorKind::UnresolvableMro { bases_list } => {
StaticMroErrorKind::UnresolvableMro { bases_list } => {
if let Some(builder) =
self.context.report_lint(&INCONSISTENT_MRO, class_node)
{
@@ -829,7 +829,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
));
}
}
MroErrorKind::Pep695ClassWithGenericInheritance => {
StaticMroErrorKind::Pep695ClassWithGenericInheritance => {
if let Some(builder) =
self.context.report_lint(&INVALID_GENERIC_CLASS, class_node)
{
@@ -839,7 +839,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
);
}
}
MroErrorKind::InheritanceCycle => {
StaticMroErrorKind::InheritanceCycle => {
if let Some(builder) = self
.context
.report_lint(&CYCLIC_CLASS_DEFINITION, class_node)

View File

@@ -53,7 +53,7 @@ impl<'db> Mro<'db> {
db: &'db dyn Db,
class_literal: StaticClassLiteral<'db>,
specialization: Option<Specialization<'db>>,
) -> Result<Self, MroError<'db>> {
) -> Result<Self, StaticMroError<'db>> {
/// Possibly add `Generic` to the resolved bases list.
///
/// This function is called in two cases:
@@ -141,10 +141,15 @@ impl<'db> Mro<'db> {
{
ClassBase::try_from_type(db, *single_base, ClassLiteral::Static(class_literal))
.map_or_else(
|| Err(MroErrorKind::InvalidBases(Box::from([(0, *single_base)]))),
|| {
Err(StaticMroErrorKind::InvalidBases(Box::from([(
0,
*single_base,
)])))
},
|single_base| {
if single_base.has_cyclic_mro(db) {
Err(MroErrorKind::InheritanceCycle)
Err(StaticMroErrorKind::InheritanceCycle)
} else {
Ok(std::iter::once(ClassBase::Class(class))
.chain(single_base.mro(db, specialization))
@@ -188,8 +193,10 @@ impl<'db> Mro<'db> {
}
if !invalid_bases.is_empty() {
return Err(MroErrorKind::InvalidBases(invalid_bases.into_boxed_slice())
.into_mro_error(db, class));
return Err(
StaticMroErrorKind::InvalidBases(invalid_bases.into_boxed_slice())
.into_mro_error(db, class),
);
}
// `Generic` is implicitly added to the bases list of a class that has PEP-695 type parameters
@@ -201,7 +208,7 @@ impl<'db> Mro<'db> {
let mut seqs = vec![VecDeque::from([ClassBase::Class(class)])];
for base in &resolved_bases {
if base.has_cyclic_mro(db) {
return Err(MroErrorKind::InheritanceCycle.into_mro_error(db, class));
return Err(StaticMroErrorKind::InheritanceCycle.into_mro_error(db, class));
}
seqs.push(base.mro(db, specialization).collect());
}
@@ -229,9 +236,8 @@ impl<'db> Mro<'db> {
)
})
{
return Err(
MroErrorKind::Pep695ClassWithGenericInheritance.into_mro_error(db, class)
);
return Err(StaticMroErrorKind::Pep695ClassWithGenericInheritance
.into_mro_error(db, class));
}
let mut duplicate_dynamic_bases = false;
@@ -291,14 +297,14 @@ impl<'db> Mro<'db> {
if duplicate_dynamic_bases {
Ok(Mro::from_error(db, class))
} else {
Err(MroErrorKind::UnresolvableMro {
Err(StaticMroErrorKind::UnresolvableMro {
bases_list: original_bases.iter().copied().collect(),
}
.into_mro_error(db, class))
}
} else {
Err(
MroErrorKind::DuplicateBases(duplicate_bases.into_boxed_slice())
StaticMroErrorKind::DuplicateBases(duplicate_bases.into_boxed_slice())
.into_mro_error(db, class),
)
}
@@ -537,23 +543,23 @@ impl<'db> Iterator for MroIterator<'db> {
impl std::iter::FusedIterator for MroIterator<'_> {}
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
pub(super) struct MroError<'db> {
kind: MroErrorKind<'db>,
pub(super) struct StaticMroError<'db> {
kind: StaticMroErrorKind<'db>,
fallback_mro: Mro<'db>,
}
impl<'db> MroError<'db> {
impl<'db> StaticMroError<'db> {
/// Construct an MRO error of kind `InheritanceCycle`.
pub(super) fn cycle(db: &'db dyn Db, class: ClassType<'db>) -> Self {
MroErrorKind::InheritanceCycle.into_mro_error(db, class)
StaticMroErrorKind::InheritanceCycle.into_mro_error(db, class)
}
pub(super) fn is_cycle(&self) -> bool {
matches!(self.kind, MroErrorKind::InheritanceCycle)
matches!(self.kind, StaticMroErrorKind::InheritanceCycle)
}
/// Return an [`MroErrorKind`] variant describing why we could not resolve the MRO for this class.
pub(super) fn reason(&self) -> &MroErrorKind<'db> {
/// Return an [`StaticMroErrorKind`] variant describing why we could not resolve the MRO for this class.
pub(super) fn reason(&self) -> &StaticMroErrorKind<'db> {
&self.kind
}
@@ -564,9 +570,9 @@ impl<'db> MroError<'db> {
}
}
/// Possible ways in which attempting to resolve the MRO of a class might fail.
/// Possible ways in which attempting to resolve the MRO of a statically-defined class might fail.
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
pub(super) enum MroErrorKind<'db> {
pub(super) enum StaticMroErrorKind<'db> {
/// The class inherits from one or more invalid bases.
///
/// To avoid excessive complexity in our implementation,
@@ -596,9 +602,13 @@ pub(super) enum MroErrorKind<'db> {
UnresolvableMro { bases_list: Box<[Type<'db>]> },
}
impl<'db> MroErrorKind<'db> {
pub(super) fn into_mro_error(self, db: &'db dyn Db, class: ClassType<'db>) -> MroError<'db> {
MroError {
impl<'db> StaticMroErrorKind<'db> {
pub(super) fn into_mro_error(
self,
db: &'db dyn Db,
class: ClassType<'db>,
) -> StaticMroError<'db> {
StaticMroError {
kind: self,
fallback_mro: Mro::from_error(db, class),
}
@@ -660,7 +670,7 @@ fn c3_merge(mut sequences: Vec<VecDeque<ClassBase>>) -> Option<Mro> {
/// Error for dynamic class MRO computation with fallback MRO.
///
/// Separate from [`MroError`] because dynamic classes can only have a subset of MRO errors.
/// Separate from [`StaticMroError`] because dynamic classes can only have a subset of MRO errors.
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize, salsa::Update)]
pub(crate) struct DynamicMroError<'db> {
kind: DynamicMroErrorKind<'db>,