Skip to content

Commit 6b5f780

Browse files
committed
Implment #[cfg] in where clauses
1 parent 8aca4ba commit 6b5f780

File tree

48 files changed

+1298
-262
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1298
-262
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,27 @@ impl Default for WhereClause {
422422

423423
/// A single predicate in a where-clause.
424424
#[derive(Clone, Encodable, Decodable, Debug)]
425-
pub enum WherePredicate {
425+
pub struct WherePredicate {
426+
pub attrs: AttrVec,
427+
pub kind: WherePredicateKind,
428+
pub id: NodeId,
429+
}
430+
431+
impl WherePredicate {
432+
pub fn with_kind(&self, kind: WherePredicateKind) -> WherePredicate {
433+
self.map_kind(|_| kind)
434+
}
435+
pub fn map_kind(
436+
&self,
437+
f: impl FnOnce(&WherePredicateKind) -> WherePredicateKind,
438+
) -> WherePredicate {
439+
WherePredicate { attrs: self.attrs.clone(), kind: f(&self.kind), id: DUMMY_NODE_ID }
440+
}
441+
}
442+
443+
/// Predicate kind in where-clause.
444+
#[derive(Clone, Encodable, Decodable, Debug)]
445+
pub enum WherePredicateKind {
426446
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
427447
BoundPredicate(WhereBoundPredicate),
428448
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
@@ -431,12 +451,12 @@ pub enum WherePredicate {
431451
EqPredicate(WhereEqPredicate),
432452
}
433453

434-
impl WherePredicate {
454+
impl WherePredicateKind {
435455
pub fn span(&self) -> Span {
436456
match self {
437-
WherePredicate::BoundPredicate(p) => p.span,
438-
WherePredicate::RegionPredicate(p) => p.span,
439-
WherePredicate::EqPredicate(p) => p.span,
457+
WherePredicateKind::BoundPredicate(p) => p.span,
458+
WherePredicateKind::RegionPredicate(p) => p.span,
459+
WherePredicateKind::EqPredicate(p) => p.span,
440460
}
441461
}
442462
}

Diff for: compiler/rustc_ast/src/ast_traits.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::tokenstream::LazyAttrTokenStream;
1111
use crate::{
1212
Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField,
1313
FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind,
14-
Ty, Variant, Visibility,
14+
Ty, Variant, Visibility, WherePredicate,
1515
};
1616

1717
/// A utility trait to reduce boilerplate.
@@ -79,6 +79,7 @@ impl_has_node_id!(
7979
Stmt,
8080
Ty,
8181
Variant,
82+
WherePredicate,
8283
);
8384

8485
impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T {
@@ -127,7 +128,16 @@ macro_rules! impl_has_tokens_none {
127128
}
128129

129130
impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility);
130-
impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
131+
impl_has_tokens_none!(
132+
Arm,
133+
ExprField,
134+
FieldDef,
135+
GenericParam,
136+
Param,
137+
PatField,
138+
Variant,
139+
WherePredicate
140+
);
131141

132142
impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
133143
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
@@ -289,6 +299,7 @@ impl_has_attrs!(
289299
Param,
290300
PatField,
291301
Variant,
302+
WherePredicate,
292303
);
293304
impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
294305

Diff for: compiler/rustc_ast/src/mut_visit.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,11 @@ pub trait MutVisitor: Sized {
286286
walk_where_clause(self, where_clause);
287287
}
288288

289-
fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
290-
walk_where_predicate(self, where_predicate);
289+
fn filter_map_where_predicate(
290+
&mut self,
291+
where_predicate: WherePredicate,
292+
) -> Option<WherePredicate> {
293+
walk_filter_map_where_predicate(self, where_predicate)
291294
}
292295

293296
fn visit_vis(&mut self, vis: &mut Visibility) {
@@ -987,32 +990,39 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
987990

988991
fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
989992
let WhereClause { has_where_token: _, predicates, span } = wc;
990-
visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
993+
predicates.flat_map_in_place(|predicate| vis.filter_map_where_predicate(predicate));
991994
vis.visit_span(span);
992995
}
993996

994-
fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
995-
match pred {
996-
WherePredicate::BoundPredicate(bp) => {
997+
pub fn walk_filter_map_where_predicate<T: MutVisitor>(
998+
vis: &mut T,
999+
mut pred: WherePredicate,
1000+
) -> Option<WherePredicate> {
1001+
let WherePredicate { ref mut attrs, ref mut kind, ref mut id } = pred;
1002+
vis.visit_id(id);
1003+
visit_attrs(vis, attrs);
1004+
match kind {
1005+
WherePredicateKind::BoundPredicate(bp) => {
9971006
let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
9981007
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
9991008
vis.visit_ty(bounded_ty);
10001009
visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
10011010
vis.visit_span(span);
10021011
}
1003-
WherePredicate::RegionPredicate(rp) => {
1012+
WherePredicateKind::RegionPredicate(rp) => {
10041013
let WhereRegionPredicate { span, lifetime, bounds } = rp;
10051014
vis.visit_lifetime(lifetime);
10061015
visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
10071016
vis.visit_span(span);
10081017
}
1009-
WherePredicate::EqPredicate(ep) => {
1018+
WherePredicateKind::EqPredicate(ep) => {
10101019
let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
10111020
vis.visit_ty(lhs_ty);
10121021
vis.visit_ty(rhs_ty);
10131022
vis.visit_span(span);
10141023
}
10151024
}
1025+
Some(pred)
10161026
}
10171027

10181028
fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) {

Diff for: compiler/rustc_ast/src/visit.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,10 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
789789
visitor: &mut V,
790790
predicate: &'a WherePredicate,
791791
) -> V::Result {
792-
match predicate {
793-
WherePredicate::BoundPredicate(WhereBoundPredicate {
792+
let WherePredicate { attrs, kind, id: _ } = predicate;
793+
walk_list!(visitor, visit_attribute, attrs);
794+
match kind {
795+
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
794796
bounded_ty,
795797
bounds,
796798
bound_generic_params,
@@ -800,11 +802,11 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
800802
try_visit!(visitor.visit_ty(bounded_ty));
801803
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
802804
}
803-
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => {
805+
WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => {
804806
try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
805807
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
806808
}
807-
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => {
809+
WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => {
808810
try_visit!(visitor.visit_ty(lhs_ty));
809811
try_visit!(visitor.visit_ty(rhs_ty));
810812
}

Diff for: compiler/rustc_ast_lowering/src/index.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
381381
}
382382

383383
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
384-
match predicate {
385-
WherePredicate::BoundPredicate(pred) => {
384+
self.insert(predicate.span(), predicate.hir_id, Node::WherePredicate(predicate));
385+
match predicate.kind {
386+
WherePredicateKind::BoundPredicate(pred) => {
386387
self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
387388
self.with_parent(pred.hir_id, |this| {
388389
intravisit::walk_where_predicate(this, predicate)

Diff for: compiler/rustc_ast_lowering/src/item.rs

+32-25
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14751475
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
14761476
// checks both param bounds and where clauses for `?Sized`.
14771477
for pred in &generics.where_clause.predicates {
1478-
let WherePredicate::BoundPredicate(bound_pred) = pred else {
1478+
let WherePredicateKind::BoundPredicate(ref bound_pred) = pred.kind else {
14791479
continue;
14801480
};
14811481
let compute_is_param = || {
@@ -1705,8 +1705,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
17051705
});
17061706
let span = self.lower_span(span);
17071707

1708-
match kind {
1709-
GenericParamKind::Const { .. } => None,
1708+
let kind = match kind {
1709+
GenericParamKind::Const { .. } => return None,
17101710
GenericParamKind::Type { .. } => {
17111711
let def_id = self.local_def_id(id).to_def_id();
17121712
let hir_id = self.next_id();
@@ -1721,37 +1721,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
17211721
let ty_id = self.next_id();
17221722
let bounded_ty =
17231723
self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
1724-
Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1724+
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
17251725
hir_id: self.next_id(),
17261726
bounded_ty: self.arena.alloc(bounded_ty),
17271727
bounds,
17281728
span,
17291729
bound_generic_params: &[],
17301730
origin,
1731-
}))
1731+
})
17321732
}
17331733
GenericParamKind::Lifetime => {
17341734
let ident = self.lower_ident(ident);
17351735
let lt_id = self.next_node_id();
17361736
let lifetime = self.new_named_lifetime(id, lt_id, ident);
1737-
Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1737+
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
17381738
lifetime,
17391739
span,
17401740
bounds,
17411741
in_where_clause: false,
1742-
}))
1742+
})
17431743
}
1744-
}
1744+
};
1745+
Some(hir::WherePredicate { hir_id: self.next_id(), kind: self.arena.alloc(kind) })
17451746
}
17461747

17471748
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
1748-
match pred {
1749-
WherePredicate::BoundPredicate(WhereBoundPredicate {
1749+
let hir_id = self.lower_node_id(pred.id);
1750+
self.lower_attrs(hir_id, &pred.attrs);
1751+
let kind = match &pred.kind {
1752+
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
17501753
bound_generic_params,
17511754
bounded_ty,
17521755
bounds,
17531756
span,
1754-
}) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1757+
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
17551758
hir_id: self.next_id(),
17561759
bound_generic_params: self
17571760
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
@@ -1764,26 +1767,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
17641767
span: self.lower_span(*span),
17651768
origin: PredicateOrigin::WhereClause,
17661769
}),
1767-
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => {
1768-
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1769-
span: self.lower_span(*span),
1770-
lifetime: self.lower_lifetime(lifetime),
1771-
bounds: self.lower_param_bounds(
1772-
bounds,
1773-
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1774-
),
1775-
in_where_clause: true,
1776-
})
1777-
}
1778-
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
1779-
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1770+
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
1771+
lifetime,
1772+
bounds,
1773+
span,
1774+
}) => hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1775+
span: self.lower_span(*span),
1776+
lifetime: self.lower_lifetime(lifetime),
1777+
bounds: self.lower_param_bounds(
1778+
bounds,
1779+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1780+
),
1781+
in_where_clause: true,
1782+
}),
1783+
WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
1784+
hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
17801785
lhs_ty: self
17811786
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
17821787
rhs_ty: self
17831788
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
17841789
span: self.lower_span(*span),
17851790
})
17861791
}
1787-
}
1792+
};
1793+
let kind = self.arena.alloc(kind);
1794+
hir::WherePredicate { hir_id, kind }
17881795
}
17891796
}

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1247,14 +1247,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12471247
validate_generic_param_order(self.dcx(), &generics.params, generics.span);
12481248

12491249
for predicate in &generics.where_clause.predicates {
1250-
if let WherePredicate::EqPredicate(predicate) = predicate {
1250+
if let WherePredicateKind::EqPredicate(ref predicate) = predicate.kind {
12511251
deny_equality_constraints(self, predicate, generics);
12521252
}
12531253
}
12541254
walk_list!(self, visit_generic_param, &generics.params);
12551255
for predicate in &generics.where_clause.predicates {
1256-
match predicate {
1257-
WherePredicate::BoundPredicate(bound_pred) => {
1256+
match predicate.kind {
1257+
WherePredicateKind::BoundPredicate(ref bound_pred) => {
12581258
// This is slightly complicated. Our representation for poly-trait-refs contains a single
12591259
// binder and thus we only allow a single level of quantification. However,
12601260
// the syntax of Rust permits quantification in two places in where clauses,
@@ -1638,18 +1638,18 @@ fn deny_equality_constraints(
16381638
let mut preds = generics.where_clause.predicates.iter().peekable();
16391639
// Find the predicate that shouldn't have been in the where bound list.
16401640
while let Some(pred) = preds.next() {
1641-
if let WherePredicate::EqPredicate(pred) = pred
1641+
if let WherePredicateKind::EqPredicate(ref pred) = pred.kind
16421642
&& pred.span == predicate.span
16431643
{
16441644
if let Some(next) = preds.peek() {
16451645
// This is the first predicate, remove the trailing comma as well.
1646-
span = span.with_hi(next.span().lo());
1646+
span = span.with_hi(next.kind.span().lo());
16471647
} else if let Some(prev) = prev {
16481648
// Remove the previous comma as well.
16491649
span = span.with_lo(prev.hi());
16501650
}
16511651
}
1652-
prev = Some(pred.span());
1652+
prev = Some(pred.kind.span());
16531653
}
16541654
span
16551655
};
@@ -1666,8 +1666,8 @@ fn deny_equality_constraints(
16661666
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
16671667
// Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
16681668
for bounds in generics.params.iter().map(|p| &p.bounds).chain(
1669-
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
1670-
WherePredicate::BoundPredicate(p) => Some(&p.bounds),
1669+
generics.where_clause.predicates.iter().filter_map(|pred| match pred.kind {
1670+
WherePredicateKind::BoundPredicate(ref p) => Some(&p.bounds),
16711671
_ => None,
16721672
}),
16731673
) {
@@ -1690,8 +1690,8 @@ fn deny_equality_constraints(
16901690
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
16911691
if let [potential_param, potential_assoc] = &full_path.segments[..] {
16921692
for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain(
1693-
generics.where_clause.predicates.iter().filter_map(|pred| match pred {
1694-
WherePredicate::BoundPredicate(p)
1693+
generics.where_clause.predicates.iter().filter_map(|pred| match pred.kind {
1694+
WherePredicateKind::BoundPredicate(ref p)
16951695
if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind
16961696
&& let [segment] = &path.segments[..] =>
16971697
{

Diff for: compiler/rustc_ast_passes/src/feature_gate.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
344344

345345
fn visit_generics(&mut self, g: &'a ast::Generics) {
346346
for predicate in &g.where_clause.predicates {
347-
match predicate {
348-
ast::WherePredicate::BoundPredicate(bound_pred) => {
347+
visit::walk_list!(self, visit_attribute, &predicate.attrs);
348+
match predicate.kind {
349+
ast::WherePredicateKind::BoundPredicate(ref bound_pred) => {
349350
// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
350351
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
351352
}

0 commit comments

Comments
 (0)