diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c43bd7b2c494e..b4fd9cc307492 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -12,7 +12,7 @@ use rustc_type_ir::search_graph::{CandidateHeadUsages, LowerAvailableDepth, Path use rustc_type_ir::solve::{ AccessedOpaques, ExternalRegionConstraints, FetchEligibleAssocItemResponse, MaybeInfo, NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunCondition, - RerunNonErased, RerunReason, RerunResultExt, SmallCopyList, + RerunNonErased, RerunReason, RerunResultExt, SmallCopySet, }; use rustc_type_ir::{ self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased, @@ -1732,7 +1732,7 @@ fn should_rerun_after_erased_canonicalization( parent_opaque_types: &[(OpaqueTypeKey, I::Ty)], ) -> RerunDecision { let parent_opaque_def_ids = parent_opaque_types.iter().map(|(key, _)| key.def_id.into()); - let opaque_in_storage = |opaques: I::LocalDefIds, def_ids: SmallCopyList<_>| { + let opaque_in_storage = |opaques: I::LocalDefIds, def_ids: SmallCopySet<_>| { if def_ids.as_ref().is_empty() { RerunDecision::No } else if opaques diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a916dbd079efa..303476fa11694 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -79,17 +79,21 @@ impl From for NoSolutionOrRerunNonErased { } } +/// A small set of up to 3 `Copy` elements, used as an optimization in [`RerunCondition`]. +/// The entire set can be `Copy`ed because of this requirement. +/// +/// Set properties maintained using [`union`](SmallCopySet::union), which deduplicates values. #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[derive(TypeVisitable_Generic, TypeFoldable_Generic, GenericTypeVisitable)] #[cfg_attr(feature = "nightly", derive(StableHash_NoContext))] -pub enum SmallCopyList { +pub enum SmallCopySet { Empty, One([T; 1]), Two([T; 2]), Three([T; 3]), } -impl SmallCopyList { +impl SmallCopySet { fn empty() -> Self { Self::Empty } @@ -127,7 +131,7 @@ impl SmallCopyList { } } -impl AsRef<[T]> for SmallCopyList { +impl AsRef<[T]> for SmallCopySet { fn as_ref(&self) -> &[T] { match self { Self::Empty => &[], @@ -165,12 +169,12 @@ pub enum RerunCondition { /// Note that this only reruns according to the condition *if* we are in [`TypingMode::Typeck`]. AnyOpaqueHasInferAsHidden, /// Note: unconditionally reruns in postanalysis - OpaqueInStorage(SmallCopyList), + OpaqueInStorage(SmallCopySet), /// Merges [`Self::AnyOpaqueHasInferAsHidden`] and [`Self::OpaqueInStorage`]. /// Note that just like the unmerged [`Self::OpaqueInStorage`], that part of the /// condition only matters in [`TypingMode::Typeck`] - OpaqueInStorageOrAnyOpaqueHasInferAsHidden(SmallCopyList), + OpaqueInStorageOrAnyOpaqueHasInferAsHidden(SmallCopySet), Always, } @@ -327,7 +331,7 @@ impl AccessedOpaques { debug!("set rerun if post analysis"); self.update(AccessedOpaques { reason: Some(reason), - rerun: RerunCondition::OpaqueInStorage(SmallCopyList::empty()), + rerun: RerunCondition::OpaqueInStorage(SmallCopySet::empty()), }) } @@ -339,7 +343,7 @@ impl AccessedOpaques { debug!("set rerun if opaque type {defid:?} in storage"); self.update(AccessedOpaques { reason: Some(reason), - rerun: RerunCondition::OpaqueInStorage(SmallCopyList::new(defid.into())), + rerun: RerunCondition::OpaqueInStorage(SmallCopySet::new(defid.into())), }) }