From 3ddcf8b94cb22a3c8acd73b96fe938c1515a4a7b Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 7 Jul 2025 11:19:58 +0200 Subject: [PATCH] remove `has_nested` --- compiler/rustc_middle/src/traits/select.rs | 9 +-- .../src/traits/select/candidate_assembly.rs | 26 +++--- .../src/traits/select/confirmation.rs | 79 +++++++++---------- .../src/traits/select/mod.rs | 6 +- 4 files changed, 54 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index aa2ee756bc502..c498e6b3c83da 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -97,9 +97,7 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>), pub enum SelectionCandidate<'tcx> { /// A built-in implementation for the `Sized` trait. This is preferred /// over all other candidates. - SizedCandidate { - has_nested: bool, - }, + SizedCandidate, /// A builtin implementation for some specific traits, used in cases /// where we cannot rely an ordinary library implementations. @@ -107,10 +105,7 @@ pub enum SelectionCandidate<'tcx> { /// The most notable examples are `Copy` and `Clone`. This is also /// used for the `DiscriminantKind` and `Pointee` trait, both of which have /// an associated type. - BuiltinCandidate { - /// `false` if there are no *further* obligations. - has_nested: bool, - }, + BuiltinCandidate, /// Implementation of transmutability trait. TransmutabilityCandidate, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 81ce58a93fa9d..9af85f5e3f0ef 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -80,11 +80,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } Some(LangItem::DiscriminantKind) => { // `DiscriminantKind` is automatically implemented for every type. - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } Some(LangItem::PointeeTrait) => { // `Pointee` is automatically implemented for every type. - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } Some(LangItem::Sized) => { self.assemble_builtin_sized_candidate( @@ -365,7 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",); - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } } @@ -810,7 +810,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { hir::Movability::Movable => { // Movable coroutines are always `Unpin`, so add an // unconditional builtin candidate. - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } } } @@ -1122,10 +1122,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { sizedness: SizedTraitKind, ) { match self.sizedness_conditions(obligation, sizedness) { - BuiltinImplConditions::Where(nested) => { - candidates - .vec - .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() }); + BuiltinImplConditions::Where(_nested) => { + candidates.vec.push(SizedCandidate); } BuiltinImplConditions::None => {} BuiltinImplConditions::Ambiguous => { @@ -1143,10 +1141,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>, ) { match conditions { - BuiltinImplConditions::Where(nested) => { - candidates - .vec - .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() }); + BuiltinImplConditions::Where(_) => { + candidates.vec.push(BuiltinCandidate); } BuiltinImplConditions::None => {} BuiltinImplConditions::Ambiguous => { @@ -1160,7 +1156,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } fn assemble_candidate_for_tuple( @@ -1171,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); match self_ty.kind() { ty::Tuple(_) => { - candidates.vec.push(BuiltinCandidate { has_nested: false }); + candidates.vec.push(BuiltinCandidate); } ty::Infer(ty::TyVar(_)) => { candidates.ambiguous = true; @@ -1215,7 +1211,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty()); match self_ty.skip_binder().kind() { - ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }), + ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate), ty::Bool | ty::Char | ty::Int(_) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a6b77583fdcda..545531f927a95 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -37,13 +37,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidate: SelectionCandidate<'tcx>, ) -> Result, SelectionError<'tcx>> { Ok(match candidate { - SizedCandidate { has_nested } => { - let data = self.confirm_builtin_candidate(obligation, has_nested); + SizedCandidate => { + let data = self.confirm_builtin_candidate(obligation); ImplSource::Builtin(BuiltinImplSource::Misc, data) } - BuiltinCandidate { has_nested } => { - let data = self.confirm_builtin_candidate(obligation, has_nested); + BuiltinCandidate => { + let data = self.confirm_builtin_candidate(obligation); ImplSource::Builtin(BuiltinImplSource::Misc, data) } @@ -249,50 +249,47 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + #[instrument(level = "debug", skip(self), ret)] fn confirm_builtin_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - has_nested: bool, ) -> PredicateObligations<'tcx> { - debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); - + debug!(?obligation, "confirm_builtin_candidate"); let tcx = self.tcx(); - let obligations = if has_nested { - let trait_def = obligation.predicate.def_id(); - let conditions = match tcx.as_lang_item(trait_def) { - Some(LangItem::Sized) => { - self.sizedness_conditions(obligation, SizedTraitKind::Sized) - } - Some(LangItem::MetaSized) => { - self.sizedness_conditions(obligation, SizedTraitKind::MetaSized) - } - Some(LangItem::PointeeSized) => { - bug!("`PointeeSized` is removing during lowering"); - } - Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation), - Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation), - other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"), - }; - let BuiltinImplConditions::Where(types) = conditions else { - bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); - }; - let types = self.infcx.enter_forall_and_leak_universe(types); - - let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); - self.collect_predicates_for_types( - obligation.param_env, - cause, - obligation.recursion_depth + 1, - trait_def, - types, - ) - } else { - PredicateObligations::new() + let trait_def = obligation.predicate.def_id(); + let conditions = match tcx.as_lang_item(trait_def) { + Some(LangItem::Sized) => self.sizedness_conditions(obligation, SizedTraitKind::Sized), + Some(LangItem::MetaSized) => { + self.sizedness_conditions(obligation, SizedTraitKind::MetaSized) + } + Some(LangItem::PointeeSized) => { + bug!("`PointeeSized` is removing during lowering"); + } + Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation), + Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation), + Some( + LangItem::Destruct + | LangItem::DiscriminantKind + | LangItem::FnPtrTrait + | LangItem::PointeeTrait + | LangItem::Tuple + | LangItem::Unpin, + ) => BuiltinImplConditions::Where(ty::Binder::dummy(vec![])), + other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"), }; + let BuiltinImplConditions::Where(types) = conditions else { + bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); + }; + let types = self.infcx.enter_forall_and_leak_universe(types); - debug!(?obligations); - - obligations + let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); + self.collect_predicates_for_types( + obligation.param_env, + cause, + obligation.recursion_depth + 1, + trait_def, + types, + ) } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index af3641c22ed82..c9930c69b32cc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1834,7 +1834,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // We prefer `Sized` candidates over everything. let mut sized_candidates = - candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate { has_nested: _ })); + candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate)); if let Some(sized_candidate) = sized_candidates.next() { // There should only ever be a single sized candidate // as they would otherwise overlap. @@ -1986,8 +1986,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // Don't use impl candidates which overlap with other candidates. // This should pretty much only ever happen with malformed impls. if candidates.iter().all(|c| match c.candidate { - SizedCandidate { has_nested: _ } - | BuiltinCandidate { has_nested: _ } + SizedCandidate + | BuiltinCandidate | TransmutabilityCandidate | AutoImplCandidate | ClosureCandidate { .. }