Skip to content

Commit 8ccae90

Browse files
authored
Rollup merge of #157195 - JonathanBrouwer:gating-port, r=mejrs
Move feature gating to the new attr parsing infrastructure Does the feature gate checking for attributes during attribute parsing, rather than during expansion. This is one more step towards removing `BUILTIN_ATTRIBUTES`. My goal was to keep the diagnostics mostly the same during this PR, and do some improvements and cleanups later, to reduce the diff. Some diagnostics still had minor changes to keep the implementation simpler. This PR was fully manually written, I triple-checked that I didn't accidentally stabilize or change the gate of an attribute, but I'm terrified of a mistake still slipping through so please check this again. r? @mejrs @jdonszelmann cc @nnethercote @scrabsha @Bryntet
2 parents ee80e3f + 47acd7a commit 8ccae90

76 files changed

Lines changed: 1016 additions & 700 deletions

File tree

Some content is hidden

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

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
22
use rustc_ast::{self as ast, AttrVec, GenericBound, NodeId, PatKind, attr, token};
33
use rustc_attr_parsing::AttributeParser;
44
use rustc_errors::msg;
5-
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
5+
use rustc_feature::Features;
66
use rustc_hir::Attribute;
77
use rustc_hir::attrs::AttributeKind;
88
use rustc_session::Session;
@@ -155,15 +155,6 @@ impl<'a> PostExpansionVisitor<'a> {
155155

156156
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
157157
fn visit_attribute(&mut self, attr: &ast::Attribute) {
158-
let attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name));
159-
// Check feature gates for built-in attributes.
160-
if let Some(BuiltinAttribute {
161-
gate: AttributeGate::Gated { feature, message, check, notes, .. },
162-
..
163-
}) = attr_info
164-
{
165-
gate_alt!(self, check(self.features), *feature, attr.span, *message, *notes);
166-
}
167158
// Check unstable flavors of the `#[doc]` attribute.
168159
if attr.has_name(sym::doc) {
169160
for meta_item_inner in attr.meta_item_list().unwrap_or_default() {

compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::iter;
22

3+
use rustc_feature::AttributeStability;
4+
35
use super::prelude::*;
46
use crate::session_diagnostics;
57

@@ -16,6 +18,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser {
1618
Warn(Target::Arm),
1719
]);
1820
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
21+
const STABILITY: AttributeStability = unstable!(allow_internal_unstable);
1922

2023
fn extend(
2124
cx: &mut AcceptContext<'_, '_>,
@@ -32,6 +35,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser {
3235
const PATH: &[rustc_span::Symbol] = &[sym::unstable_feature_bound];
3336
type Item = (Symbol, Span);
3437
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items);
38+
const STABILITY: AttributeStability = unstable!(staged_api);
3539
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
3640
Allow(Target::Fn),
3741
Allow(Target::Impl { of_trait: true }),
@@ -43,9 +47,6 @@ impl CombineAttributeParser for UnstableFeatureBoundParser {
4347
cx: &mut AcceptContext<'_, '_>,
4448
args: &ArgParser,
4549
) -> impl IntoIterator<Item = Self::Item> {
46-
if !cx.features().staged_api() {
47-
cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span });
48-
}
4950
parse_unstable(cx, args, <Self as CombineAttributeParser>::PATH[0])
5051
.into_iter()
5152
.zip(iter::repeat(cx.attr_span))
@@ -65,6 +66,10 @@ impl CombineAttributeParser for RustcAllowConstFnUnstableParser {
6566
Allow(Target::Method(MethodKind::TraitImpl)),
6667
]);
6768
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
69+
const STABILITY: AttributeStability = unstable!(
70+
rustc_attrs,
71+
"rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
72+
);
6873

6974
fn extend(
7075
cx: &mut AcceptContext<'_, '_>,

compiler/rustc_attr_parsing/src/attributes/autodiff.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::str::FromStr;
22

33
use rustc_ast::LitKind;
44
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
5-
use rustc_feature::{AttributeTemplate, template};
5+
use rustc_feature::{AttributeStability, AttributeTemplate, template};
66
use rustc_hir::attrs::{AttributeKind, RustcAutodiff};
77
use rustc_hir::{MethodKind, Target};
88
use rustc_span::{Symbol, sym};
@@ -13,6 +13,7 @@ use crate::attributes::prelude::Allow;
1313
use crate::context::AcceptContext;
1414
use crate::parser::{ArgParser, MetaItemOrLitParser};
1515
use crate::target_checking::AllowedTargets;
16+
use crate::unstable;
1617

1718
pub(crate) struct RustcAutodiffParser;
1819

@@ -29,6 +30,7 @@ impl SingleAttributeParser for RustcAutodiffParser {
2930
List: &["MODE", "WIDTH", "INPUT_ACTIVITIES", "OUTPUT_ACTIVITY"],
3031
"https://doc.rust-lang.org/std/autodiff/index.html"
3132
);
33+
const STABILITY: AttributeStability = unstable!(rustc_attrs);
3234

3335
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3436
let list = match args {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! Attributes that can be found in function body.
22
3+
use rustc_feature::AttributeStability;
4+
35
use super::prelude::*;
46

57
pub(crate) struct CoroutineParser;
68

79
impl NoArgsAttributeParser for CoroutineParser {
810
const PATH: &[Symbol] = &[sym::coroutine];
911
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
12+
const STABILITY: AttributeStability = unstable!(coroutines);
1013
const CREATE: fn(rustc_span::Span) -> AttributeKind = |_| AttributeKind::Coroutine;
1114
}

compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use rustc_feature::AttributeStability;
2+
13
use super::prelude::*;
24
pub(crate) struct CfiEncodingParser;
35
impl SingleAttributeParser for CfiEncodingParser {
@@ -9,6 +11,7 @@ impl SingleAttributeParser for CfiEncodingParser {
911
Allow(Target::Union),
1012
]);
1113
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
14+
const STABILITY: AttributeStability = unstable!(cfi_encoding);
1215

1316
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1417
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::cfi_encoding))?;

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_feature::AttributeStability;
12
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
23
use rustc_session::errors::feature_err;
34
use rustc_span::edition::Edition::Edition2024;
@@ -22,6 +23,7 @@ impl SingleAttributeParser for OptimizeParser {
2223
Allow(Target::Method(MethodKind::Inherent)),
2324
]);
2425
const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]);
26+
const STABILITY: AttributeStability = unstable!(optimize_attribute);
2527

2628
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2729
let single = cx.expect_single_element_list(args, cx.attr_span)?;
@@ -54,6 +56,7 @@ impl NoArgsAttributeParser for ColdParser {
5456
Allow(Target::ForeignFn),
5557
Allow(Target::Closure),
5658
]);
59+
const STABILITY: AttributeStability = AttributeStability::Stable;
5760
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Cold;
5861
}
5962

@@ -73,6 +76,7 @@ impl SingleAttributeParser for CoverageParser {
7376
Allow(Target::Crate),
7477
]);
7578
const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]);
79+
const STABILITY: AttributeStability = unstable!(coverage_attribute);
7680

7781
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
7882
let arg = cx.expect_single_element_list(args, cx.attr_span)?;
@@ -116,6 +120,7 @@ impl SingleAttributeParser for ExportNameParser {
116120
Warn(Target::MacroCall),
117121
]);
118122
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
123+
const STABILITY: AttributeStability = AttributeStability::Stable;
119124

120125
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
121126
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
@@ -143,6 +148,7 @@ impl SingleAttributeParser for RustcObjcClassParser {
143148
const ALLOWED_TARGETS: AllowedTargets =
144149
AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
145150
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName");
151+
const STABILITY: AttributeStability = unstable!(rustc_attrs);
146152

147153
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
148154
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
@@ -170,6 +176,7 @@ impl SingleAttributeParser for RustcObjcSelectorParser {
170176
const ALLOWED_TARGETS: AllowedTargets =
171177
AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
172178
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName");
179+
const STABILITY: AttributeStability = unstable!(rustc_attrs);
173180

174181
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
175182
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
@@ -197,7 +204,7 @@ pub(crate) struct NakedParser {
197204

198205
impl AttributeParser for NakedParser {
199206
const ATTRIBUTES: AcceptMapping<Self> =
200-
&[(&[sym::naked], template!(Word), |this, cx, args| {
207+
&[(&[sym::naked], template!(Word), AttributeStability::Stable, |this, cx, args| {
201208
let Some(()) = cx.expect_no_args(args) else {
202209
return;
203210
};
@@ -331,6 +338,7 @@ impl NoArgsAttributeParser for TrackCallerParser {
331338
Warn(Target::Field),
332339
Warn(Target::MacroCall),
333340
]);
341+
const STABILITY: AttributeStability = AttributeStability::Stable;
334342
const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller;
335343
}
336344

@@ -347,6 +355,7 @@ impl NoArgsAttributeParser for NoMangleParser {
347355
AllowSilent(Target::Const), // Handled in the `InvalidNoMangleItems` pass
348356
Error(Target::Closure),
349357
]);
358+
const STABILITY: AttributeStability = AttributeStability::Stable;
350359
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoMangle;
351360
}
352361

@@ -365,6 +374,7 @@ impl AttributeParser for UsedParser {
365374
const ATTRIBUTES: AcceptMapping<Self> = &[(
366375
&[sym::used],
367376
template!(Word, List: &["compiler", "linker"]),
377+
AttributeStability::Stable,
368378
|group: &mut Self, cx, args| {
369379
let used_by = match args {
370380
ArgParser::NoArgs => UsedBy::Default,
@@ -502,6 +512,7 @@ impl CombineAttributeParser for TargetFeatureParser {
502512
was_forced: false,
503513
};
504514
const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]);
515+
const STABILITY: AttributeStability = AttributeStability::Stable;
505516

506517
fn extend(
507518
cx: &mut AcceptContext<'_, '_>,
@@ -541,6 +552,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser {
541552
Allow(Target::Method(MethodKind::Trait { body: true })),
542553
Allow(Target::Method(MethodKind::TraitImpl)),
543554
]);
555+
const STABILITY: AttributeStability = unstable!(effective_target_features);
544556

545557
fn extend(
546558
cx: &mut AcceptContext<'_, '_>,
@@ -554,10 +566,8 @@ pub(crate) struct SanitizeParser;
554566

555567
impl SingleAttributeParser for SanitizeParser {
556568
const PATH: &[Symbol] = &[sym::sanitize];
557-
558569
// FIXME: still checked in check_attrs.rs
559570
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
560-
561571
const TEMPLATE: AttributeTemplate = template!(List: &[
562572
r#"address = "on|off""#,
563573
r#"kernel_address = "on|off""#,
@@ -571,6 +581,7 @@ impl SingleAttributeParser for SanitizeParser {
571581
r#"thread = "on|off""#,
572582
r#"realtime = "nonblocking|blocking|caller""#,
573583
]);
584+
const STABILITY: AttributeStability = unstable!(sanitize);
574585

575586
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
576587
let list = cx.expect_list(args, cx.attr_span)?;
@@ -667,6 +678,7 @@ impl NoArgsAttributeParser for ThreadLocalParser {
667678
const PATH: &[Symbol] = &[sym::thread_local];
668679
const ALLOWED_TARGETS: AllowedTargets =
669680
AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
681+
const STABILITY: AttributeStability = unstable!(thread_local);
670682
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal;
671683
}
672684

@@ -675,6 +687,7 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser;
675687
impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser {
676688
const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis];
677689
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
690+
const STABILITY: AttributeStability = unstable!(rustc_attrs);
678691
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis;
679692
}
680693

@@ -684,6 +697,7 @@ impl NoArgsAttributeParser for RustcEiiForeignItemParser {
684697
const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
685698
const ALLOWED_TARGETS: AllowedTargets =
686699
AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
700+
const STABILITY: AttributeStability = unstable!(eii_internals);
687701
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
688702
}
689703

@@ -693,6 +707,7 @@ impl SingleAttributeParser for PatchableFunctionEntryParser {
693707
const PATH: &[Symbol] = &[sym::patchable_function_entry];
694708
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
695709
const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
710+
const STABILITY: AttributeStability = unstable!(patchable_function_entry);
696711

697712
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
698713
let meta_item_list = cx.expect_list(args, cx.attr_span)?;

compiler/rustc_attr_parsing/src/attributes/confusables.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use rustc_feature::AttributeStability;
2+
13
use super::prelude::*;
24
use crate::session_diagnostics::EmptyConfusables;
35

@@ -11,6 +13,7 @@ impl AttributeParser for ConfusablesParser {
1113
const ATTRIBUTES: AcceptMapping<Self> = &[(
1214
&[sym::rustc_confusables],
1315
template!(List: &[r#""name1", "name2", ..."#]),
16+
unstable!(rustc_attrs),
1417
|this, cx, args| {
1518
let Some(list) = cx.expect_list(args, cx.attr_span) else { return };
1619

0 commit comments

Comments
 (0)