Inline WhereClause into Generics.
This commit is contained in:
parent
71b4e2d852
commit
05b29f9a92
@ -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,
|
||||
})
|
||||
}
|
||||
|
@ -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],
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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>>(
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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!(
|
||||
"{} {}",
|
||||
|
@ -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`
|
||||
|
@ -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>(
|
||||
[¶m_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))
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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, ¶m.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 };
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()),
|
||||
},
|
||||
);
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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) => {
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user