From 82c1c877ef2beb2b5911c337f5ffbe9c03294da1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Jun 2026 13:59:11 +0200 Subject: [PATCH 1/2] Eagerly decide whether relaxed bounds are allowed or not --- compiler/rustc_ast_lowering/src/item.rs | 11 ++++++++--- compiler/rustc_ast_lowering/src/lib.rs | 21 ++++++--------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 70f55d67c7a16..5fa614841a513 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1986,7 +1986,7 @@ impl<'hir> LoweringContext<'_, 'hir> { bounds: &[GenericBound], colon_span: Option, parent_span: Span, - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, itctx: ImplTraitContext, origin: PredicateOrigin, ) -> Option> { @@ -2061,8 +2061,13 @@ impl<'hir> LoweringContext<'_, 'hir> { bounded_ty, bounds, }) => { - let rbp = if bound_generic_params.is_empty() { - RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params) + let rbp = if bound_generic_params.is_empty() + && let Some(res) = + self.get_partial_res(bounded_ty.id).and_then(|r| r.full_res()) + && let Res::Def(DefKind::TyParam, def_id) = res + && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id()) + { + RelaxedBoundPolicy::Allowed } else { RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope) }; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4045f08c053ed..95d3ab7a5c5a2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -318,9 +318,8 @@ impl<'tcx> ResolverAstLowering<'tcx> { /// Relaxed bounds should only be allowed in places where we later /// (namely during HIR ty lowering) perform *sized elaboration*. #[derive(Clone, Copy, Debug)] -enum RelaxedBoundPolicy<'a> { +enum RelaxedBoundPolicy { Allowed, - AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]), Forbidden(RelaxedBoundForbiddenReason), } @@ -1955,7 +1954,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_param_bound( &mut self, tpb: &GenericBound, - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { @@ -2193,7 +2192,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_poly_trait_ref( &mut self, PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef, - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, itctx: ImplTraitContext, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = @@ -2217,7 +2216,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &self, trait_ref: hir::TraitRef<'_>, span: Span, - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, ) { // Even though feature `more_maybe_bounds` enables the user to relax all default bounds // other than `Sized` in a lot more positions (thereby bypassing the given policy), we don't @@ -2230,14 +2229,6 @@ impl<'hir> LoweringContext<'_, 'hir> { match rbp { RelaxedBoundPolicy::Allowed => return, - RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => { - if let Some(res) = self.get_partial_res(id).and_then(|r| r.full_res()) - && let Res::Def(DefKind::TyParam, def_id) = res - && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id()) - { - return; - } - } RelaxedBoundPolicy::Forbidden(reason) => { let gate = |context, subject| { let extended = self.tcx.features().more_maybe_bounds(); @@ -2299,7 +2290,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_param_bounds( &mut self, bounds: &[GenericBound], - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, itctx: ImplTraitContext, ) -> hir::GenericBounds<'hir> { self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx)) @@ -2308,7 +2299,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_param_bounds_mut( &mut self, bounds: &[GenericBound], - rbp: RelaxedBoundPolicy<'_>, + rbp: RelaxedBoundPolicy, itctx: ImplTraitContext, ) -> impl Iterator> { bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx)) From 876d5f376f83cfe36c4f3025ff85f8d9aae2e843 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Jun 2026 17:20:22 +0200 Subject: [PATCH 2/2] Rename and document a relaxed bound reason --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5fa614841a513..784d82aab391f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2069,7 +2069,7 @@ impl<'hir> LoweringContext<'_, 'hir> { { RelaxedBoundPolicy::Allowed } else { - RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope) + RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::WhereBound) }; hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params: self.lower_generic_params( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 95d3ab7a5c5a2..72b1d0642001d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -329,7 +329,9 @@ enum RelaxedBoundForbiddenReason { SuperTrait, TraitAlias, AssocTyBounds, - LateBoundVarsInScope, + /// We do not allow where bounds doing relaxed bounds, + /// except if it's for generic parameters of the current item. + WhereBound, } /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, @@ -2268,7 +2270,7 @@ impl<'hir> LoweringContext<'_, 'hir> { return; } RelaxedBoundForbiddenReason::AssocTyBounds - | RelaxedBoundForbiddenReason::LateBoundVarsInScope => {} + | RelaxedBoundForbiddenReason::WhereBound => {} }; } }