Skip to content

Commit db35ed6

Browse files
committed
Implment #[cfg] and #[cfg_attr] in where clauses
1 parent f8a913b commit db35ed6

File tree

39 files changed

+7125
-90
lines changed

39 files changed

+7125
-90
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ impl WhereClause {
417417
/// A single predicate in a where-clause.
418418
#[derive(Clone, Encodable, Decodable, Debug)]
419419
pub struct WherePredicate {
420+
pub attrs: AttrVec,
420421
pub kind: WherePredicateKind,
421422
pub id: NodeId,
422423
pub span: Span,
@@ -431,6 +432,8 @@ pub enum WherePredicateKind {
431432
RegionPredicate(WhereRegionPredicate),
432433
/// An equality predicate (unsupported).
433434
EqPredicate(WhereEqPredicate),
435+
/// A macro invocation,
436+
MacCall(P<MacCall>),
434437
}
435438

436439
/// A type bound.

compiler/rustc_ast/src/ast_traits.rs

Lines changed: 13 additions & 2 deletions
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> {
@@ -285,6 +295,7 @@ impl_has_attrs!(
285295
Param,
286296
PatField,
287297
Variant,
298+
WherePredicate,
288299
);
289300
impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
290301

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,11 @@ pub trait MutVisitor: Sized {
338338
walk_where_clause(self, where_clause);
339339
}
340340

341-
fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
342-
walk_where_predicate(self, where_predicate)
341+
fn flat_map_where_predicate(
342+
&mut self,
343+
where_predicate: WherePredicate,
344+
) -> SmallVec<[WherePredicate; 1]> {
345+
walk_flat_map_where_predicate(self, where_predicate)
343346
}
344347

345348
fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
@@ -1105,15 +1108,20 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
11051108

11061109
fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
11071110
let WhereClause { has_where_token: _, predicates, span } = wc;
1108-
visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
1111+
predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
11091112
vis.visit_span(span);
11101113
}
11111114

1112-
pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
1113-
let WherePredicate { kind, id, span } = pred;
1115+
pub fn walk_flat_map_where_predicate<T: MutVisitor>(
1116+
vis: &mut T,
1117+
mut pred: WherePredicate,
1118+
) -> SmallVec<[WherePredicate; 1]> {
1119+
let WherePredicate { attrs, kind, id, span } = &mut pred;
11141120
vis.visit_id(id);
1121+
visit_attrs(vis, attrs);
11151122
vis.visit_where_predicate_kind(kind);
11161123
vis.visit_span(span);
1124+
smallvec![pred]
11171125
}
11181126

11191127
pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
@@ -1134,6 +1142,7 @@ pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePre
11341142
vis.visit_ty(lhs_ty);
11351143
vis.visit_ty(rhs_ty);
11361144
}
1145+
WherePredicateKind::MacCall(m) => vis.visit_mac_call(m),
11371146
}
11381147
}
11391148

compiler/rustc_ast/src/visit.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
833833
visitor: &mut V,
834834
predicate: &'a WherePredicate,
835835
) -> V::Result {
836-
let WherePredicate { kind, id: _, span: _ } = predicate;
836+
let WherePredicate { attrs, kind, id: _, span: _ } = predicate;
837+
walk_list!(visitor, visit_attribute, attrs);
837838
visitor.visit_where_predicate_kind(kind)
838839
}
839840

@@ -859,6 +860,9 @@ pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>(
859860
try_visit!(visitor.visit_ty(lhs_ty));
860861
try_visit!(visitor.visit_ty(rhs_ty));
861862
}
863+
WherePredicateKind::MacCall(mac) => {
864+
try_visit!(visitor.visit_mac_call(mac));
865+
}
862866
}
863867
V::Result::output()
864868
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17271727
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
17281728
let hir_id = self.lower_node_id(pred.id);
17291729
let span = self.lower_span(pred.span);
1730+
self.lower_attrs(hir_id, &pred.attrs);
17301731
let kind = self.arena.alloc(match &pred.kind {
17311732
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
17321733
bound_generic_params,
@@ -1761,6 +1762,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17611762
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
17621763
})
17631764
}
1765+
WherePredicateKind::MacCall(_) => panic!("macro shouldn't exist here"),
17641766
});
17651767
hir::WherePredicate { hir_id, span, kind }
17661768
}

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
515515
gate_all!(unsafe_binders, "unsafe binder types are experimental");
516516
gate_all!(contracts, "contracts are incomplete");
517517
gate_all!(contracts_internals, "contract internal machinery is for internal use only");
518+
gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
518519

519520
if !visitor.features.never_patterns() {
520521
if let Some(spans) = spans.get(&sym::never_patterns) {

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,8 @@ impl<'a> State<'a> {
735735
}
736736

737737
pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
738-
let ast::WherePredicate { kind, id: _, span: _ } = predicate;
738+
let ast::WherePredicate { attrs, kind, id: _, span: _ } = predicate;
739+
self.print_outer_attributes(attrs);
739740
match kind {
740741
ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
741742
self.print_where_bound_predicate(where_bound_predicate);
@@ -760,6 +761,12 @@ impl<'a> State<'a> {
760761
self.word_space("=");
761762
self.print_type(rhs_ty);
762763
}
764+
ast::WherePredicateKind::MacCall(m) => {
765+
self.print_mac(m);
766+
if m.args.need_semicolon() {
767+
self.word(";");
768+
}
769+
}
763770
}
764771
}
765772

compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,15 @@ pub(crate) fn expand_deriving_coerce_pointee(
300300
to_ty: &s_ty,
301301
rewritten: false,
302302
};
303-
let mut predicate = ast::WherePredicate {
304-
kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
305-
span: predicate.span,
306-
id: ast::DUMMY_NODE_ID,
307-
};
308-
substitution.visit_where_predicate(&mut predicate);
303+
let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone());
304+
substitution.visit_where_predicate_kind(&mut kind);
309305
if substitution.rewritten {
306+
let predicate = ast::WherePredicate {
307+
attrs: predicate.attrs.clone(),
308+
kind,
309+
span: predicate.span,
310+
id: ast::DUMMY_NODE_ID,
311+
};
310312
impl_generics.where_clause.predicates.push(predicate);
311313
}
312314
}
@@ -388,8 +390,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
388390
}
389391
}
390392

391-
fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
392-
match &mut where_predicate.kind {
393+
fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) {
394+
match kind {
393395
rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
394396
bound
395397
.bound_generic_params
@@ -400,7 +402,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
400402
}
401403
}
402404
rustc_ast::WherePredicateKind::RegionPredicate(_)
403-
| rustc_ast::WherePredicateKind::EqPredicate(_) => {}
405+
| rustc_ast::WherePredicateKind::EqPredicate(_)
406+
| rustc_ast::WherePredicateKind::MacCall(_) => {}
404407
}
405408
}
406409
}

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ impl<'a> TraitDef<'a> {
690690
// and similarly for where clauses
691691
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
692692
ast::WherePredicate {
693+
attrs: clause.attrs.clone(),
693694
kind: clause.kind.clone(),
694695
id: ast::DUMMY_NODE_ID,
695696
span: clause.span.with_ctxt(ctxt),
@@ -747,8 +748,12 @@ impl<'a> TraitDef<'a> {
747748
};
748749

749750
let kind = ast::WherePredicateKind::BoundPredicate(predicate);
750-
let predicate =
751-
ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
751+
let predicate = ast::WherePredicate {
752+
attrs: ThinVec::new(),
753+
kind,
754+
id: ast::DUMMY_NODE_ID,
755+
span: self.span,
756+
};
752757
where_clause.predicates.push(predicate);
753758
}
754759
}

compiler/rustc_expand/src/base.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub enum Annotatable {
5252
Param(ast::Param),
5353
FieldDef(ast::FieldDef),
5454
Variant(ast::Variant),
55+
WherePredicate(ast::WherePredicate),
5556
Crate(ast::Crate),
5657
}
5758

@@ -70,6 +71,7 @@ impl Annotatable {
7071
Annotatable::Param(p) => p.span,
7172
Annotatable::FieldDef(sf) => sf.span,
7273
Annotatable::Variant(v) => v.span,
74+
Annotatable::WherePredicate(wp) => wp.span,
7375
Annotatable::Crate(c) => c.spans.inner_span,
7476
}
7577
}
@@ -88,6 +90,7 @@ impl Annotatable {
8890
Annotatable::Param(p) => p.visit_attrs(f),
8991
Annotatable::FieldDef(sf) => sf.visit_attrs(f),
9092
Annotatable::Variant(v) => v.visit_attrs(f),
93+
Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
9194
Annotatable::Crate(c) => c.visit_attrs(f),
9295
}
9396
}
@@ -106,6 +109,7 @@ impl Annotatable {
106109
Annotatable::Param(p) => visitor.visit_param(p),
107110
Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
108111
Annotatable::Variant(v) => visitor.visit_variant(v),
112+
Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
109113
Annotatable::Crate(c) => visitor.visit_crate(c),
110114
}
111115
}
@@ -127,6 +131,7 @@ impl Annotatable {
127131
| Annotatable::Param(..)
128132
| Annotatable::FieldDef(..)
129133
| Annotatable::Variant(..)
134+
| Annotatable::WherePredicate(..)
130135
| Annotatable::Crate(..) => panic!("unexpected annotatable"),
131136
}
132137
}
@@ -222,6 +227,13 @@ impl Annotatable {
222227
}
223228
}
224229

230+
pub fn expect_where_predicate(self) -> ast::WherePredicate {
231+
match self {
232+
Annotatable::WherePredicate(wp) => wp,
233+
_ => panic!("expected where predicate"),
234+
}
235+
}
236+
225237
pub fn expect_crate(self) -> ast::Crate {
226238
match self {
227239
Annotatable::Crate(krate) => krate,
@@ -445,6 +457,10 @@ pub trait MacResult {
445457
None
446458
}
447459

460+
fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
461+
None
462+
}
463+
448464
fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
449465
// Fn-like macros cannot produce a crate.
450466
unreachable!()

0 commit comments

Comments
 (0)