1
Fork 0

Inline WhereClause into Generics.

This commit is contained in:
Camille GILLOT 2022-02-05 15:48:02 +01:00
parent 71b4e2d852
commit 05b29f9a92
24 changed files with 98 additions and 139 deletions

View file

@ -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 { GenericsCtor {
params: self.lower_generic_params_mut(&generics.params, itctx).collect(), 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), span: self.lower_span(generics.span),
} }
} }
@ -1354,15 +1363,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics_ctor.into_generics(self.arena) 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> { fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
match *pred { match *pred {
WherePredicate::BoundPredicate(WhereBoundPredicate { WherePredicate::BoundPredicate(WhereBoundPredicate {
@ -1414,7 +1414,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// Helper struct for delayed construction of Generics. /// Helper struct for delayed construction of Generics.
pub(super) struct GenericsCtor<'hir> { pub(super) struct GenericsCtor<'hir> {
pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>, pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
where_clause: hir::WhereClause<'hir>, predicates: &'hir [hir::WherePredicate<'hir>],
where_clause_span: Span,
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> { pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> {
arena.alloc(hir::Generics { arena.alloc(hir::Generics {
params: arena.alloc_from_iter(self.params), 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, span: self.span,
}) })
} }

View file

@ -1385,7 +1385,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let opaque_ty_item = hir::OpaqueTy { let opaque_ty_item = hir::OpaqueTy {
generics: self.arena.alloc(hir::Generics { generics: self.arena.alloc(hir::Generics {
params: lifetime_defs, 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), span: lctx.lower_span(span),
}), }),
bounds: hir_bounds, bounds: hir_bounds,
@ -1717,7 +1718,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let opaque_ty_item = hir::OpaqueTy { let opaque_ty_item = hir::OpaqueTy {
generics: this.arena.alloc(hir::Generics { generics: this.arena.alloc(hir::Generics {
params: generic_params, 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), span: this.lower_span(span),
}), }),
bounds: arena_vec![this; future_bound], bounds: arena_vec![this; future_bound],

View file

@ -567,17 +567,15 @@ pub struct GenericParamCount {
#[derive(Debug, HashStable_Generic)] #[derive(Debug, HashStable_Generic)]
pub struct Generics<'hir> { pub struct Generics<'hir> {
pub params: &'hir [GenericParam<'hir>], pub params: &'hir [GenericParam<'hir>],
pub where_clause: WhereClause<'hir>, pub predicates: &'hir [WherePredicate<'hir>],
pub where_clause_span: Span,
pub span: Span, pub span: Span,
} }
impl<'hir> Generics<'hir> { impl<'hir> Generics<'hir> {
pub const fn empty() -> &'hir Generics<'hir> { pub const fn empty() -> &'hir Generics<'hir> {
const NOPE: Generics<'_> = Generics { const NOPE: Generics<'_> =
params: &[], Generics { params: &[], predicates: &[], where_clause_span: DUMMY_SP, span: DUMMY_SP };
where_clause: WhereClause { predicates: &[], span: DUMMY_SP },
span: DUMMY_SP,
};
&NOPE &NOPE
} }
@ -597,30 +595,20 @@ impl<'hir> Generics<'hir> {
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into() self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
} }
} }
}
/// A where-clause in a definition. pub fn where_clause_span(&self) -> Option<Span> {
#[derive(Debug, HashStable_Generic)] if self.predicates.is_empty() { None } else { Some(self.where_clause_span) }
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) }
} }
/// 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. /// space where the `where` clause should be. Only of use for diagnostic suggestions.
pub fn span_for_predicates_or_empty_place(&self) -> Span { 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 /// `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. /// 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(); 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) self.predicates.last().map_or(end, |p| p.span()).shrink_to_hi().to(end)
} }

View file

@ -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>) { 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_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>>( pub fn walk_where_predicate<'v, V: Visitor<'v>>(

View file

@ -445,7 +445,7 @@ impl<'a> State<'a> {
if let Some(bounds) = bounds { if let Some(bounds) = bounds {
self.print_bounds(":", bounds); self.print_bounds(":", bounds);
} }
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
if let Some(ty) = ty { if let Some(ty) = ty {
self.space(); self.space();
self.word_space("="); self.word_space("=");
@ -465,7 +465,7 @@ impl<'a> State<'a> {
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.end(); // end the inner ibox self.end(); // end the inner ibox
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.space(); self.space();
inner(self); inner(self);
self.word(";"); self.word(";");
@ -650,7 +650,7 @@ impl<'a> State<'a> {
} }
self.print_type(&self_ty); self.print_type(&self_ty);
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.space(); self.space();
self.bopen(); self.bopen();
@ -678,7 +678,7 @@ impl<'a> State<'a> {
} }
} }
self.print_bounds(":", real_bounds); self.print_bounds(":", real_bounds);
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.word(" "); self.word(" ");
self.bopen(); self.bopen();
for trait_item in trait_items { for trait_item in trait_items {
@ -703,7 +703,7 @@ impl<'a> State<'a> {
} }
self.nbsp(); self.nbsp();
self.print_bounds("=", real_bounds); self.print_bounds("=", real_bounds);
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.word(";"); self.word(";");
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
@ -739,7 +739,7 @@ impl<'a> State<'a> {
self.head("enum"); self.head("enum");
self.print_name(name); self.print_name(name);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.space(); self.space();
self.print_variants(&enum_definition.variants, span) self.print_variants(&enum_definition.variants, span)
} }
@ -787,7 +787,7 @@ impl<'a> State<'a> {
}); });
self.pclose(); self.pclose();
} }
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
if print_finalizer { if print_finalizer {
self.word(";"); self.word(";");
} }
@ -795,7 +795,7 @@ impl<'a> State<'a> {
self.end() // close the outer-box self.end() // close the outer-box
} }
hir::VariantData::Struct(..) => { hir::VariantData::Struct(..) => {
self.print_where_clause(&generics.where_clause); self.print_where_clause(generics);
self.nbsp(); self.nbsp();
self.bopen(); self.bopen();
self.hardbreak_if_not_bol(); self.hardbreak_if_not_bol();
@ -1995,7 +1995,7 @@ impl<'a> State<'a> {
self.pclose(); self.pclose();
self.print_fn_output(decl); 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) { 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()) self.print_ident(lifetime.name.ident())
} }
pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause<'_>) { pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {
if where_clause.predicates.is_empty() { if generics.predicates.is_empty() {
return; return;
} }
self.space(); self.space();
self.word_space("where"); self.word_space("where");
for (i, predicate) in where_clause.predicates.iter().enumerate() { for (i, predicate) in generics.predicates.iter().enumerate() {
if i != 0 { if i != 0 {
self.word_space(","); self.word_space(",");
} }
@ -2236,11 +2236,7 @@ impl<'a> State<'a> {
) { ) {
self.ibox(INDENT_UNIT); self.ibox(INDENT_UNIT);
self.print_formal_generic_params(generic_params); self.print_formal_generic_params(generic_params);
let generics = hir::Generics { let generics = hir::Generics::empty();
params: &[],
where_clause: hir::WhereClause { predicates: &[], span: rustc_span::DUMMY_SP },
span: rustc_span::DUMMY_SP,
};
self.print_fn( self.print_fn(
decl, decl,
hir::FnHeader { hir::FnHeader {

View file

@ -2543,11 +2543,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let pred = format!("{}: {}", bound_kind, sub); let pred = format!("{}: {}", bound_kind, sub);
let suggestion = format!( let suggestion = format!(
"{} {}", "{} {}",
if !generics.where_clause.predicates.is_empty() { "," } else { " where" }, if !generics.predicates.is_empty() { "," } else { " where" },
pred, pred,
); );
err.span_suggestion( err.span_suggestion(
generics.where_clause.tail_span_for_suggestion(), generics.tail_span_for_predicate_suggestion(),
"consider adding a where clause", "consider adding a where clause",
suggestion, suggestion,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,

View file

@ -372,8 +372,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.hir() .hir()
.get_generics(impl_item_def_id) .get_generics(impl_item_def_id)
.unwrap() .unwrap()
.where_clause .where_clause_span
.tail_span_for_suggestion(); .shrink_to_hi();
let suggestion = format!( let suggestion = format!(
"{} {}", "{} {}",

View file

@ -1519,20 +1519,19 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
} }
let mut suggested_changing_assoc_types = false; let mut suggested_changing_assoc_types = false;
// There must not be a where clause // 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( cx.lint(
TYPE_ALIAS_BOUNDS, TYPE_ALIAS_BOUNDS,
|lint| { |lint| {
let mut err = lint.build("where clauses are not enforced in type aliases"); let mut err = lint.build("where clauses are not enforced in type aliases");
let spans: Vec<_> = type_alias_generics let spans: Vec<_> = type_alias_generics
.where_clause
.predicates .predicates
.iter() .iter()
.map(|pred| pred.span()) .map(|pred| pred.span())
.collect(); .collect();
err.set_span(spans); err.set_span(spans);
err.span_suggestion( 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", "the clause will not be checked when the type alias is used, and should be removed",
String::new(), String::new(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
@ -2245,8 +2244,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
let mut where_lint_spans = Vec::new(); let mut where_lint_spans = Vec::new();
let mut dropped_predicate_count = 0; let mut dropped_predicate_count = 0;
let num_predicates = hir_generics.where_clause.predicates.len(); let num_predicates = hir_generics.predicates.len();
for (i, where_predicate) in hir_generics.where_clause.predicates.iter().enumerate() { for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
let (relevant_lifetimes, bounds, span) = match where_predicate { let (relevant_lifetimes, bounds, span) = match where_predicate {
hir::WherePredicate::RegionPredicate(predicate) => { hir::WherePredicate::RegionPredicate(predicate) => {
if let Some(Region::EarlyBound(index, ..)) = 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 // If all the bounds on a predicate were inferable and there are
// further predicates, we want to eat the trailing comma. // further predicates, we want to eat the trailing comma.
if drop_predicate && i + 1 < num_predicates { 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())); where_lint_spans.push(span.to(next_predicate_span.shrink_to_lo()));
} else { } else {
where_lint_spans.extend(self.consolidate_outlives_bound_spans( where_lint_spans.extend(self.consolidate_outlives_bound_spans(
@ -2318,8 +2317,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
// (including the `where`) // (including the `where`)
if num_predicates > 0 && dropped_predicate_count == num_predicates { if num_predicates > 0 && dropped_predicate_count == num_predicates {
let where_span = hir_generics let where_span = hir_generics
.where_clause .where_clause_span()
.span()
.expect("span of (nonempty) where clause should exist"); .expect("span of (nonempty) where clause should exist");
// Extend the where clause back to the closing `>` of the // Extend the where clause back to the closing `>` of the
// generics, except for tuple struct, which have the `where` // generics, except for tuple struct, which have the `where`

View file

@ -156,13 +156,13 @@ pub fn suggest_arbitrary_trait_bound(
_ => {} _ => {}
} }
// Suggest a where clause bound for a non-type parameter. // 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 ") ("introducing a", " where ")
} else { } else {
("extending the", ", ") ("extending the", ", ")
}; };
err.span_suggestion_verbose( err.span_suggestion_verbose(
generics.where_clause.tail_span_for_suggestion(), generics.tail_span_for_predicate_suggestion(),
&format!( &format!(
"consider {} `where` bound, but there might be an alternative better way to express \ "consider {} `where` bound, but there might be an alternative better way to express \
this requirement", 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. // 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`, // First look at the `where` clause because we can have `where T: ?Sized`,
// then look at params. // 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 { match predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate { WherePredicate::BoundPredicate(WhereBoundPredicate {
bounded_ty: bounded_ty:
@ -218,27 +218,18 @@ fn suggest_removing_unsized_bound(
if poly.trait_ref.trait_def_id() == def_id => {} if poly.trait_ref.trait_def_id() == def_id => {}
_ => continue, _ => continue,
} }
let sp = match ( let sp = match (bounds.len(), pos, generics.predicates.len(), where_pos) {
bounds.len(),
pos,
generics.where_clause.predicates.len(),
where_pos,
) {
// where T: ?Sized // where T: ?Sized
// ^^^^^^^^^^^^^^^ // ^^^^^^^^^^^^^^^
(1, _, 1, _) => generics.where_clause.span, (1, _, 1, _) => generics.where_clause_span,
// where Foo: Bar, T: ?Sized, // where Foo: Bar, T: ?Sized,
// ^^^^^^^^^^^ // ^^^^^^^^^^^
(1, _, len, pos) if pos == len - 1 => generics.where_clause.predicates (1, _, len, pos) if pos == len - 1 => {
[pos - 1] generics.predicates[pos - 1].span().shrink_to_hi().to(*span)
.span() }
.shrink_to_hi()
.to(*span),
// where T: ?Sized, Foo: Bar, // where T: ?Sized, Foo: Bar,
// ^^^^^^^^^^^ // ^^^^^^^^^^^
(1, _, _, pos) => { (1, _, _, pos) => span.until(generics.predicates[pos + 1].span()),
span.until(generics.where_clause.predicates[pos + 1].span())
}
// where T: ?Sized + Bar, Foo: Bar, // where T: ?Sized + Bar, Foo: Bar,
// ^^^^^^^^^ // ^^^^^^^^^
(_, 0, _, _) => bound.span().to(bounds[1].span().shrink_to_lo()), (_, 0, _, _) => bound.span().to(bounds[1].span().shrink_to_lo()),
@ -381,7 +372,7 @@ pub fn suggest_constraining_type_params<'a>(
continue; 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 // 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>`. // `where` clause instead of `trait Base<T: Copy = String>: Super<T>`.
&& !matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) && !matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. })
@ -475,12 +466,12 @@ pub fn suggest_constraining_type_params<'a>(
// - insert: `where T: Zar` // - insert: `where T: Zar`
if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) 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 // 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`. // default (`<T=Foo>`), so we suggest adding `where T: Bar`.
suggestions.push(( suggestions.push((
generics.where_clause.tail_span_for_suggestion(), generics.tail_span_for_predicate_suggestion(),
format!(" where {}: {}", param_name, constraint), format!(" where {}: {}", param_name, constraint),
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name }, SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name },
)); ));
@ -488,7 +479,7 @@ pub fn suggest_constraining_type_params<'a>(
let mut param_spans = Vec::new(); let mut param_spans = Vec::new();
let mut non_empty = false; let mut non_empty = false;
for predicate in generics.where_clause.predicates { for predicate in generics.predicates {
if let WherePredicate::BoundPredicate(WhereBoundPredicate { if let WherePredicate::BoundPredicate(WhereBoundPredicate {
span, span,
bounded_ty, bounded_ty,
@ -512,7 +503,7 @@ pub fn suggest_constraining_type_params<'a>(
[&param_span] => suggest_restrict(param_span.shrink_to_hi(), non_empty), [&param_span] => suggest_restrict(param_span.shrink_to_hi(), non_empty),
_ => { _ => {
suggestions.push(( suggestions.push((
generics.where_clause.tail_span_for_suggestion(), generics.tail_span_for_predicate_suggestion(),
constraints constraints
.iter() .iter()
.map(|&(constraint, _)| format!(", {}: {}", param_name, constraint)) .map(|&(constraint, _)| format!(", {}: {}", param_name, constraint))

View file

@ -605,7 +605,7 @@ impl<T> Trait<T> for X {
// First look in the `where` clause, as this might be // First look in the `where` clause, as this might be
// `fn foo<T>(x: T) where T: Trait`. // `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::WherePredicate::BoundPredicate(pred) = predicate {
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) =
pred.bounded_ty.kind pred.bounded_ty.kind

View file

@ -1590,7 +1590,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
self.check_generic_bound(bound); self.check_generic_bound(bound);
} }
} }
for predicate in generics.where_clause.predicates { for predicate in generics.predicates {
match predicate { match predicate {
hir::WherePredicate::BoundPredicate(bound_pred) => { hir::WherePredicate::BoundPredicate(bound_pred) => {
for bound in bound_pred.bounds.iter() { for bound in bound_pred.bounds.iter() {

View file

@ -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 { match predicate {
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
ref bounded_ty, ref bounded_ty,
@ -1717,7 +1717,7 @@ fn object_lifetime_defaults_for_item<'tcx>(
add_bounds(&mut set, &param.bounds); add_bounds(&mut set, &param.bounds);
let param_def_id = tcx.hir().local_def_id(param.hir_id); 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. // Look for `type: ...` where clauses.
let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue }; let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };

View file

@ -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 { if let hir::WherePredicate::BoundPredicate(ref wbp) = *pred {
self.process_bounds(wbp.bounds); self.process_bounds(wbp.bounds);
self.visit_ty(wbp.bounded_ty); self.visit_ty(wbp.bounded_ty);

View file

@ -2419,7 +2419,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
}; };
let sized_trait = self.tcx.lang_items().sized_trait(); let sized_trait = self.tcx.lang_items().sized_trait();
debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params); 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| { 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 // 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. // `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; return;
}; };
let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id(); 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 let explicitly_sized = preds
.filter_map(|pred| match pred { .filter_map(|pred| match pred {
hir::WherePredicate::BoundPredicate(bp) => Some(bp), hir::WherePredicate::BoundPredicate(bp) => Some(bp),

View file

@ -319,12 +319,8 @@ pub trait InferCtxtExt<'tcx> {
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) { fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
( (
generics.where_clause.tail_span_for_suggestion(), generics.tail_span_for_predicate_suggestion(),
format!( format!("{} {}", if !generics.predicates.is_empty() { "," } else { " where" }, pred,),
"{} {}",
if !generics.where_clause.predicates.is_empty() { "," } else { " where" },
pred,
),
) )
} }
@ -346,7 +342,7 @@ fn suggest_restriction<'tcx>(
// - ^^^^^^^^^ GenericBounds // - ^^^^^^^^^ GenericBounds
// | // |
// &Ident // &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() { if span.from_expansion() || span.desugaring_kind().is_some() {
return; return;
} }

View file

@ -221,7 +221,6 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
.. ..
}) => Some( }) => Some(
generics generics
.where_clause
.predicates .predicates
.iter() .iter()
.filter_map(|pred| { .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`. // We'll attempt to provide a structured suggestion for `Self: Sized`.
let sugg = let sugg =
tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map( tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map(
|generics| match generics.where_clause.predicates { |generics| match generics.predicates {
[] => (" where Self: Sized", generics.where_clause.span), [] => (" where Self: Sized", generics.where_clause_span),
[.., pred] => (", Self: Sized", pred.span().shrink_to_hi()), [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()),
}, },
); );

View file

@ -599,7 +599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: kind:
hir::ItemKind::Fn( hir::ItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs: fn_parameters, output: fn_return, .. }, .. }, hir::FnSig { decl: hir::FnDecl { inputs: fn_parameters, output: fn_return, .. }, .. },
hir::Generics { params, where_clause, .. }, hir::Generics { params, predicates, .. },
_body_id, _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 }; 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 // get all where BoundPredicates here, because they are used in to cases below
let where_predicates = where_clause let where_predicates = predicates
.predicates
.iter() .iter()
.filter_map(|p| match p { .filter_map(|p| match p {
WherePredicate::BoundPredicate(hir::WhereBoundPredicate { WherePredicate::BoundPredicate(hir::WhereBoundPredicate {

View file

@ -533,12 +533,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node { if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
if let Some(g) = kind.generics() { 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), [.., pred] => (pred.span().shrink_to_hi(), false),
[] => ( [] => (g.span_for_predicates_or_empty_place(), true),
g.where_clause.span_for_predicates_or_empty_place(),
true,
),
}; };
type_params type_params
.entry(key) .entry(key)

View file

@ -420,15 +420,11 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
let suggestion = format!( let suggestion = format!(
"{} {}", "{} {}",
if !gat_item_hir.generics.where_clause.predicates.is_empty() { if !gat_item_hir.generics.predicates.is_empty() { "," } else { " where" },
","
} else {
" where"
},
unsatisfied_bounds.join(", "), unsatisfied_bounds.join(", "),
); );
err.span_suggestion( 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}"), &format!("add the required where clause{plural}"),
suggestion, suggestion,
Applicability::MachineApplicable, Applicability::MachineApplicable,
@ -1733,7 +1729,6 @@ fn check_variances_for_type_defn<'tcx>(
let explicitly_bounded_params = Lazy::new(|| { let explicitly_bounded_params = Lazy::new(|| {
let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id()); let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
hir_generics hir_generics
.where_clause
.predicates .predicates
.iter() .iter()
.filter_map(|predicate| match predicate { .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) // 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()) hir_node.and_then(|node| node.generics())
{ {
let obligation_span = obligation.cause.span(fcx.tcx); let obligation_span = obligation.cause.span(fcx.tcx);
span = where_clause span = predicates
.predicates
.iter() .iter()
// There seems to be no better way to find out which predicate we are in // There seems to be no better way to find out which predicate we are in
.find(|pred| pred.span().contains(obligation_span)) .find(|pred| pred.span().contains(obligation_span))

View file

@ -700,7 +700,6 @@ impl<'tcx> ItemCtxt<'tcx> {
let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id(); let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
let from_where_clauses = ast_generics let from_where_clauses = ast_generics
.where_clause
.predicates .predicates
.iter() .iter()
.filter_map(|wp| match *wp { .filter_map(|wp| match *wp {
@ -2343,7 +2342,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
&icx, &icx,
&mut bounds, &mut bounds,
param.bounds, param.bounds,
Some((param.hir_id, ast_generics.where_clause.predicates)), Some((param.hir_id, ast_generics.predicates)),
param.span, param.span,
); );
predicates.extend(bounds.predicates(tcx, param_ty)); 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. // Add in the bounds that appear in the where-clause.
let where_clause = &ast_generics.where_clause; for predicate in ast_generics.predicates {
for predicate in where_clause.predicates {
match predicate { match predicate {
hir::WherePredicate::BoundPredicate(bound_pred) => { hir::WherePredicate::BoundPredicate(bound_pred) => {
let ty = icx.to_ty(bound_pred.bounded_ty); let ty = icx.to_ty(bound_pred.bounded_ty);

View file

@ -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()); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) { match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, ref generics, _), .. })) => { 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"); 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(); .emit();
error = true; error = true;
} }
if let Some(sp) = generics.where_clause.span() { if let Some(sp) = generics.where_clause_span() {
struct_span_err!( struct_span_err!(
tcx.sess, tcx.sess,
sp, sp,

View file

@ -545,7 +545,7 @@ impl Clean<Generics> for hir::Generics<'_> {
let mut generics = Generics { let mut generics = Generics {
params, 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 // Some duplicates are generated for ?Sized bounds between type params and where

View file

@ -8,7 +8,7 @@ use rustc_hir::FnRetTy::Return;
use rustc_hir::{ use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem,
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier, 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_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -130,7 +130,7 @@ fn check_fn_inner<'tcx>(
span: Span, span: Span,
report_extra_lifetimes: bool, 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; 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 /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to
/// reason about elision. /// reason about elision.
fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool { fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {
for predicate in where_clause.predicates { for predicate in generics.predicates {
match *predicate { match *predicate {
WherePredicate::RegionPredicate(..) => return true, WherePredicate::RegionPredicate(..) => return true,
WherePredicate::BoundPredicate(ref pred) => { WherePredicate::BoundPredicate(ref pred) => {

View file

@ -90,10 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
} }
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) { 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(); let mut self_bounds_map = FxHashMap::default();
for predicate in where_clause.predicates { for predicate in item.generics.predicates {
if_chain! { if_chain! {
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate; if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
if !bound_predicate.span.from_expansion(); if !bound_predicate.span.from_expansion();
@ -166,7 +165,7 @@ impl TraitBounds {
} }
let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default(); let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
let mut applicability = Applicability::MaybeIncorrect; let mut applicability = Applicability::MaybeIncorrect;
for bound in gen.where_clause.predicates { for bound in gen.predicates {
if_chain! { if_chain! {
if let WherePredicate::BoundPredicate(ref p) = bound; if let WherePredicate::BoundPredicate(ref p) = bound;
if p.bounds.len() as u64 <= self.max_trait_bounds; 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<'_>) { 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; 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_chain! {
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate; if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
if !bound_predicate.span.from_expansion(); if !bound_predicate.span.from_expansion();