about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2022-02-05 15:48:02 +0100
committerCamille GILLOT <gillot.camille@gmail.com>2022-04-30 13:51:49 +0200
commit05b29f9a9295caf71fedfc24e6d7062bba434171 (patch)
tree8c94ee91cac59af0af3d8fd0027c8a70f7c1d6c2
parent71b4e2d852be70174579e7e5a96644418348a7da (diff)
downloadrust-05b29f9a9295caf71fedfc24e6d7062bba434171.tar.gz
rust-05b29f9a9295caf71fedfc24e6d7062bba434171.zip
Inline WhereClause into Generics.
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs26
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs6
-rw-r--r--compiler/rustc_hir/src/hir.rs30
-rw-r--r--compiler/rustc_hir/src/intravisit.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs30
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs14
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs37
-rw-r--r--compiler/rustc_middle/src/ty/error.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs4
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs5
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs5
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs7
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs14
-rw-r--r--compiler/rustc_typeck/src/collect.rs6
-rw-r--r--compiler/rustc_typeck/src/lib.rs4
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs9
24 files changed, 98 insertions, 139 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 7fc53d264a6..764eb4eb8ba 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1338,9 +1338,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
+        let predicates = self.arena.alloc_from_iter(
+            generics
+                .where_clause
+                .predicates
+                .iter()
+                .map(|predicate| self.lower_where_predicate(predicate)),
+        );
+
         GenericsCtor {
             params: self.lower_generic_params_mut(&generics.params, itctx).collect(),
-            where_clause: self.lower_where_clause(&generics.where_clause),
+            predicates,
+            where_clause_span: self.lower_span(generics.where_clause.span),
             span: self.lower_span(generics.span),
         }
     }
@@ -1354,15 +1363,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         generics_ctor.into_generics(self.arena)
     }
 
-    fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
-        hir::WhereClause {
-            predicates: self.arena.alloc_from_iter(
-                wc.predicates.iter().map(|predicate| self.lower_where_predicate(predicate)),
-            ),
-            span: self.lower_span(wc.span),
-        }
-    }
-
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
         match *pred {
             WherePredicate::BoundPredicate(WhereBoundPredicate {
@@ -1414,7 +1414,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
 /// Helper struct for delayed construction of Generics.
 pub(super) struct GenericsCtor<'hir> {
     pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
-    where_clause: hir::WhereClause<'hir>,
+    predicates: &'hir [hir::WherePredicate<'hir>],
+    where_clause_span: Span,
     span: Span,
 }
 
@@ -1422,7 +1423,8 @@ impl<'hir> GenericsCtor<'hir> {
     pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> {
         arena.alloc(hir::Generics {
             params: arena.alloc_from_iter(self.params),
-            where_clause: self.where_clause,
+            predicates: self.predicates,
+            where_clause_span: self.where_clause_span,
             span: self.span,
         })
     }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a5e12408087..6acd8fcc5ce 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1385,7 +1385,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             let opaque_ty_item = hir::OpaqueTy {
                 generics: self.arena.alloc(hir::Generics {
                     params: lifetime_defs,
-                    where_clause: hir::WhereClause { predicates: &[], span: lctx.lower_span(span) },
+                    predicates: &[],
+                    where_clause_span: lctx.lower_span(span),
                     span: lctx.lower_span(span),
                 }),
                 bounds: hir_bounds,
@@ -1717,7 +1718,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             let opaque_ty_item = hir::OpaqueTy {
                 generics: this.arena.alloc(hir::Generics {
                     params: generic_params,
-                    where_clause: hir::WhereClause { predicates: &[], span: this.lower_span(span) },
+                    predicates: &[],
+                    where_clause_span: this.lower_span(span),
                     span: this.lower_span(span),
                 }),
                 bounds: arena_vec![this; future_bound],
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index b723312f094..e34f9e8ca6f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -567,17 +567,15 @@ pub struct GenericParamCount {
 #[derive(Debug, HashStable_Generic)]
 pub struct Generics<'hir> {
     pub params: &'hir [GenericParam<'hir>],
-    pub where_clause: WhereClause<'hir>,
+    pub predicates: &'hir [WherePredicate<'hir>],
+    pub where_clause_span: Span,
     pub span: Span,
 }
 
 impl<'hir> Generics<'hir> {
     pub const fn empty() -> &'hir Generics<'hir> {
-        const NOPE: Generics<'_> = Generics {
-            params: &[],
-            where_clause: WhereClause { predicates: &[], span: DUMMY_SP },
-            span: DUMMY_SP,
-        };
+        const NOPE: Generics<'_> =
+            Generics { params: &[], predicates: &[], where_clause_span: DUMMY_SP, span: DUMMY_SP };
         &NOPE
     }
 
@@ -597,30 +595,20 @@ impl<'hir> Generics<'hir> {
             self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
         }
     }
-}
 
-/// A where-clause in a definition.
-#[derive(Debug, HashStable_Generic)]
-pub struct WhereClause<'hir> {
-    pub predicates: &'hir [WherePredicate<'hir>],
-    // Only valid if predicates aren't empty.
-    pub span: Span,
-}
-
-impl WhereClause<'_> {
-    pub fn span(&self) -> Option<Span> {
-        if self.predicates.is_empty() { None } else { Some(self.span) }
+    pub fn where_clause_span(&self) -> Option<Span> {
+        if self.predicates.is_empty() { None } else { Some(self.where_clause_span) }
     }
 
-    /// The `WhereClause` under normal circumstances points at either the predicates or the empty
+    /// The `where_span` under normal circumstances points at either the predicates or the empty
     /// space where the `where` clause should be. Only of use for diagnostic suggestions.
     pub fn span_for_predicates_or_empty_place(&self) -> Span {
-        self.span
+        self.where_clause_span
     }
 
     /// `Span` where further predicates would be suggested, accounting for trailing commas, like
     ///  in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
-    pub fn tail_span_for_suggestion(&self) -> Span {
+    pub fn tail_span_for_predicate_suggestion(&self) -> Span {
         let end = self.span_for_predicates_or_empty_place().shrink_to_hi();
         self.predicates.last().map_or(end, |p| p.span()).shrink_to_hi().to(end)
     }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 002fa607416..85ef54f8890 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -908,7 +908,7 @@ pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v Ano
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
     walk_list!(visitor, visit_generic_param, generics.params);
-    walk_list!(visitor, visit_where_predicate, generics.where_clause.predicates);
+    walk_list!(visitor, visit_where_predicate, generics.predicates);
 }
 
 pub fn walk_where_predicate<'v, V: Visitor<'v>>(
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 3978579c60b..375a96b1519 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -445,7 +445,7 @@ impl<'a> State<'a> {
         if let Some(bounds) = bounds {
             self.print_bounds(":", bounds);
         }
-        self.print_where_clause(&generics.where_clause);
+        self.print_where_clause(generics);
         if let Some(ty) = ty {
             self.space();
             self.word_space("=");
@@ -465,7 +465,7 @@ impl<'a> State<'a> {
         self.print_generic_params(&generics.params);
         self.end(); // end the inner ibox
 
-        self.print_where_clause(&generics.where_clause);
+        self.print_where_clause(generics);
         self.space();
         inner(self);
         self.word(";");
@@ -650,7 +650,7 @@ impl<'a> State<'a> {
                 }
 
                 self.print_type(&self_ty);
-                self.print_where_clause(&generics.where_clause);
+                self.print_where_clause(generics);
 
                 self.space();
                 self.bopen();
@@ -678,7 +678,7 @@ impl<'a> State<'a> {
                     }
                 }
                 self.print_bounds(":", real_bounds);
-                self.print_where_clause(&generics.where_clause);
+                self.print_where_clause(generics);
                 self.word(" ");
                 self.bopen();
                 for trait_item in trait_items {
@@ -703,7 +703,7 @@ impl<'a> State<'a> {
                 }
                 self.nbsp();
                 self.print_bounds("=", real_bounds);
-                self.print_where_clause(&generics.where_clause);
+                self.print_where_clause(generics);
                 self.word(";");
                 self.end(); // end inner head-block
                 self.end(); // end outer head-block
@@ -739,7 +739,7 @@ impl<'a> State<'a> {
         self.head("enum");
         self.print_name(name);
         self.print_generic_params(&generics.params);
-        self.print_where_clause(&generics.where_clause);
+        self.print_where_clause(generics);
         self.space();
         self.print_variants(&enum_definition.variants, span)
     }
@@ -787,7 +787,7 @@ impl<'a> State<'a> {
                     });
                     self.pclose();
                 }
-                self.print_where_clause(&generics.where_clause);
+                self.print_where_clause(generics);
                 if print_finalizer {
                     self.word(";");
                 }
@@ -795,7 +795,7 @@ impl<'a> State<'a> {
                 self.end() // close the outer-box
             }
             hir::VariantData::Struct(..) => {
-                self.print_where_clause(&generics.where_clause);
+                self.print_where_clause(generics);
                 self.nbsp();
                 self.bopen();
                 self.hardbreak_if_not_bol();
@@ -1995,7 +1995,7 @@ impl<'a> State<'a> {
         self.pclose();
 
         self.print_fn_output(decl);
-        self.print_where_clause(&generics.where_clause)
+        self.print_where_clause(generics)
     }
 
     fn print_closure_params(&mut self, decl: &hir::FnDecl<'_>, body_id: hir::BodyId) {
@@ -2133,15 +2133,15 @@ impl<'a> State<'a> {
         self.print_ident(lifetime.name.ident())
     }
 
-    pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause<'_>) {
-        if where_clause.predicates.is_empty() {
+    pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {
+        if generics.predicates.is_empty() {
             return;
         }
 
         self.space();
         self.word_space("where");
 
-        for (i, predicate) in where_clause.predicates.iter().enumerate() {
+        for (i, predicate) in generics.predicates.iter().enumerate() {
             if i != 0 {
                 self.word_space(",");
             }
@@ -2236,11 +2236,7 @@ impl<'a> State<'a> {
     ) {
         self.ibox(INDENT_UNIT);
         self.print_formal_generic_params(generic_params);
-        let generics = hir::Generics {
-            params: &[],
-            where_clause: hir::WhereClause { predicates: &[], span: rustc_span::DUMMY_SP },
-            span: rustc_span::DUMMY_SP,
-        };
+        let generics = hir::Generics::empty();
         self.print_fn(
             decl,
             hir::FnHeader {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 14555ad9255..8f363cbe0de 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2543,11 +2543,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 let pred = format!("{}: {}", bound_kind, sub);
                 let suggestion = format!(
                     "{} {}",
-                    if !generics.where_clause.predicates.is_empty() { "," } else { " where" },
+                    if !generics.predicates.is_empty() { "," } else { " where" },
                     pred,
                 );
                 err.span_suggestion(
-                    generics.where_clause.tail_span_for_suggestion(),
+                    generics.tail_span_for_predicate_suggestion(),
                     "consider adding a where clause",
                     suggestion,
                     Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index baea3e8285a..cbdcf013522 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -372,8 +372,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         .hir()
                         .get_generics(impl_item_def_id)
                         .unwrap()
-                        .where_clause
-                        .tail_span_for_suggestion();
+                        .where_clause_span
+                        .shrink_to_hi();
 
                     let suggestion = format!(
                         "{} {}",
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index e097ab9d7fd..4c26a515bf6 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1519,20 +1519,19 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
         }
         let mut suggested_changing_assoc_types = false;
         // There must not be a where clause
-        if !type_alias_generics.where_clause.predicates.is_empty() {
+        if !type_alias_generics.predicates.is_empty() {
             cx.lint(
                 TYPE_ALIAS_BOUNDS,
                 |lint| {
                     let mut err = lint.build("where clauses are not enforced in type aliases");
                     let spans: Vec<_> = type_alias_generics
-                        .where_clause
                         .predicates
                         .iter()
                         .map(|pred| pred.span())
                         .collect();
                     err.set_span(spans);
                     err.span_suggestion(
-                        type_alias_generics.where_clause.span_for_predicates_or_empty_place(),
+                        type_alias_generics.span_for_predicates_or_empty_place(),
                         "the clause will not be checked when the type alias is used, and should be removed",
                         String::new(),
                         Applicability::MachineApplicable,
@@ -2245,8 +2244,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
 
             let mut where_lint_spans = Vec::new();
             let mut dropped_predicate_count = 0;
-            let num_predicates = hir_generics.where_clause.predicates.len();
-            for (i, where_predicate) in hir_generics.where_clause.predicates.iter().enumerate() {
+            let num_predicates = hir_generics.predicates.len();
+            for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
                 let (relevant_lifetimes, bounds, span) = match where_predicate {
                     hir::WherePredicate::RegionPredicate(predicate) => {
                         if let Some(Region::EarlyBound(index, ..)) =
@@ -2303,7 +2302,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                 // If all the bounds on a predicate were inferable and there are
                 // further predicates, we want to eat the trailing comma.
                 if drop_predicate && i + 1 < num_predicates {
-                    let next_predicate_span = hir_generics.where_clause.predicates[i + 1].span();
+                    let next_predicate_span = hir_generics.predicates[i + 1].span();
                     where_lint_spans.push(span.to(next_predicate_span.shrink_to_lo()));
                 } else {
                     where_lint_spans.extend(self.consolidate_outlives_bound_spans(
@@ -2318,8 +2317,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
             // (including the `where`)
             if num_predicates > 0 && dropped_predicate_count == num_predicates {
                 let where_span = hir_generics
-                    .where_clause
-                    .span()
+                    .where_clause_span()
                     .expect("span of (nonempty) where clause should exist");
                 // Extend the where clause back to the closing `>` of the
                 // generics, except for tuple struct, which have the `where`
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 8c8a2650fd6..5203fb51882 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -156,13 +156,13 @@ pub fn suggest_arbitrary_trait_bound(
         _ => {}
     }
     // Suggest a where clause bound for a non-type parameter.
-    let (action, prefix) = if generics.where_clause.predicates.is_empty() {
+    let (action, prefix) = if generics.predicates.is_empty() {
         ("introducing a", " where ")
     } else {
         ("extending the", ", ")
     };
     err.span_suggestion_verbose(
-        generics.where_clause.tail_span_for_suggestion(),
+        generics.tail_span_for_predicate_suggestion(),
         &format!(
             "consider {} `where` bound, but there might be an alternative better way to express \
              this requirement",
@@ -192,7 +192,7 @@ fn suggest_removing_unsized_bound(
     // See if there's a `?Sized` bound that can be removed to suggest that.
     // First look at the `where` clause because we can have `where T: ?Sized`,
     // then look at params.
-    for (where_pos, predicate) in generics.where_clause.predicates.iter().enumerate() {
+    for (where_pos, predicate) in generics.predicates.iter().enumerate() {
         match predicate {
             WherePredicate::BoundPredicate(WhereBoundPredicate {
                 bounded_ty:
@@ -218,27 +218,18 @@ fn suggest_removing_unsized_bound(
                             if poly.trait_ref.trait_def_id() == def_id => {}
                         _ => continue,
                     }
-                    let sp = match (
-                        bounds.len(),
-                        pos,
-                        generics.where_clause.predicates.len(),
-                        where_pos,
-                    ) {
+                    let sp = match (bounds.len(), pos, generics.predicates.len(), where_pos) {
                         // where T: ?Sized
                         // ^^^^^^^^^^^^^^^
-                        (1, _, 1, _) => generics.where_clause.span,
+                        (1, _, 1, _) => generics.where_clause_span,
                         // where Foo: Bar, T: ?Sized,
                         //               ^^^^^^^^^^^
-                        (1, _, len, pos) if pos == len - 1 => generics.where_clause.predicates
-                            [pos - 1]
-                            .span()
-                            .shrink_to_hi()
-                            .to(*span),
+                        (1, _, len, pos) if pos == len - 1 => {
+                            generics.predicates[pos - 1].span().shrink_to_hi().to(*span)
+                        }
                         // where T: ?Sized, Foo: Bar,
                         //       ^^^^^^^^^^^
-                        (1, _, _, pos) => {
-                            span.until(generics.where_clause.predicates[pos + 1].span())
-                        }
+                        (1, _, _, pos) => span.until(generics.predicates[pos + 1].span()),
                         // where T: ?Sized + Bar, Foo: Bar,
                         //          ^^^^^^^^^
                         (_, 0, _, _) => bound.span().to(bounds[1].span().shrink_to_lo()),
@@ -381,7 +372,7 @@ pub fn suggest_constraining_type_params<'a>(
             continue;
         }
 
-        if generics.where_clause.predicates.is_empty()
+        if generics.predicates.is_empty()
         // Given `trait Base<T = String>: Super<T>` where `T: Copy`, suggest restricting in the
         // `where` clause instead of `trait Base<T: Copy = String>: Super<T>`.
         && !matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. })
@@ -475,12 +466,12 @@ pub fn suggest_constraining_type_params<'a>(
             //                     - insert: `where T: Zar`
 
             if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. })
-                && generics.where_clause.predicates.len() == 0
+                && generics.predicates.len() == 0
             {
                 // Suggest a bound, but there is no existing `where` clause *and* the type param has a
                 // default (`<T=Foo>`), so we suggest adding `where T: Bar`.
                 suggestions.push((
-                    generics.where_clause.tail_span_for_suggestion(),
+                    generics.tail_span_for_predicate_suggestion(),
                     format!(" where {}: {}", param_name, constraint),
                     SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name },
                 ));
@@ -488,7 +479,7 @@ pub fn suggest_constraining_type_params<'a>(
                 let mut param_spans = Vec::new();
                 let mut non_empty = false;
 
-                for predicate in generics.where_clause.predicates {
+                for predicate in generics.predicates {
                     if let WherePredicate::BoundPredicate(WhereBoundPredicate {
                         span,
                         bounded_ty,
@@ -512,7 +503,7 @@ pub fn suggest_constraining_type_params<'a>(
                     [&param_span] => suggest_restrict(param_span.shrink_to_hi(), non_empty),
                     _ => {
                         suggestions.push((
-                            generics.where_clause.tail_span_for_suggestion(),
+                            generics.tail_span_for_predicate_suggestion(),
                             constraints
                                 .iter()
                                 .map(|&(constraint, _)| format!(", {}: {}", param_name, constraint))
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 07878defa8c..5c5d0a46534 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -605,7 +605,7 @@ impl<T> Trait<T> for X {
 
                 // First look in the `where` clause, as this might be
                 // `fn foo<T>(x: T) where T: Trait`.
-                for predicate in hir_generics.where_clause.predicates {
+                for predicate in hir_generics.predicates {
                     if let hir::WherePredicate::BoundPredicate(pred) = predicate {
                         if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) =
                             pred.bounded_ty.kind
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 5f9a0357557..5c396c2b7ea 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1590,7 +1590,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                 self.check_generic_bound(bound);
             }
         }
-        for predicate in generics.where_clause.predicates {
+        for predicate in generics.predicates {
             match predicate {
                 hir::WherePredicate::BoundPredicate(bound_pred) => {
                     for bound in bound_pred.bounds.iter() {
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 35a40a0a321..f7e94dd10f7 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1342,7 +1342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     }
                 }
             }
-            for predicate in generics.where_clause.predicates {
+            for predicate in generics.predicates {
                 match predicate {
                     &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                         ref bounded_ty,
@@ -1717,7 +1717,7 @@ fn object_lifetime_defaults_for_item<'tcx>(
             add_bounds(&mut set, &param.bounds);
 
             let param_def_id = tcx.hir().local_def_id(param.hir_id);
-            for predicate in generics.where_clause.predicates {
+            for predicate in generics.predicates {
                 // Look for `type: ...` where clauses.
                 let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
 
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 6681ea9d299..a27ac75d584 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -1281,7 +1281,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 }
             }
         }
-        for pred in generics.where_clause.predicates {
+        for pred in generics.predicates {
             if let hir::WherePredicate::BoundPredicate(ref wbp) = *pred {
                 self.process_bounds(wbp.bounds);
                 self.visit_ty(wbp.bounded_ty);
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 082402a38e3..a3e8be44c7a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2419,7 +2419,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         };
         let sized_trait = self.tcx.lang_items().sized_trait();
         debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params);
-        debug!("maybe_suggest_unsized_generics: generics.where_clause={:?}", generics.where_clause);
+        debug!("maybe_suggest_unsized_generics: generics.predicates={:?}", generics.predicates);
         let param = generics.params.iter().filter(|param| param.span == span).find(|param| {
             // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit
             // `Sized` bound is there intentionally and we don't need to suggest relaxing it.
@@ -2432,7 +2432,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
             return;
         };
         let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id();
-        let preds = generics.where_clause.predicates.iter();
+        let preds = generics.predicates.iter();
         let explicitly_sized = preds
             .filter_map(|pred| match pred {
                 hir::WherePredicate::BoundPredicate(bp) => Some(bp),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 187df6f7de0..9900cdd3eba 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -319,12 +319,8 @@ pub trait InferCtxtExt<'tcx> {
 
 fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
     (
-        generics.where_clause.tail_span_for_suggestion(),
-        format!(
-            "{} {}",
-            if !generics.where_clause.predicates.is_empty() { "," } else { " where" },
-            pred,
-        ),
+        generics.tail_span_for_predicate_suggestion(),
+        format!("{} {}", if !generics.predicates.is_empty() { "," } else { " where" }, pred,),
     )
 }
 
@@ -346,7 +342,7 @@ fn suggest_restriction<'tcx>(
     //              -  ^^^^^^^^^ GenericBounds
     //              |
     //              &Ident
-    let span = generics.where_clause.span_for_predicates_or_empty_place();
+    let span = generics.span_for_predicates_or_empty_place();
     if span.from_expansion() || span.desugaring_kind().is_some() {
         return;
     }
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 84958136cac..b39310d1294 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -221,7 +221,6 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
                 ..
             }) => Some(
                 generics
-                    .where_clause
                     .predicates
                     .iter()
                     .filter_map(|pred| {
@@ -399,8 +398,8 @@ fn virtual_call_violation_for_method<'tcx>(
         // We'll attempt to provide a structured suggestion for `Self: Sized`.
         let sugg =
             tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map(
-                |generics| match generics.where_clause.predicates {
-                    [] => (" where Self: Sized", generics.where_clause.span),
+                |generics| match generics.predicates {
+                    [] => (" where Self: Sized", generics.where_clause_span),
                     [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()),
                 },
             );
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index a92c288cac9..c42db45854f 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -599,7 +599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             kind:
                 hir::ItemKind::Fn(
                     hir::FnSig { decl: hir::FnDecl { inputs: fn_parameters, output: fn_return, .. }, .. },
-                    hir::Generics { params, where_clause, .. },
+                    hir::Generics { params, predicates, .. },
                     _body_id,
                 ),
             ..
@@ -608,8 +608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some(expected_generic_param) = params.get(expected_ty_as_param.index as usize) else { return };
 
         // get all where BoundPredicates here, because they are used in to cases below
-        let where_predicates = where_clause
-            .predicates
+        let where_predicates = predicates
             .iter()
             .filter_map(|p| match p {
                 WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 80c31355fe7..727352c395b 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -533,12 +533,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 };
                                 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
                                     if let Some(g) = kind.generics() {
-                                        let key = match g.where_clause.predicates {
+                                        let key = match g.predicates {
                                             [.., pred] => (pred.span().shrink_to_hi(), false),
-                                            [] => (
-                                                g.where_clause.span_for_predicates_or_empty_place(),
-                                                true,
-                                            ),
+                                            [] => (g.span_for_predicates_or_empty_place(), true),
                                         };
                                         type_params
                                             .entry(key)
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 4e3e32670e9..ce70650d4ac 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -420,15 +420,11 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
 
             let suggestion = format!(
                 "{} {}",
-                if !gat_item_hir.generics.where_clause.predicates.is_empty() {
-                    ","
-                } else {
-                    " where"
-                },
+                if !gat_item_hir.generics.predicates.is_empty() { "," } else { " where" },
                 unsatisfied_bounds.join(", "),
             );
             err.span_suggestion(
-                gat_item_hir.generics.where_clause.tail_span_for_suggestion(),
+                gat_item_hir.generics.tail_span_for_predicate_suggestion(),
                 &format!("add the required where clause{plural}"),
                 suggestion,
                 Applicability::MachineApplicable,
@@ -1733,7 +1729,6 @@ fn check_variances_for_type_defn<'tcx>(
     let explicitly_bounded_params = Lazy::new(|| {
         let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
         hir_generics
-            .where_clause
             .predicates
             .iter()
             .filter_map(|predicate| match predicate {
@@ -1819,13 +1814,12 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirI
 
             // only use the span of the predicate clause (#90869)
 
-            if let Some(hir::Generics { where_clause, .. }) =
+            if let Some(hir::Generics { predicates, .. }) =
                 hir_node.and_then(|node| node.generics())
             {
                 let obligation_span = obligation.cause.span(fcx.tcx);
 
-                span = where_clause
-                    .predicates
+                span = predicates
                     .iter()
                     // There seems to be no better way to find out which predicate we are in
                     .find(|pred| pred.span().contains(obligation_span))
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index e36eebcf931..fd63fd1eb7d 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -700,7 +700,6 @@ impl<'tcx> ItemCtxt<'tcx> {
 
         let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
         let from_where_clauses = ast_generics
-            .where_clause
             .predicates
             .iter()
             .filter_map(|wp| match *wp {
@@ -2343,7 +2342,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                     &icx,
                     &mut bounds,
                     param.bounds,
-                    Some((param.hir_id, ast_generics.where_clause.predicates)),
+                    Some((param.hir_id, ast_generics.predicates)),
                     param.span,
                 );
                 predicates.extend(bounds.predicates(tcx, param_ty));
@@ -2357,8 +2356,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
     }
 
     // Add in the bounds that appear in the where-clause.
-    let where_clause = &ast_generics.where_clause;
-    for predicate in where_clause.predicates {
+    for predicate in ast_generics.predicates {
         match predicate {
             hir::WherePredicate::BoundPredicate(bound_pred) => {
                 let ty = icx.to_ty(bound_pred.bounded_ty);
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 9fb9652b849..03b3d68d59f 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -213,7 +213,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
         match tcx.hir().find(hir_id) {
             Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, ref generics, _), .. })) => {
-                generics.where_clause.span()
+                generics.where_clause_span()
             }
             _ => {
                 span_bug!(tcx.def_span(def_id), "main has a non-function type");
@@ -408,7 +408,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
                         .emit();
                         error = true;
                     }
-                    if let Some(sp) = generics.where_clause.span() {
+                    if let Some(sp) = generics.where_clause_span() {
                         struct_span_err!(
                             tcx.sess,
                             sp,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 476a89523a5..258880ac928 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -545,7 +545,7 @@ impl Clean<Generics> for hir::Generics<'_> {
 
         let mut generics = Generics {
             params,
-            where_predicates: self.where_clause.predicates.iter().map(|x| x.clean(cx)).collect(),
+            where_predicates: self.predicates.iter().map(|x| x.clean(cx)).collect(),
         };
 
         // Some duplicates are generated for ?Sized bounds between type params and where
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index b09c23f31e9..4ec7c2362f0 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -8,7 +8,7 @@ use rustc_hir::FnRetTy::Return;
 use rustc_hir::{
     BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem,
     ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier,
-    TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate,
+    TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -130,7 +130,7 @@ fn check_fn_inner<'tcx>(
     span: Span,
     report_extra_lifetimes: bool,
 ) {
-    if span.from_expansion() || has_where_lifetimes(cx, &generics.where_clause) {
+    if span.from_expansion() || has_where_lifetimes(cx, generics) {
         return;
     }
 
@@ -445,8 +445,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
 
 /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to
 /// reason about elision.
-fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool {
-    for predicate in where_clause.predicates {
+fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {
+    for predicate in generics.predicates {
         match *predicate {
             WherePredicate::RegionPredicate(..) => return true,
             WherePredicate::BoundPredicate(ref pred) => {
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 43e0132a7ec..c388d2854cc 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -90,10 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
-        let Generics { where_clause, .. } = &item.generics;
         let mut self_bounds_map = FxHashMap::default();
 
-        for predicate in where_clause.predicates {
+        for predicate in item.generics.predicates {
             if_chain! {
                 if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
                 if !bound_predicate.span.from_expansion();
@@ -166,7 +165,7 @@ impl TraitBounds {
         }
         let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
         let mut applicability = Applicability::MaybeIncorrect;
-        for bound in gen.where_clause.predicates {
+        for bound in gen.predicates {
             if_chain! {
                 if let WherePredicate::BoundPredicate(ref p) = bound;
                 if p.bounds.len() as u64 <= self.max_trait_bounds;
@@ -216,7 +215,7 @@ impl TraitBounds {
 }
 
 fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
-    if gen.span.from_expansion() || gen.params.is_empty() || gen.where_clause.predicates.is_empty() {
+    if gen.span.from_expansion() || gen.params.is_empty() || gen.predicates.is_empty() {
         return;
     }
 
@@ -232,7 +231,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
         }
     }
 
-    for predicate in gen.where_clause.predicates {
+    for predicate in gen.predicates {
         if_chain! {
             if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
             if !bound_predicate.span.from_expansion();