Skip to content

Commit d0cdfab

Browse files
committed
Implment #[cfg] in where clauses
1 parent 78668c5 commit d0cdfab

File tree

32 files changed

+1566
-66
lines changed

32 files changed

+1566
-66
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ impl Default for WhereClause {
429429
/// A single predicate in a where-clause.
430430
#[derive(Clone, Encodable, Decodable, Debug)]
431431
pub struct WherePredicate {
432+
pub attrs: AttrVec,
432433
pub kind: WherePredicateKind,
433434
pub id: NodeId,
434435
pub span: Span,
@@ -444,6 +445,7 @@ impl WherePredicate {
444445
f: impl FnOnce(&WherePredicateKind) -> WherePredicateKind,
445446
) -> WherePredicate {
446447
WherePredicate {
448+
attrs: self.attrs.clone(),
447449
kind: f(&self.kind),
448450
id: DUMMY_NODE_ID,
449451
span: ctxt.map_or(self.span, |ctxt| self.span.with_ctxt(ctxt)),

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,9 @@ pub fn walk_flat_map_where_predicate<T: MutVisitor>(
10021002
vis: &mut T,
10031003
mut pred: WherePredicate,
10041004
) -> SmallVec<[WherePredicate; 1]> {
1005-
let WherePredicate { ref mut kind, ref mut id, ref mut span } = pred;
1005+
let WherePredicate { ref mut attrs, ref mut kind, ref mut id, ref mut span } = pred;
10061006
vis.visit_id(id);
1007+
visit_attrs(vis, attrs);
10071008
vis.visit_where_predicate_kind(kind);
10081009
vis.visit_span(span);
10091010
smallvec![pred]

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
789789
visitor: &mut V,
790790
predicate: &'a WherePredicate,
791791
) -> V::Result {
792-
let WherePredicate { kind, id: _, span: _ } = predicate;
792+
let WherePredicate { attrs, kind, id: _, span: _ } = predicate;
793+
walk_list!(visitor, visit_attribute, attrs);
793794
visitor.visit_where_predicate_kind(kind)
794795
}
795796

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

+1
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15791579

15801580
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
15811581
let hir_id = self.lower_node_id(pred.id);
1582+
self.lower_attrs(hir_id, &pred.attrs);
15821583
let kind = match &pred.kind {
15831584
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
15841585
bound_generic_params,

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

+1
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
547547
gate_all!(global_registration, "global registration is experimental");
548548
gate_all!(return_type_notation, "return type notation is experimental");
549549
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
550+
gate_all!(cfg_attribute_in_where, "`#[cfg]` attribute in `where` clause is unstable");
550551

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

Diff for: compiler/rustc_ast_pretty/src/pprust/state/item.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,9 @@ impl<'a> State<'a> {
726726
}
727727

728728
pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
729-
let &ast::WherePredicate { ref kind, id, span: _ } = predicate;
729+
let &ast::WherePredicate { ref attrs, ref kind, id, span: _ } = predicate;
730730
self.ann.pre(self, AnnNode::SubItem(id));
731+
self.print_outer_attributes(attrs);
731732
match kind {
732733
ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
733734
self.print_where_bound_predicate(where_bound_predicate);

Diff for: compiler/rustc_builtin_macros/src/cfg_eval.rs

+4
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ fn flat_map_annotatable(
8080
vis.visit_crate(&mut krate);
8181
Some(Annotatable::Crate(krate))
8282
}
83+
Annotatable::WherePredicate(predicate) => {
84+
vis.flat_map_where_predicate(predicate).pop().map(Annotatable::WherePredicate)
85+
}
8386
}
8487
}
8588

@@ -114,6 +117,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
114117
Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field),
115118
Annotatable::Variant(variant) => CfgFinder.visit_variant(variant),
116119
Annotatable::Crate(krate) => CfgFinder.visit_crate(krate),
120+
Annotatable::WherePredicate(predicate) => CfgFinder.visit_where_predicate(predicate),
117121
};
118122
res.is_break()
119123
}

Diff for: compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,12 @@ impl<'a> TraitDef<'a> {
761761
};
762762

763763
let kind = ast::WherePredicateKind::BoundPredicate(predicate);
764-
let predicate =
765-
ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
764+
let predicate = ast::WherePredicate {
765+
attrs: ThinVec::new(),
766+
kind,
767+
id: ast::DUMMY_NODE_ID,
768+
span: self.span,
769+
};
766770
where_clause.predicates.push(predicate);
767771
}
768772
}

Diff for: compiler/rustc_expand/src/base.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub enum Annotatable {
5353
FieldDef(ast::FieldDef),
5454
Variant(ast::Variant),
5555
Crate(ast::Crate),
56+
WherePredicate(ast::WherePredicate),
5657
}
5758

5859
impl Annotatable {
@@ -71,6 +72,7 @@ impl Annotatable {
7172
Annotatable::FieldDef(sf) => sf.span,
7273
Annotatable::Variant(v) => v.span,
7374
Annotatable::Crate(c) => c.spans.inner_span,
75+
Annotatable::WherePredicate(wp) => wp.span,
7476
}
7577
}
7678

@@ -89,6 +91,7 @@ impl Annotatable {
8991
Annotatable::FieldDef(sf) => sf.visit_attrs(f),
9092
Annotatable::Variant(v) => v.visit_attrs(f),
9193
Annotatable::Crate(c) => c.visit_attrs(f),
94+
Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
9295
}
9396
}
9497

@@ -107,6 +110,7 @@ impl Annotatable {
107110
Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
108111
Annotatable::Variant(v) => visitor.visit_variant(v),
109112
Annotatable::Crate(c) => visitor.visit_crate(c),
113+
Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
110114
}
111115
}
112116

@@ -127,7 +131,8 @@ impl Annotatable {
127131
| Annotatable::Param(..)
128132
| Annotatable::FieldDef(..)
129133
| Annotatable::Variant(..)
130-
| Annotatable::Crate(..) => panic!("unexpected annotatable"),
134+
| Annotatable::Crate(..)
135+
| Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
131136
}
132137
}
133138

@@ -228,6 +233,13 @@ impl Annotatable {
228233
_ => panic!("expected krate"),
229234
}
230235
}
236+
237+
pub fn expect_where_predicate(self) -> ast::WherePredicate {
238+
match self {
239+
Annotatable::WherePredicate(wp) => wp,
240+
_ => panic!("expected where predicate"),
241+
}
242+
}
231243
}
232244

233245
/// Result of an expansion that may need to be retried.
@@ -449,6 +461,10 @@ pub trait MacResult {
449461
// Fn-like macros cannot produce a crate.
450462
unreachable!()
451463
}
464+
465+
fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
466+
None
467+
}
452468
}
453469

454470
macro_rules! make_MacEager {

Diff for: compiler/rustc_expand/src/expand.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ ast_fragments! {
229229
"variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
230230
}
231231
Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; }
232+
WherePredicate(SmallVec<[ast::WherePredicate; 1]>) {
233+
"where predicate";
234+
many fn flat_map_where_predicate;
235+
fn visit_where_predicate();
236+
fn make_where_predicates;
237+
}
232238
}
233239

234240
pub enum SupportsMacroExpansion {
@@ -260,7 +266,8 @@ impl AstFragmentKind {
260266
| AstFragmentKind::GenericParams
261267
| AstFragmentKind::Params
262268
| AstFragmentKind::FieldDefs
263-
| AstFragmentKind::Variants => SupportsMacroExpansion::No,
269+
| AstFragmentKind::Variants
270+
| AstFragmentKind::WherePredicate => SupportsMacroExpansion::No,
264271
}
265272
}
266273

@@ -318,6 +325,9 @@ impl AstFragmentKind {
318325
AstFragmentKind::Crate => {
319326
AstFragment::Crate(items.next().expect("expected exactly one crate").expect_crate())
320327
}
328+
AstFragmentKind::WherePredicate => AstFragment::WherePredicate(
329+
items.map(Annotatable::expect_where_predicate).collect(),
330+
),
321331
AstFragmentKind::Pat | AstFragmentKind::Ty => {
322332
panic!("patterns and types aren't annotatable")
323333
}
@@ -866,7 +876,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
866876
| Annotatable::GenericParam(..)
867877
| Annotatable::Param(..)
868878
| Annotatable::FieldDef(..)
869-
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
879+
| Annotatable::Variant(..)
880+
| Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
870881
};
871882
if self.cx.ecfg.features.proc_macro_hygiene() {
872883
return;
@@ -1003,7 +1014,8 @@ pub fn parse_ast_fragment<'a>(
10031014
| AstFragmentKind::GenericParams
10041015
| AstFragmentKind::Params
10051016
| AstFragmentKind::FieldDefs
1006-
| AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
1017+
| AstFragmentKind::Variants
1018+
| AstFragmentKind::WherePredicate => panic!("unexpected AST fragment kind"),
10071019
})
10081020
}
10091021

@@ -1587,6 +1599,19 @@ impl InvocationCollectorNode for ast::Crate {
15871599
}
15881600
}
15891601

1602+
impl InvocationCollectorNode for ast::WherePredicate {
1603+
const KIND: AstFragmentKind = AstFragmentKind::WherePredicate;
1604+
fn to_annotatable(self) -> Annotatable {
1605+
Annotatable::WherePredicate(self)
1606+
}
1607+
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1608+
fragment.make_where_predicates()
1609+
}
1610+
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
1611+
walk_flat_map_where_predicate(visitor, self)
1612+
}
1613+
}
1614+
15901615
impl InvocationCollectorNode for P<ast::Ty> {
15911616
type OutputTy = P<ast::Ty>;
15921617
const KIND: AstFragmentKind = AstFragmentKind::Ty;
@@ -2179,6 +2204,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
21792204
self.visit_node(node)
21802205
}
21812206

2207+
fn flat_map_where_predicate(
2208+
&mut self,
2209+
node: ast::WherePredicate,
2210+
) -> SmallVec<[ast::WherePredicate; 1]> {
2211+
self.flat_map_node(node)
2212+
}
2213+
21822214
fn visit_expr(&mut self, node: &mut P<ast::Expr>) {
21832215
// FIXME: Feature gating is performed inconsistently between `Expr` and `OptExpr`.
21842216
if let Some(attr) = node.attrs.first() {

Diff for: compiler/rustc_expand/src/placeholders.rs

+13
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ pub(crate) fn placeholder(
187187
vis,
188188
is_placeholder: true,
189189
}]),
190+
AstFragmentKind::WherePredicate => {
191+
AstFragment::WherePredicate(smallvec![ast::WherePredicate {
192+
attrs: Default::default(),
193+
id,
194+
span,
195+
kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
196+
span,
197+
bound_generic_params: Default::default(),
198+
bounded_ty: ty(),
199+
bounds: Default::default(),
200+
}),
201+
}])
202+
}
190203
}
191204
}
192205

Diff for: compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ declare_features! (
389389
(unstable, async_for_loop, "1.77.0", Some(118898)),
390390
/// Allows using C-variadics.
391391
(unstable, c_variadic, "1.34.0", Some(44930)),
392+
/// Allows the use of `#[cfg]` in `where` clauses.
393+
(unstable, cfg_attribute_in_where, "CURRENT_RUSTC_VERSION", Some(115590)),
392394
/// Allows the use of `#[cfg(<true/false>)]`.
393395
(unstable, cfg_boolean_literals, "1.83.0", Some(131204)),
394396
/// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.

Diff for: compiler/rustc_hir_pretty/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,7 @@ impl<'a> State<'a> {
21612161
}
21622162

21632163
fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
2164+
self.print_outer_attributes(self.attrs(predicate.hir_id));
21642165
match *predicate.kind {
21652166
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
21662167
bound_generic_params,

0 commit comments

Comments
 (0)