Auto merge of #132894 - frank-king:feature/where-refactor, r=cjgillot

Refactor `where` predicates, and reserve for attributes support

Refactor `WherePredicate` to `WherePredicateKind`, and reserve for attributes support in `where` predicates.

This is a part of #115590 and is split from #132388.

r? petrochenkov
This commit is contained in:
bors 2024-11-26 04:12:33 +00:00
commit f2abf827c1
44 changed files with 394 additions and 408 deletions

View File

@ -428,7 +428,15 @@ impl Default for WhereClause {
/// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicate {
pub struct WherePredicate {
pub kind: WherePredicateKind,
pub id: NodeId,
pub span: Span,
}
/// Predicate kind in where-clause.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicateKind {
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
BoundPredicate(WhereBoundPredicate),
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
@ -437,22 +445,11 @@ pub enum WherePredicate {
EqPredicate(WhereEqPredicate),
}
impl WherePredicate {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
WherePredicate::RegionPredicate(p) => p.span,
WherePredicate::EqPredicate(p) => p.span,
}
}
}
/// A type bound.
///
/// E.g., `for<'c> Foo: Send + Clone + 'c`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereBoundPredicate {
pub span: Span,
/// Any generics from a `for` binding.
pub bound_generic_params: ThinVec<GenericParam>,
/// The type being bounded.
@ -466,7 +463,6 @@ pub struct WhereBoundPredicate {
/// E.g., `'a: 'b + 'c`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereRegionPredicate {
pub span: Span,
pub lifetime: Lifetime,
pub bounds: GenericBounds,
}
@ -476,7 +472,6 @@ pub struct WhereRegionPredicate {
/// E.g., `T = int`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereEqPredicate {
pub span: Span,
pub lhs_ty: P<Ty>,
pub rhs_ty: P<Ty>,
}

View File

@ -332,7 +332,11 @@ pub trait MutVisitor: Sized {
}
fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
walk_where_predicate(self, where_predicate);
walk_where_predicate(self, where_predicate)
}
fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
walk_where_predicate_kind(self, kind)
}
fn visit_vis(&mut self, vis: &mut Visibility) {
@ -1065,26 +1069,30 @@ fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
vis.visit_span(span);
}
fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
match pred {
WherePredicate::BoundPredicate(bp) => {
let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
let WherePredicate { kind, id, span } = pred;
vis.visit_id(id);
vis.visit_where_predicate_kind(kind);
vis.visit_span(span);
}
pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
match kind {
WherePredicateKind::BoundPredicate(bp) => {
let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp;
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
vis.visit_ty(bounded_ty);
visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
vis.visit_span(span);
}
WherePredicate::RegionPredicate(rp) => {
let WhereRegionPredicate { span, lifetime, bounds } = rp;
WherePredicateKind::RegionPredicate(rp) => {
let WhereRegionPredicate { lifetime, bounds } = rp;
vis.visit_lifetime(lifetime);
visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
vis.visit_span(span);
}
WherePredicate::EqPredicate(ep) => {
let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
WherePredicateKind::EqPredicate(ep) => {
let WhereEqPredicate { lhs_ty, rhs_ty } = ep;
vis.visit_ty(lhs_ty);
vis.visit_ty(rhs_ty);
vis.visit_span(span);
}
}
}

View File

@ -192,6 +192,9 @@ pub trait Visitor<'ast>: Sized {
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result {
walk_where_predicate(self, p)
}
fn visit_where_predicate_kind(&mut self, k: &'ast WherePredicateKind) -> Self::Result {
walk_where_predicate_kind(self, k)
}
fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result {
walk_fn(self, fk)
}
@ -794,22 +797,29 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
visitor: &mut V,
predicate: &'a WherePredicate,
) -> V::Result {
match predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate {
let WherePredicate { kind, id: _, span: _ } = predicate;
visitor.visit_where_predicate_kind(kind)
}
pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>(
visitor: &mut V,
kind: &'a WherePredicateKind,
) -> V::Result {
match kind {
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bounds,
bound_generic_params,
span: _,
}) => {
walk_list!(visitor, visit_generic_param, bound_generic_params);
try_visit!(visitor.visit_ty(bounded_ty));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => {
WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => {
WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
try_visit!(visitor.visit_ty(lhs_ty));
try_visit!(visitor.visit_ty(rhs_ty));
}

View File

@ -381,15 +381,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
match predicate {
WherePredicate::BoundPredicate(pred) => {
self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
self.with_parent(pred.hir_id, |this| {
intravisit::walk_where_predicate(this, predicate)
})
}
_ => intravisit::walk_where_predicate(self, predicate),
}
self.insert(predicate.span, predicate.hir_id, Node::WherePredicate(predicate));
self.with_parent(predicate.hir_id, |this| {
intravisit::walk_where_predicate(this, predicate)
});
}
fn visit_array_length(&mut self, len: &'hir ArrayLen<'hir>) {

View File

@ -1401,7 +1401,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
// checks both param bounds and where clauses for `?Sized`.
for pred in &generics.where_clause.predicates {
let WherePredicate::BoundPredicate(bound_pred) = pred else {
let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else {
continue;
};
let compute_is_param = || {
@ -1538,9 +1538,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
});
let span = self.lower_span(span);
match kind {
GenericParamKind::Const { .. } => None,
let hir_id = self.next_id();
let kind = self.arena.alloc(match kind {
GenericParamKind::Const { .. } => return None,
GenericParamKind::Type { .. } => {
let def_id = self.local_def_id(id).to_def_id();
let hir_id = self.next_id();
@ -1555,38 +1555,36 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ty_id = self.next_id();
let bounded_ty =
self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
hir_id: self.next_id(),
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bounded_ty: self.arena.alloc(bounded_ty),
bounds,
span,
bound_generic_params: &[],
origin,
}))
})
}
GenericParamKind::Lifetime => {
let ident = self.lower_ident(ident);
let lt_id = self.next_node_id();
let lifetime = self.new_named_lifetime(id, lt_id, ident);
Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
span,
bounds,
in_where_clause: false,
}))
})
}
}
});
Some(hir::WherePredicate { hir_id, span, kind })
}
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
match pred {
WherePredicate::BoundPredicate(WhereBoundPredicate {
let hir_id = self.lower_node_id(pred.id);
let span = self.lower_span(pred.span);
let kind = self.arena.alloc(match &pred.kind {
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bound_generic_params,
bounded_ty,
bounds,
span,
}) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
hir_id: self.next_id(),
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: self
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
bounded_ty: self
@ -1595,12 +1593,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
span: self.lower_span(*span),
origin: PredicateOrigin::WhereClause,
}),
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => {
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
span: self.lower_span(*span),
WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(
bounds,
@ -1609,15 +1605,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
in_where_clause: true,
})
}
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
lhs_ty: self
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
rhs_ty: self
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
span: self.lower_span(*span),
})
}
}
});
hir::WherePredicate { hir_id, span, kind }
}
}

View File

@ -1200,14 +1200,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
validate_generic_param_order(self.dcx(), &generics.params, generics.span);
for predicate in &generics.where_clause.predicates {
if let WherePredicate::EqPredicate(predicate) = predicate {
deny_equality_constraints(self, predicate, generics);
let span = predicate.span;
if let WherePredicateKind::EqPredicate(predicate) = &predicate.kind {
deny_equality_constraints(self, predicate, span, generics);
}
}
walk_list!(self, visit_generic_param, &generics.params);
for predicate in &generics.where_clause.predicates {
match predicate {
WherePredicate::BoundPredicate(bound_pred) => {
match &predicate.kind {
WherePredicateKind::BoundPredicate(bound_pred) => {
// This is slightly complicated. Our representation for poly-trait-refs contains a single
// binder and thus we only allow a single level of quantification. However,
// the syntax of Rust permits quantification in two places in where clauses,
@ -1504,9 +1505,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn deny_equality_constraints(
this: &AstValidator<'_>,
predicate: &WhereEqPredicate,
predicate_span: Span,
generics: &Generics,
) {
let mut err = errors::EqualityInWhere { span: predicate.span, assoc: None, assoc2: None };
let mut err = errors::EqualityInWhere { span: predicate_span, assoc: None, assoc2: None };
// Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind
@ -1550,7 +1552,7 @@ fn deny_equality_constraints(
}
}
err.assoc = Some(errors::AssociatedSuggestion {
span: predicate.span,
span: predicate_span,
ident: *ident,
param: param.ident,
path: pprust::path_to_string(&assoc_path),
@ -1580,23 +1582,23 @@ fn deny_equality_constraints(
// We're removing th eonly where bound left, remove the whole thing.
generics.where_clause.span
} else {
let mut span = predicate.span;
let mut span = predicate_span;
let mut prev: Option<Span> = None;
let mut preds = generics.where_clause.predicates.iter().peekable();
// Find the predicate that shouldn't have been in the where bound list.
while let Some(pred) = preds.next() {
if let WherePredicate::EqPredicate(pred) = pred
&& pred.span == predicate.span
if let WherePredicateKind::EqPredicate(_) = pred.kind
&& pred.span == predicate_span
{
if let Some(next) = preds.peek() {
// This is the first predicate, remove the trailing comma as well.
span = span.with_hi(next.span().lo());
span = span.with_hi(next.span.lo());
} else if let Some(prev) = prev {
// Remove the previous comma as well.
span = span.with_lo(prev.hi());
}
}
prev = Some(pred.span());
prev = Some(pred.span);
}
span
};
@ -1613,8 +1615,8 @@ fn deny_equality_constraints(
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
// Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
for bounds in generics.params.iter().map(|p| &p.bounds).chain(
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
WherePredicate::BoundPredicate(p) => Some(&p.bounds),
generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind {
WherePredicateKind::BoundPredicate(p) => Some(&p.bounds),
_ => None,
}),
) {
@ -1637,8 +1639,8 @@ fn deny_equality_constraints(
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
if let [potential_param, potential_assoc] = &full_path.segments[..] {
for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain(
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
WherePredicate::BoundPredicate(p)
generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind {
WherePredicateKind::BoundPredicate(p)
if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind
&& let [segment] = &path.segments[..] =>
{

View File

@ -345,8 +345,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_generics(&mut self, g: &'a ast::Generics) {
for predicate in &g.where_clause.predicates {
match predicate {
ast::WherePredicate::BoundPredicate(bound_pred) => {
match &predicate.kind {
ast::WherePredicateKind::BoundPredicate(bound_pred) => {
// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
}

View File

@ -726,11 +726,12 @@ impl<'a> State<'a> {
}
pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
match predicate {
ast::WherePredicate::BoundPredicate(where_bound_predicate) => {
let ast::WherePredicate { kind, id: _, span: _ } = predicate;
match kind {
ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
self.print_where_bound_predicate(where_bound_predicate);
}
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
lifetime,
bounds,
..
@ -742,7 +743,9 @@ impl<'a> State<'a> {
self.print_lifetime_bounds(bounds);
}
}
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate {
lhs_ty, rhs_ty, ..
}) => {
self.print_type(lhs_ty);
self.space();
self.word_space("=");

View File

@ -1062,8 +1062,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
&& let spans = hir_generics
.predicates
.iter()
.filter_map(|pred| match pred {
hir::WherePredicate::BoundPredicate(pred) => Some(pred),
.filter_map(|pred| match pred.kind {
hir::WherePredicateKind::BoundPredicate(pred) => Some(pred),
_ => None,
})
.filter(|pred| {

View File

@ -5,7 +5,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::GenericBound::Trait;
use rustc_hir::QPath::Resolved;
use rustc_hir::WherePredicate::BoundPredicate;
use rustc_hir::WherePredicateKind::BoundPredicate;
use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
@ -236,7 +236,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let mut hrtb_bounds = vec![];
gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| {
for pred in generics.predicates {
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) =
pred.kind
else {
continue;
};
@ -267,12 +268,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
};
debug!(?generics_fn);
generics_fn.predicates.iter().for_each(|predicate| {
let BoundPredicate(WhereBoundPredicate {
span: bounded_span,
bounded_ty,
bounds,
..
}) = predicate
let BoundPredicate(WhereBoundPredicate { bounded_ty, bounds, .. }) = predicate.kind
else {
return;
};
@ -287,7 +283,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.rfind(|param| param.def_id.to_def_id() == defid)
.is_some()
{
suggestions.push((bounded_span.shrink_to_hi(), " + 'static".to_string()));
suggestions.push((predicate.span.shrink_to_hi(), " + 'static".to_string()));
}
});
});

View File

@ -288,19 +288,18 @@ pub(crate) fn expand_deriving_coerce_pointee(
//
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`
// as well as any bound that indirectly involves the `#[pointee] T` type.
for bound in &generics.where_clause.predicates {
if let ast::WherePredicate::BoundPredicate(bound) = bound {
for predicate in &generics.where_clause.predicates {
if let ast::WherePredicateKind::BoundPredicate(bound) = &predicate.kind {
let mut substitution = TypeSubstitution {
from_name: pointee_ty_ident.name,
to_ty: &s_ty,
rewritten: false,
};
let mut predicate = ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
span: bound.span,
bound_generic_params: bound.bound_generic_params.clone(),
bounded_ty: bound.bounded_ty.clone(),
bounds: bound.bounds.clone(),
});
let mut predicate = ast::WherePredicate {
kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
span: predicate.span,
id: ast::DUMMY_NODE_ID,
};
substitution.visit_where_predicate(&mut predicate);
if substitution.rewritten {
impl_generics.where_clause.predicates.push(predicate);
@ -319,7 +318,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool {
for bound in predicates {
if let ast::WherePredicate::BoundPredicate(bound) = bound
if let ast::WherePredicateKind::BoundPredicate(bound) = &bound.kind
&& bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee)
{
for bound in &bound.bounds {
@ -385,8 +384,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
}
fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
match where_predicate {
rustc_ast::WherePredicate::BoundPredicate(bound) => {
match &mut where_predicate.kind {
rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
bound
.bound_generic_params
.flat_map_in_place(|param| self.flat_map_generic_param(param));
@ -395,8 +394,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
self.visit_param_bound(bound, BoundKind::Bound)
}
}
rustc_ast::WherePredicate::RegionPredicate(_)
| rustc_ast::WherePredicate::EqPredicate(_) => {}
rustc_ast::WherePredicateKind::RegionPredicate(_)
| rustc_ast::WherePredicateKind::EqPredicate(_) => {}
}
}
}

View File

@ -690,25 +690,10 @@ impl<'a> TraitDef<'a> {
// and similarly for where clauses
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
match clause {
ast::WherePredicate::BoundPredicate(wb) => {
let span = wb.span.with_ctxt(ctxt);
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
span,
..wb.clone()
})
}
ast::WherePredicate::RegionPredicate(wr) => {
let span = wr.span.with_ctxt(ctxt);
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
span,
..wr.clone()
})
}
ast::WherePredicate::EqPredicate(we) => {
let span = we.span.with_ctxt(ctxt);
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() })
}
ast::WherePredicate {
kind: clause.kind.clone(),
id: ast::DUMMY_NODE_ID,
span: clause.span.with_ctxt(ctxt),
}
}));
@ -757,13 +742,14 @@ impl<'a> TraitDef<'a> {
if !bounds.is_empty() {
let predicate = ast::WhereBoundPredicate {
span: self.span,
bound_generic_params: field_ty_param.bound_generic_params,
bounded_ty: field_ty_param.ty,
bounds,
};
let predicate = ast::WherePredicate::BoundPredicate(predicate);
let kind = ast::WherePredicateKind::BoundPredicate(predicate);
let predicate =
ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
where_clause.predicates.push(predicate);
}
}

View File

@ -690,8 +690,8 @@ impl<'hir> Generics<'hir> {
if self.has_where_clause_predicates {
self.predicates
.iter()
.rfind(|&p| p.in_where_clause())
.map_or(end, |p| p.span())
.rfind(|&p| p.kind.in_where_clause())
.map_or(end, |p| p.span)
.shrink_to_hi()
.to(end)
} else {
@ -714,8 +714,10 @@ impl<'hir> Generics<'hir> {
&self,
param_def_id: LocalDefId,
) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
self.predicates.iter().filter_map(move |pred| match pred {
WherePredicate::BoundPredicate(bp) if bp.is_param_bound(param_def_id.to_def_id()) => {
self.predicates.iter().filter_map(move |pred| match pred.kind {
WherePredicateKind::BoundPredicate(bp)
if bp.is_param_bound(param_def_id.to_def_id()) =>
{
Some(bp)
}
_ => None,
@ -726,8 +728,8 @@ impl<'hir> Generics<'hir> {
&self,
param_def_id: LocalDefId,
) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
self.predicates.iter().filter_map(move |pred| match pred {
WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
self.predicates.iter().filter_map(move |pred| match pred.kind {
WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
_ => None,
})
}
@ -779,9 +781,9 @@ impl<'hir> Generics<'hir> {
pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
let predicate = &self.predicates[pos];
let span = predicate.span();
let span = predicate.span;
if !predicate.in_where_clause() {
if !predicate.kind.in_where_clause() {
// <T: ?Sized, U>
// ^^^^^^^^
return span;
@ -790,19 +792,19 @@ impl<'hir> Generics<'hir> {
// We need to find out which comma to remove.
if pos < self.predicates.len() - 1 {
let next_pred = &self.predicates[pos + 1];
if next_pred.in_where_clause() {
if next_pred.kind.in_where_clause() {
// where T: ?Sized, Foo: Bar,
// ^^^^^^^^^^^
return span.until(next_pred.span());
return span.until(next_pred.span);
}
}
if pos > 0 {
let prev_pred = &self.predicates[pos - 1];
if prev_pred.in_where_clause() {
if prev_pred.kind.in_where_clause() {
// where Foo: Bar, T: ?Sized,
// ^^^^^^^^^^^
return prev_pred.span().shrink_to_hi().to(span);
return prev_pred.span.shrink_to_hi().to(span);
}
}
@ -814,7 +816,7 @@ impl<'hir> Generics<'hir> {
pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
let predicate = &self.predicates[predicate_pos];
let bounds = predicate.bounds();
let bounds = predicate.kind.bounds();
if bounds.len() == 1 {
return self.span_for_predicate_removal(predicate_pos);
@ -841,7 +843,15 @@ impl<'hir> Generics<'hir> {
/// A single predicate in a where-clause.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum WherePredicate<'hir> {
pub struct WherePredicate<'hir> {
pub hir_id: HirId,
pub span: Span,
pub kind: &'hir WherePredicateKind<'hir>,
}
/// The kind of a single predicate in a where-clause.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum WherePredicateKind<'hir> {
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
BoundPredicate(WhereBoundPredicate<'hir>),
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
@ -850,28 +860,20 @@ pub enum WherePredicate<'hir> {
EqPredicate(WhereEqPredicate<'hir>),
}
impl<'hir> WherePredicate<'hir> {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
WherePredicate::RegionPredicate(p) => p.span,
WherePredicate::EqPredicate(p) => p.span,
}
}
impl<'hir> WherePredicateKind<'hir> {
pub fn in_where_clause(&self) -> bool {
match self {
WherePredicate::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
WherePredicate::RegionPredicate(p) => p.in_where_clause,
WherePredicate::EqPredicate(_) => false,
WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
WherePredicateKind::EqPredicate(_) => false,
}
}
pub fn bounds(&self) -> GenericBounds<'hir> {
match self {
WherePredicate::BoundPredicate(p) => p.bounds,
WherePredicate::RegionPredicate(p) => p.bounds,
WherePredicate::EqPredicate(_) => &[],
WherePredicateKind::BoundPredicate(p) => p.bounds,
WherePredicateKind::RegionPredicate(p) => p.bounds,
WherePredicateKind::EqPredicate(_) => &[],
}
}
}
@ -886,8 +888,6 @@ pub enum PredicateOrigin {
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereBoundPredicate<'hir> {
pub hir_id: HirId,
pub span: Span,
/// Origin of the predicate.
pub origin: PredicateOrigin,
/// Any generics from a `for` binding.
@ -908,7 +908,6 @@ impl<'hir> WhereBoundPredicate<'hir> {
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereRegionPredicate<'hir> {
pub span: Span,
pub in_where_clause: bool,
pub lifetime: &'hir Lifetime,
pub bounds: GenericBounds<'hir>,
@ -924,7 +923,6 @@ impl<'hir> WhereRegionPredicate<'hir> {
/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereEqPredicate<'hir> {
pub span: Span,
pub lhs_ty: &'hir Ty<'hir>,
pub rhs_ty: &'hir Ty<'hir>,
}
@ -3798,7 +3796,7 @@ pub enum Node<'hir> {
GenericParam(&'hir GenericParam<'hir>),
Crate(&'hir Mod<'hir>),
Infer(&'hir InferArg),
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
WherePredicate(&'hir WherePredicate<'hir>),
// FIXME: Merge into `Node::Infer`.
ArrayLenInfer(&'hir InferArg),
PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
@ -3853,7 +3851,7 @@ impl<'hir> Node<'hir> {
| Node::TraitRef(..)
| Node::OpaqueTy(..)
| Node::Infer(..)
| Node::WhereBoundPredicate(..)
| Node::WherePredicate(..)
| Node::ArrayLenInfer(..)
| Node::Synthetic
| Node::Err(..) => None,

View File

@ -961,30 +961,28 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
visitor: &mut V,
predicate: &'v WherePredicate<'v>,
) -> V::Result {
match *predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate {
hir_id,
let &WherePredicate { hir_id, kind, span: _ } = predicate;
try_visit!(visitor.visit_id(hir_id));
match *kind {
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
ref bounded_ty,
bounds,
bound_generic_params,
origin: _,
span: _,
}) => {
try_visit!(visitor.visit_id(hir_id));
try_visit!(visitor.visit_ty(bounded_ty));
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_generic_param, bound_generic_params);
}
WherePredicate::RegionPredicate(WhereRegionPredicate {
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
ref lifetime,
bounds,
span: _,
in_where_clause: _,
}) => {
try_visit!(visitor.visit_lifetime(lifetime));
walk_list!(visitor, visit_param_bound, bounds);
}
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => {
WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => {
try_visit!(visitor.visit_ty(lhs_ty));
try_visit!(visitor.visit_ty(rhs_ty));
}

View File

@ -1100,7 +1100,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
// *are* present in the impl.
for p in trait_generics.predicates {
if let hir::WherePredicate::BoundPredicate(pred) = p {
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
for b in pred.bounds {
if let hir::GenericBound::Outlives(lt) = b {
bounds_span.push(lt.ident.span);
@ -1113,7 +1113,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
{
let mut impl_bounds = 0;
for p in impl_generics.predicates {
if let hir::WherePredicate::BoundPredicate(pred) = p {
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
for b in pred.bounds {
if let hir::GenericBound::Outlives(_) = b {
impl_bounds += 1;

View File

@ -1921,8 +1921,8 @@ fn check_variances_for_type_defn<'tcx>(
hir_generics
.predicates
.iter()
.filter_map(|predicate| match predicate {
hir::WherePredicate::BoundPredicate(predicate) => {
.filter_map(|predicate| match predicate.kind {
hir::WherePredicateKind::BoundPredicate(predicate) => {
match icx.lower_ty(predicate.bounded_ty).kind() {
ty::Param(data) => Some(Parameter(data.index)),
_ => None,
@ -2202,8 +2202,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
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))
.map(|pred| pred.span())
.find(|pred| pred.span.contains(obligation_span))
.map(|pred| pred.span)
.unwrap_or(obligation_span);
}

View File

@ -238,11 +238,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
trace!(?predicates);
// Add inline `<T: Foo>` bounds and bounds in the where clause.
for predicate in hir_generics.predicates {
match predicate {
hir::WherePredicate::BoundPredicate(bound_pred) => {
match predicate.kind {
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
let bound_vars = tcx.late_bound_vars(predicate.hir_id);
// Keep the type around in a dummy predicate, in case of no bounds.
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
// is still checked for WF.
@ -275,7 +275,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
predicates.extend(bounds.clauses());
}
hir::WherePredicate::RegionPredicate(region_pred) => {
hir::WherePredicateKind::RegionPredicate(region_pred) => {
let r1 = icx
.lowerer()
.lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
@ -298,7 +298,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}))
}
hir::WherePredicate::EqPredicate(..) => {
hir::WherePredicateKind::EqPredicate(..) => {
// FIXME(#20041)
}
}
@ -881,7 +881,8 @@ impl<'tcx> ItemCtxt<'tcx> {
let mut bounds = Bounds::default();
for predicate in hir_generics.predicates {
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
let hir_id = predicate.hir_id;
let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind else {
continue;
};
@ -901,7 +902,7 @@ impl<'tcx> ItemCtxt<'tcx> {
let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
let bound_vars = self.tcx.late_bound_vars(hir_id);
self.lowerer().lower_bounds(
bound_ty,
predicate.bounds,
@ -974,10 +975,10 @@ pub(super) fn const_conditions<'tcx>(
let mut bounds = Bounds::default();
for pred in generics.predicates {
match pred {
hir::WherePredicate::BoundPredicate(bound_pred) => {
match pred.kind {
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
let bound_vars = tcx.late_bound_vars(pred.hir_id);
icx.lowerer().lower_bounds(
ty,
bound_pred.bounds.iter(),

View File

@ -936,9 +936,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
fn visit_where_predicate(&mut self, predicate: &'tcx hir::WherePredicate<'tcx>) {
match predicate {
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
hir_id,
let hir_id = predicate.hir_id;
match predicate.kind {
&hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bounded_ty,
bounds,
bound_generic_params,
@ -979,7 +979,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
walk_list!(this, visit_param_bound, bounds);
})
}
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
&hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
bounds,
..
@ -987,7 +987,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
self.visit_lifetime(lifetime);
walk_list!(self, visit_param_bound, bounds);
}
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
&hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
lhs_ty, rhs_ty, ..
}) => {
self.visit_ty(lhs_ty);
self.visit_ty(rhs_ty);
}
@ -2073,7 +2075,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// bounds since we'll be emitting a hard error in HIR lowering, so this
// is purely speculative.
let one_bound = generics.predicates.iter().find_map(|predicate| {
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind
else {
return None;
};
let hir::TyKind::Path(hir::QPath::Resolved(None, bounded_path)) =

View File

@ -69,7 +69,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
search_bounds(hir_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause {
if let hir::WherePredicate::BoundPredicate(pred) = clause
if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
&& pred.is_param_bound(self_ty.to_def_id())
{
search_bounds(pred.bounds);

View File

@ -117,11 +117,7 @@ impl<'a> State<'a> {
Node::Ctor(..) => panic!("cannot print isolated Ctor"),
Node::LetStmt(a) => self.print_local_decl(a),
Node::Crate(..) => panic!("cannot print Crate"),
Node::WhereBoundPredicate(pred) => {
self.print_formal_generic_params(pred.bound_generic_params);
self.print_type(pred.bounded_ty);
self.print_bounds(":", pred.bounds);
}
Node::WherePredicate(pred) => self.print_where_predicate(pred),
Node::ArrayLenInfer(_) => self.word("_"),
Node::Synthetic => unreachable!(),
Node::Err(_) => self.word("/*ERROR*/"),
@ -2160,47 +2156,50 @@ impl<'a> State<'a> {
if i != 0 {
self.word_space(",");
}
self.print_where_predicate(predicate);
}
}
match *predicate {
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params,
bounded_ty,
bounds,
..
}) => {
self.print_formal_generic_params(bound_generic_params);
self.print_type(bounded_ty);
self.print_bounds(":", bounds);
}
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
bounds,
..
}) => {
self.print_lifetime(lifetime);
self.word(":");
fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
match *predicate.kind {
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params,
bounded_ty,
bounds,
..
}) => {
self.print_formal_generic_params(bound_generic_params);
self.print_type(bounded_ty);
self.print_bounds(":", bounds);
}
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
bounds,
..
}) => {
self.print_lifetime(lifetime);
self.word(":");
for (i, bound) in bounds.iter().enumerate() {
match bound {
GenericBound::Outlives(lt) => {
self.print_lifetime(lt);
}
_ => panic!("unexpected bound on lifetime param: {bound:?}"),
for (i, bound) in bounds.iter().enumerate() {
match bound {
GenericBound::Outlives(lt) => {
self.print_lifetime(lt);
}
_ => panic!("unexpected bound on lifetime param: {bound:?}"),
}
if i != 0 {
self.word(":");
}
if i != 0 {
self.word(":");
}
}
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
lhs_ty, rhs_ty, ..
}) => {
self.print_type(lhs_ty);
self.space();
self.word_space("=");
self.print_type(rhs_ty);
}
}
hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
lhs_ty, rhs_ty, ..
}) => {
self.print_type(lhs_ty);
self.space();
self.word_space("=");
self.print_type(rhs_ty);
}
}
}

View File

@ -420,7 +420,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| hir::Node::GenericParam(_)
| hir::Node::Crate(_)
| hir::Node::Infer(_)
| hir::Node::WhereBoundPredicate(_)
| hir::Node::WherePredicate(_)
| hir::Node::ArrayLenInfer(_)
| hir::Node::PreciseCapturingNonLifetimeArg(_)
| hir::Node::OpaqueTy(_) => {

View File

@ -10,7 +10,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId,
Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind,
};
use rustc_hir_analysis::collect::suggest_impl_trait;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
@ -1004,8 +1004,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// get all where BoundPredicates here, because they are used in two cases below
let where_predicates = predicates
.iter()
.filter_map(|p| match p {
WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
.filter_map(|p| match p.kind {
WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bounds,
bounded_ty,
..

View File

@ -1407,7 +1407,7 @@ declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]);
impl TypeAliasBounds {
pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool {
// Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults.
if let hir::WherePredicate::BoundPredicate(pred) = pred
if let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind
&& pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
&& pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS
&& pred.bounded_ty.as_generic_param().is_some()
@ -1451,11 +1451,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
let mut inline_sugg = Vec::new();
for p in generics.predicates {
let span = p.span();
if p.in_where_clause() {
let span = p.span;
if p.kind.in_where_clause() {
where_spans.push(span);
} else {
for b in p.bounds() {
for b in p.kind.bounds() {
inline_spans.push(b.span());
}
inline_sugg.push((span, String::new()));
@ -2071,7 +2071,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
let num_where_predicates = hir_generics
.predicates
.iter()
.filter(|predicate| predicate.in_where_clause())
.filter(|predicate| predicate.kind.in_where_clause())
.count();
let mut bound_count = 0;
@ -2080,8 +2080,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
let mut dropped_where_predicate_count = 0;
for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
let (relevant_lifetimes, bounds, predicate_span, in_where_clause) =
match where_predicate {
hir::WherePredicate::RegionPredicate(predicate) => {
match where_predicate.kind {
hir::WherePredicateKind::RegionPredicate(predicate) => {
if let Some(ResolvedArg::EarlyBound(region_def_id)) =
cx.tcx.named_bound_var(predicate.lifetime.hir_id)
{
@ -2090,21 +2090,21 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
cx.tcx,
// don't warn if the inferred span actually came from the predicate we're looking at
// this happens if the type is recursively defined
inferred_outlives
.iter()
.filter(|(_, span)| !predicate.span.contains(*span)),
inferred_outlives.iter().filter(|(_, span)| {
!where_predicate.span.contains(*span)
}),
item.owner_id.def_id,
region_def_id,
),
&predicate.bounds,
predicate.span,
where_predicate.span,
predicate.in_where_clause,
)
} else {
continue;
}
}
hir::WherePredicate::BoundPredicate(predicate) => {
hir::WherePredicateKind::BoundPredicate(predicate) => {
// FIXME we can also infer bounds on associated types,
// and should check for them here.
match predicate.bounded_ty.kind {
@ -2118,12 +2118,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
// don't warn if the inferred span actually came from the predicate we're looking at
// this happens if the type is recursively defined
inferred_outlives.iter().filter(|(_, span)| {
!predicate.span.contains(*span)
!where_predicate.span.contains(*span)
}),
index,
),
&predicate.bounds,
predicate.span,
where_predicate.span,
predicate.origin == PredicateOrigin::WhereClause,
)
}
@ -2161,7 +2161,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
} else if i + 1 < num_where_predicates {
// If all the bounds on a predicate were inferable and there are
// further predicates, we want to eat the trailing comma.
let next_predicate_span = hir_generics.predicates[i + 1].span();
let next_predicate_span = hir_generics.predicates[i + 1].span;
if next_predicate_span.from_expansion() {
where_lint_spans.push(predicate_span);
} else {

View File

@ -300,7 +300,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
let affect_object_lifetime_defaults = self
.preds
.iter()
.filter(|pred| pred.in_where_clause() == self.in_where_clause)
.filter(|pred| pred.kind.in_where_clause() == self.in_where_clause)
.any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
// If there are any shorthand assoc tys, then the bounds can't be removed automatically.

View File

@ -1304,12 +1304,12 @@ impl EarlyLintPass for UnusedParens {
}
fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) {
use rustc_ast::{WhereBoundPredicate, WherePredicate};
if let WherePredicate::BoundPredicate(WhereBoundPredicate {
use rustc_ast::{WhereBoundPredicate, WherePredicateKind};
if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bound_generic_params,
..
}) = pred
}) = &pred.kind
&& let ast::TyKind::Paren(_) = &bounded_ty.kind
&& bound_generic_params.is_empty()
{

View File

@ -947,7 +947,7 @@ impl<'hir> Map<'hir> {
Node::Infer(i) => i.span,
Node::LetStmt(local) => local.span,
Node::Crate(item) => item.spans.inner_span,
Node::WhereBoundPredicate(pred) => pred.span,
Node::WherePredicate(pred) => pred.span,
Node::ArrayLenInfer(inf) => inf.span,
Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
Node::Synthetic => unreachable!(),
@ -1225,7 +1225,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
format!("{id} (generic_param {})", path_str(param.def_id))
}
Node::Crate(..) => String::from("(root_crate)"),
Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
Node::WherePredicate(_) => node_str("where predicate"),
Node::ArrayLenInfer(_) => node_str("array len infer"),
Node::Synthetic => unreachable!(),
Node::Err(_) => node_str("error"),

View File

@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicate};
use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicateKind};
use rustc_span::{BytePos, Span};
use rustc_type_ir::TyKind::*;
@ -180,7 +180,7 @@ fn suggest_changing_unsized_bound(
// First look at the `where` clause because we can have `where T: ?Sized`,
// then look at params.
for (where_pos, predicate) in generics.predicates.iter().enumerate() {
let WherePredicate::BoundPredicate(predicate) = predicate else {
let WherePredicateKind::BoundPredicate(predicate) = predicate.kind else {
continue;
};
if !predicate.is_param_bound(param.def_id.to_def_id()) {

View File

@ -1,6 +1,7 @@
use ast::token::Delimiter;
use rustc_ast::{
self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token,
self as ast, AttrVec, DUMMY_NODE_ID, GenericBounds, GenericParam, GenericParamKind, TyKind,
WhereClause, token,
};
use rustc_errors::{Applicability, PResult};
use rustc_span::Span;
@ -14,8 +15,8 @@ use crate::errors::{
WhereClauseBeforeTupleStructBodySugg,
};
enum PredicateOrStructBody {
Predicate(ast::WherePredicate),
enum PredicateKindOrStructBody {
PredicateKind(ast::WherePredicateKind),
StructBody(ThinVec<ast::FieldDef>),
}
@ -218,10 +219,11 @@ impl<'a> Parser<'a> {
} else if this.token.can_begin_type() {
// Trying to write an associated type bound? (#26271)
let snapshot = this.create_snapshot_for_diagnostic();
match this.parse_ty_where_predicate() {
Ok(where_predicate) => {
let lo = this.token.span;
match this.parse_ty_where_predicate_kind() {
Ok(_) => {
this.dcx().emit_err(errors::BadAssocTypeBounds {
span: where_predicate.span(),
span: lo.to(this.prev_token.span),
});
// FIXME - try to continue parsing other generics?
}
@ -340,31 +342,33 @@ impl<'a> Parser<'a> {
loop {
let where_sp = where_lo.to(self.prev_token.span);
let pred_lo = self.token.span;
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
let lifetime = self.expect_lifetime();
// Bounds starting with a colon are mandatory, but possibly empty.
self.expect(&token::Colon)?;
let bounds = self.parse_lt_param_bounds();
where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
ast::WhereRegionPredicate {
span: pred_lo.to(self.prev_token.span),
lifetime,
bounds,
},
));
ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
lifetime,
bounds,
})
} else if self.check_type() {
match self.parse_ty_where_predicate_or_recover_tuple_struct_body(
match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
struct_, pred_lo, where_sp,
)? {
PredicateOrStructBody::Predicate(pred) => where_clause.predicates.push(pred),
PredicateOrStructBody::StructBody(body) => {
PredicateKindOrStructBody::PredicateKind(kind) => kind,
PredicateKindOrStructBody::StructBody(body) => {
tuple_struct_body = Some(body);
break;
}
}
} else {
break;
}
};
where_clause.predicates.push(ast::WherePredicate {
kind,
id: DUMMY_NODE_ID,
span: pred_lo.to(self.prev_token.span),
});
let prev_token = self.prev_token.span;
let ate_comma = self.eat(&token::Comma);
@ -384,12 +388,12 @@ impl<'a> Parser<'a> {
Ok((where_clause, tuple_struct_body))
}
fn parse_ty_where_predicate_or_recover_tuple_struct_body(
fn parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
&mut self,
struct_: Option<(Ident, Span)>,
pred_lo: Span,
where_sp: Span,
) -> PResult<'a, PredicateOrStructBody> {
) -> PResult<'a, PredicateKindOrStructBody> {
let mut snapshot = None;
if let Some(struct_) = struct_
@ -399,8 +403,8 @@ impl<'a> Parser<'a> {
snapshot = Some((struct_, self.create_snapshot_for_diagnostic()));
};
match self.parse_ty_where_predicate() {
Ok(pred) => Ok(PredicateOrStructBody::Predicate(pred)),
match self.parse_ty_where_predicate_kind() {
Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind(pred)),
Err(type_err) => {
let Some(((struct_name, body_insertion_point), mut snapshot)) = snapshot else {
return Err(type_err);
@ -436,7 +440,7 @@ impl<'a> Parser<'a> {
});
self.restore_snapshot(snapshot);
Ok(PredicateOrStructBody::StructBody(body))
Ok(PredicateKindOrStructBody::StructBody(body))
}
Ok(_) => Err(type_err),
Err(body_err) => {
@ -448,8 +452,7 @@ impl<'a> Parser<'a> {
}
}
fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> {
let lo = self.token.span;
fn parse_ty_where_predicate_kind(&mut self) -> PResult<'a, ast::WherePredicateKind> {
// Parse optional `for<'a, 'b>`.
// This `for` is parsed greedily and applies to the whole predicate,
// the bounded type can have its own `for` applying only to it.
@ -464,8 +467,7 @@ impl<'a> Parser<'a> {
let ty = self.parse_ty_for_where_clause()?;
if self.eat(&token::Colon) {
let bounds = self.parse_generic_bounds()?;
Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
span: lo.to(self.prev_token.span),
Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
bound_generic_params: lifetime_defs,
bounded_ty: ty,
bounds,
@ -474,11 +476,7 @@ impl<'a> Parser<'a> {
// FIXME: We are just dropping the binders in lifetime_defs on the floor here.
} else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
let rhs_ty = self.parse_ty()?;
Ok(ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
span: lo.to(self.prev_token.span),
lhs_ty: ty,
rhs_ty,
}))
Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty }))
} else {
self.maybe_recover_bounds_doubled_colon(&ty)?;
self.unexpected_any()

View File

@ -360,11 +360,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) {
record_variants!((self, p, p, None, hir, WherePredicate, WherePredicate), [
BoundPredicate,
RegionPredicate,
EqPredicate
]);
record_variants!(
(self, p, p.kind, Some(p.hir_id), hir, WherePredicate, WherePredicateKind),
[BoundPredicate, RegionPredicate, EqPredicate]
);
hir_visit::walk_where_predicate(self, p)
}
@ -611,7 +610,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
record_variants!((self, p, p, None, ast, WherePredicate, WherePredicate), [
record_variants!((self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), [
BoundPredicate,
RegionPredicate,
EqPredicate

View File

@ -1268,15 +1268,14 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
debug!("visit_where_predicate {:?}", p);
let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
if let WherePredicate::BoundPredicate(WhereBoundPredicate {
ref bounded_ty,
ref bounds,
ref bound_generic_params,
span: predicate_span,
if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bounds,
bound_generic_params,
..
}) = p
}) = &p.kind
{
let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
this.with_generic_param_rib(
bound_generic_params,
RibKind::Normal,

View File

@ -1317,21 +1317,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
/// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diag<'_>) -> bool {
// Detect that we are actually in a `where` predicate.
let (bounded_ty, bounds, where_span) =
if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
bounded_ty,
bound_generic_params,
bounds,
span,
})) = self.diag_metadata.current_where_predicate
{
if !bound_generic_params.is_empty() {
return false;
}
(bounded_ty, bounds, span)
} else {
let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate {
kind:
ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
bounded_ty,
bound_generic_params,
bounds,
}),
span,
..
}) = self.diag_metadata.current_where_predicate
{
if !bound_generic_params.is_empty() {
return false;
};
}
(bounded_ty, bounds, span)
} else {
return false;
};
// Confirm that the target is an associated type.
let (ty, _, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind {
@ -2840,9 +2843,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// for<'a, 'b> T: Trait<T> + 'b
// ^^^^^^^^^^^ suggest outer binder `for<'a, 'b>`
if let LifetimeBinderKind::WhereBound = kind
&& let Some(ast::WherePredicate::BoundPredicate(
&& let Some(predicate) = self.diag_metadata.current_where_predicate
&& let ast::WherePredicateKind::BoundPredicate(
ast::WhereBoundPredicate { bounded_ty, bounds, .. },
)) = self.diag_metadata.current_where_predicate
) = &predicate.kind
&& bounded_ty.id == binder
{
for bound in bounds {
@ -3473,7 +3477,6 @@ fn mk_where_bound_predicate(
};
let new_where_bound_predicate = ast::WhereBoundPredicate {
span: DUMMY_SP,
bound_generic_params: ThinVec::new(),
bounded_ty: ast::ptr::P(ty.clone()),
bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {

View File

@ -5312,9 +5312,10 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
};
let name = tcx.item_name(proj.projection_term.def_id);
let mut predicates = generics.predicates.iter().peekable();
let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None;
let mut prev: Option<(&hir::WhereBoundPredicate<'_>, Span)> = None;
while let Some(pred) = predicates.next() {
let hir::WherePredicate::BoundPredicate(pred) = pred else {
let curr_span = pred.span;
let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind else {
continue;
};
let mut bounds = pred.bounds.iter();
@ -5340,8 +5341,8 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
.iter()
.filter(|p| {
matches!(
p,
hir::WherePredicate::BoundPredicate(p)
p.kind,
hir::WherePredicateKind::BoundPredicate(p)
if hir::PredicateOrigin::WhereClause == p.origin
)
})
@ -5351,20 +5352,21 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
// There's only one `where` bound, that needs to be removed. Remove the whole
// `where` clause.
generics.where_clause_span
} else if let Some(hir::WherePredicate::BoundPredicate(next)) = predicates.peek()
} else if let Some(next_pred) = predicates.peek()
&& let hir::WherePredicateKind::BoundPredicate(next) = next_pred.kind
&& pred.origin == next.origin
{
// There's another bound, include the comma for the current one.
pred.span.until(next.span)
} else if let Some(prev) = prev
curr_span.until(next_pred.span)
} else if let Some((prev, prev_span)) = prev
&& pred.origin == prev.origin
{
// Last bound, try to remove the previous comma.
prev.span.shrink_to_hi().to(pred.span)
prev_span.shrink_to_hi().to(curr_span)
} else if pred.origin == hir::PredicateOrigin::WhereClause {
pred.span.with_hi(generics.where_clause_span.hi())
curr_span.with_hi(generics.where_clause_span.hi())
} else {
pred.span
curr_span
};
err.span_suggestion_verbose(
@ -5417,7 +5419,7 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
);
}
}
prev = Some(pred);
prev = Some((pred, curr_span));
}
}

View File

@ -150,8 +150,8 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
.predicates
.iter()
.filter_map(|pred| {
match pred {
hir::WherePredicate::BoundPredicate(pred)
match pred.kind {
hir::WherePredicateKind::BoundPredicate(pred)
if pred.bounded_ty.hir_id.owner.to_def_id() == trait_def_id =>
{
// Fetch spans for trait bounds that are Sized:

View File

@ -325,11 +325,11 @@ fn clean_where_predicate<'tcx>(
predicate: &hir::WherePredicate<'tcx>,
cx: &mut DocContext<'tcx>,
) -> Option<WherePredicate> {
if !predicate.in_where_clause() {
if !predicate.kind.in_where_clause() {
return None;
}
Some(match *predicate {
hir::WherePredicate::BoundPredicate(ref wbp) => {
Some(match *predicate.kind {
hir::WherePredicateKind::BoundPredicate(ref wbp) => {
let bound_params = wbp
.bound_generic_params
.iter()
@ -342,12 +342,12 @@ fn clean_where_predicate<'tcx>(
}
}
hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
hir::WherePredicateKind::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
lifetime: clean_lifetime(wrp.lifetime, cx),
bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
},
hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
hir::WherePredicateKind::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
lhs: clean_ty(wrp.lhs_ty, cx),
rhs: clean_ty(wrp.rhs_ty, cx).into(),
},

View File

@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
use rustc_hir::{
BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
PredicateOrigin, Ty, WherePredicate,
PredicateOrigin, Ty, WherePredicate, WherePredicateKind
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
@ -205,12 +205,13 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
}
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
if let WherePredicate::BoundPredicate(predicate) = predicate {
let span = predicate.span;
if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind {
// Collect spans for any bounds on type parameters.
if let Some((def_id, _)) = predicate.bounded_ty.peel_refs().as_generic_param() {
match predicate.origin {
PredicateOrigin::GenericParam => {
self.inline_bounds.insert(def_id, predicate.span);
self.inline_bounds.insert(def_id, span);
},
PredicateOrigin::WhereClause => {
self.where_bounds.insert(def_id);

View File

@ -4,7 +4,7 @@ use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::DefId;
use rustc_hir::{
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
WherePredicate,
WherePredicateKind,
};
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
@ -324,7 +324,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) {
for predicate in generics.predicates {
if let WherePredicate::BoundPredicate(predicate) = predicate
if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind
// In theory, the origin doesn't really matter,
// we *could* also lint on explicit where clauses written out by the user,
// not just impl trait desugared ones, but that contradicts with the lint name...

View File

@ -12,7 +12,7 @@ use rustc_hir::intravisit::{
use rustc_hir::{
BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, lang_items,
PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, WherePredicateKind, lang_items,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
@ -442,9 +442,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
/// reason about elision.
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) => {
match *predicate.kind {
WherePredicateKind::RegionPredicate(..) => return true,
WherePredicateKind::BoundPredicate(ref pred) => {
// a predicate like F: Trait or F: for<'a> Trait<'a>
let mut visitor = RefVisitor::new(cx);
// walk the type F, it may not contain LT refs
@ -467,7 +467,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
}
}
},
WherePredicate::EqPredicate(ref pred) => {
WherePredicateKind::EqPredicate(ref pred) => {
let mut visitor = RefVisitor::new(cx);
walk_ty(&mut visitor, pred.lhs_ty);
walk_ty(&mut visitor, pred.rhs_ty);

View File

@ -1,5 +1,5 @@
use rustc_ast::visit::FnKind;
use rustc_ast::{NodeId, WherePredicate};
use rustc_ast::{NodeId, WherePredicateKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::declare_lint_pass;
@ -51,8 +51,8 @@ impl EarlyLintPass for MultipleBoundLocations {
}
}
for clause in &generics.where_clause.predicates {
match clause {
WherePredicate::BoundPredicate(pred) => {
match &clause.kind {
WherePredicateKind::BoundPredicate(pred) => {
if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty())
&& let Some(Some(bound_span)) = pred
.bounded_ty
@ -62,14 +62,14 @@ impl EarlyLintPass for MultipleBoundLocations {
emit_lint(cx, *bound_span, pred.bounded_ty.span);
}
},
WherePredicate::RegionPredicate(pred) => {
WherePredicateKind::RegionPredicate(pred) => {
if !pred.bounds.is_empty()
&& let Some(bound_span) = generic_params_with_bounds.get(&pred.lifetime.ident.name.as_str())
{
emit_lint(cx, *bound_span, pred.lifetime.ident.span);
}
},
WherePredicate::EqPredicate(_) => {},
WherePredicateKind::EqPredicate(_) => {},
}
}
}

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::Applicability;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate};
use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{ClauseKind, PredicatePolarity};
use rustc_session::declare_lint_pass;
@ -52,7 +52,7 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item
.iter()
.enumerate()
.filter_map(|(predicate_pos, predicate)| {
let WherePredicate::BoundPredicate(bound_predicate) = predicate else {
let WherePredicateKind::BoundPredicate(bound_predicate) = &predicate.kind else {
return None;
};

View File

@ -11,7 +11,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{
BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
@ -124,9 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
let mut self_bounds_map = FxHashMap::default();
for predicate in item.generics.predicates {
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
&& bound_predicate.origin != PredicateOrigin::ImplTrait
&& !bound_predicate.span.from_expansion()
&& !predicate.span.from_expansion()
&& let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind
&& let Some(PathSegment {
res: Res::SelfTyParam { trait_: def_id },
@ -268,10 +268,10 @@ impl TraitBounds {
let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
let mut applicability = Applicability::MaybeIncorrect;
for bound in generics.predicates {
if let WherePredicate::BoundPredicate(p) = bound
if let WherePredicateKind::BoundPredicate(p) = bound.kind
&& p.origin != PredicateOrigin::ImplTrait
&& p.bounds.len() as u64 <= self.max_trait_bounds
&& !p.span.from_expansion()
&& !bound.span.from_expansion()
&& let bounds = p
.bounds
.iter()
@ -295,7 +295,7 @@ impl TraitBounds {
span_lint_and_help(
cx,
TYPE_REPETITION_IN_BOUNDS,
p.span,
bound.span,
"this type has already been used as a bound predicate",
None,
hint_string,
@ -322,8 +322,8 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
.predicates
.iter()
.filter_map(|pred| {
if pred.in_where_clause()
&& let WherePredicate::BoundPredicate(bound_predicate) = pred
if pred.kind.in_where_clause()
&& let WherePredicateKind::BoundPredicate(bound_predicate) = pred.kind
&& let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
{
return Some(
@ -347,10 +347,10 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
// |
// compare trait bounds keyed by generic name and comparable trait to collected where
// predicates eg. (T, Clone)
for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) {
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
for predicate in generics.predicates.iter().filter(|pred| !pred.kind.in_where_clause()) {
if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
&& bound_predicate.origin != PredicateOrigin::ImplTrait
&& !bound_predicate.span.from_expansion()
&& !predicate.span.from_expansion()
&& let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
{
let traits = rollup_traits(cx, bound_predicate.bounds, "these bounds contain repeated elements");

View File

@ -661,8 +661,8 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
}
pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
use WherePredicate::*;
match (l, r) {
use WherePredicateKind::*;
match (&l.kind, &r.kind) {
(BoundPredicate(l), BoundPredicate(r)) => {
over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
eq_generic_param(l, r)

View File

@ -150,11 +150,7 @@ impl Spanned for ast::FieldDef {
impl Spanned for ast::WherePredicate {
fn span(&self) -> Span {
match *self {
ast::WherePredicate::BoundPredicate(ref p) => p.span,
ast::WherePredicate::RegionPredicate(ref p) => p.span,
ast::WherePredicate::EqPredicate(ref p) => p.span,
}
self.span
}
}

View File

@ -463,8 +463,8 @@ impl Rewrite for ast::WherePredicate {
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
// FIXME: dead spans?
let result = match *self {
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
let result = match self.kind {
ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
ref bound_generic_params,
ref bounded_ty,
ref bounds,
@ -482,12 +482,11 @@ impl Rewrite for ast::WherePredicate {
rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)?
}
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
ref lifetime,
ref bounds,
span,
}) => rewrite_bounded_lifetime(lifetime, bounds, span, context, shape)?,
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
}) => rewrite_bounded_lifetime(lifetime, bounds, self.span, context, shape)?,
ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate {
ref lhs_ty,
ref rhs_ty,
..

View File

@ -5,11 +5,11 @@ ast-stats-1 Crate 40 ( 0.6%) 1 40
ast-stats-1 GenericArgs 40 ( 0.6%) 1 40
ast-stats-1 - AngleBracketed 40 ( 0.6%) 1
ast-stats-1 ExprField 48 ( 0.7%) 1 48
ast-stats-1 WherePredicate 56 ( 0.8%) 1 56
ast-stats-1 - BoundPredicate 56 ( 0.8%) 1
ast-stats-1 Attribute 64 ( 1.0%) 2 32
ast-stats-1 - DocComment 32 ( 0.5%) 1
ast-stats-1 - Normal 32 ( 0.5%) 1
ast-stats-1 WherePredicate 64 ( 1.0%) 1 64
ast-stats-1 - BoundPredicate 64 ( 1.0%) 1
ast-stats-1 Local 80 ( 1.2%) 1 80
ast-stats-1 ForeignItem 88 ( 1.3%) 1 88
ast-stats-1 - Fn 88 ( 1.3%) 1
@ -33,14 +33,14 @@ ast-stats-1 Pat 504 ( 7.6%) 7 72
ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Wild 72 ( 1.1%) 1
ast-stats-1 - Ident 360 ( 5.4%) 5
ast-stats-1 Expr 576 ( 8.7%) 8 72
ast-stats-1 Expr 576 ( 8.6%) 8 72
ast-stats-1 - Path 72 ( 1.1%) 1
ast-stats-1 - Match 72 ( 1.1%) 1
ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Lit 144 ( 2.2%) 2
ast-stats-1 - Block 216 ( 3.2%) 3
ast-stats-1 PathSegment 744 (11.2%) 31 24
ast-stats-1 Ty 896 (13.5%) 14 64
ast-stats-1 Ty 896 (13.4%) 14 64
ast-stats-1 - Ref 64 ( 1.0%) 1
ast-stats-1 - Ptr 64 ( 1.0%) 1
ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2
@ -53,7 +53,7 @@ ast-stats-1 - Enum 136 ( 2.0%) 1
ast-stats-1 - Fn 272 ( 4.1%) 2
ast-stats-1 - Use 408 ( 6.1%) 3
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 6_656 116
ast-stats-1 Total 6_664 116
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
@ -62,8 +62,8 @@ ast-stats-2 Crate 40 ( 0.5%) 1 40
ast-stats-2 GenericArgs 40 ( 0.5%) 1 40
ast-stats-2 - AngleBracketed 40 ( 0.5%) 1
ast-stats-2 ExprField 48 ( 0.7%) 1 48
ast-stats-2 WherePredicate 56 ( 0.8%) 1 56
ast-stats-2 - BoundPredicate 56 ( 0.8%) 1
ast-stats-2 WherePredicate 64 ( 0.9%) 1 64
ast-stats-2 - BoundPredicate 64 ( 0.9%) 1
ast-stats-2 Local 80 ( 1.1%) 1 80
ast-stats-2 ForeignItem 88 ( 1.2%) 1 88
ast-stats-2 - Fn 88 ( 1.2%) 1
@ -113,7 +113,7 @@ ast-stats-2 - ForeignMod 136 ( 1.9%) 1
ast-stats-2 - Fn 272 ( 3.7%) 2
ast-stats-2 - Use 544 ( 7.4%) 4
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 7_304 127
ast-stats-2 Total 7_312 127
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
@ -131,48 +131,48 @@ hir-stats Param 64 ( 0.7%) 2 32
hir-stats Body 72 ( 0.8%) 3 24
hir-stats ImplItemRef 72 ( 0.8%) 2 36
hir-stats InlineAsm 72 ( 0.8%) 1 72
hir-stats WherePredicate 72 ( 0.8%) 3 24
hir-stats - BoundPredicate 72 ( 0.8%) 3
hir-stats Arm 80 ( 0.9%) 2 40
hir-stats Stmt 96 ( 1.1%) 3 32
hir-stats - Let 32 ( 0.4%) 1
hir-stats - Semi 32 ( 0.4%) 1
hir-stats - Expr 32 ( 0.4%) 1
hir-stats FieldDef 112 ( 1.2%) 2 56
hir-stats FieldDef 112 ( 1.3%) 2 56
hir-stats FnDecl 120 ( 1.3%) 3 40
hir-stats Attribute 128 ( 1.4%) 4 32
hir-stats GenericArgs 144 ( 1.6%) 3 48
hir-stats Variant 144 ( 1.6%) 2 72
hir-stats WherePredicate 192 ( 2.1%) 3 64
hir-stats - BoundPredicate 192 ( 2.1%) 3
hir-stats GenericBound 256 ( 2.8%) 4 64
hir-stats - Trait 256 ( 2.8%) 4
hir-stats GenericBound 256 ( 2.9%) 4 64
hir-stats - Trait 256 ( 2.9%) 4
hir-stats Block 288 ( 3.2%) 6 48
hir-stats GenericParam 360 ( 4.0%) 5 72
hir-stats Pat 360 ( 4.0%) 5 72
hir-stats - Struct 72 ( 0.8%) 1
hir-stats - Wild 72 ( 0.8%) 1
hir-stats - Binding 216 ( 2.4%) 3
hir-stats Generics 560 ( 6.2%) 10 56
hir-stats Ty 720 ( 8.0%) 15 48
hir-stats Generics 560 ( 6.3%) 10 56
hir-stats Ty 720 ( 8.1%) 15 48
hir-stats - Ref 48 ( 0.5%) 1
hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Path 624 ( 6.9%) 13
hir-stats Expr 768 ( 8.5%) 12 64
hir-stats - Path 624 ( 7.0%) 13
hir-stats Expr 768 ( 8.6%) 12 64
hir-stats - Path 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - Struct 64 ( 0.7%) 1
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Lit 128 ( 1.4%) 2
hir-stats - Block 384 ( 4.2%) 6
hir-stats Item 968 (10.7%) 11 88
hir-stats - Block 384 ( 4.3%) 6
hir-stats Item 968 (10.9%) 11 88
hir-stats - Enum 88 ( 1.0%) 1
hir-stats - Trait 88 ( 1.0%) 1
hir-stats - Impl 88 ( 1.0%) 1
hir-stats - ExternCrate 88 ( 1.0%) 1
hir-stats - ForeignMod 88 ( 1.0%) 1
hir-stats - Fn 176 ( 1.9%) 2
hir-stats - Fn 176 ( 2.0%) 2
hir-stats - Use 352 ( 3.9%) 4
hir-stats Path 1_240 (13.7%) 31 40
hir-stats PathSegment 1_920 (21.2%) 40 48
hir-stats Path 1_240 (13.9%) 31 40
hir-stats PathSegment 1_920 (21.5%) 40 48
hir-stats ----------------------------------------------------------------
hir-stats Total 9_040 180
hir-stats Total 8_920 180
hir-stats