// Allows using `#[optimize(X)]`.
(active, optimize_attribute, "1.34.0", Some(54882), None),
- // Allows using `#[repr(align(X))]` on enums.
- (active, repr_align_enum, "1.34.0", Some(57996), None),
-
// Allows using C-variadics.
(active, c_variadic, "1.34.0", Some(44930), None),
// Allows the user of associated type bounds.
(active, associated_type_bounds, "1.34.0", Some(52662), None),
+ // Attributes on formal function params
+ (active, param_attrs, "1.36.0", Some(60406), None),
+
+ // Allows calling constructor functions in `const fn`
+ // FIXME Create issue
+ (active, const_constructor, "1.37.0", Some(61456), None),
+
+ // #[repr(transparent)] on enums.
+ (active, transparent_enums, "1.37.0", Some(60405), None),
+
+ // #[repr(transparent)] on unions.
+ (active, transparent_unions, "1.37.0", Some(60405), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
(accepted, extern_crate_self, "1.34.0", Some(56409), None),
// Allows arbitrary delimited token streams in non-macro attributes.
(accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+ // Allows using `#[repr(align(X))]` on enums with equivalent semantics
+ // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
+ (accepted, repr_align_enum, "1.37.0", Some(57996), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features
"internal implementation detail",
cfg_fn!(rustc_attrs))),
+ (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "internal implementation detail",
+ cfg_fn!(rustc_attrs))),
+
+ (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "used by the test suite",
+ cfg_fn!(rustc_attrs))),
+
// FIXME: #14408 whitelist docs since rustdoc looks at them
(
sym::doc,
}
match attr_info {
- Some(&(name, _, template, _)) => self.check_builtin_attribute(
- attr,
- name,
- template
- ),
- None => if let Some(TokenTree::Token(_, token::Eq)) = attr.tokens.trees().next() {
- // All key-value attributes are restricted to meta-item syntax.
- attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
+ // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
+ Some(&(name, _, template, _)) if name != sym::rustc_dummy =>
+ self.check_builtin_attribute(attr, name, template),
+ _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
+ if token == token::Eq {
+ // All key-value attributes are restricted to meta-item syntax.
+ attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
+ }
}
}
}
}
}
- ast::ItemKind::Enum(..) => {
- for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
- for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
- if item.check_name(sym::align) {
- gate_feature_post!(&self, repr_align_enum, attr.span,
- "`#[repr(align(x))]` on enums is experimental");
- }
- }
- }
- }
-
ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
if polarity == ast::ImplPolarity::Negative {
gate_feature_post!(&self, optin_builtin_traits,
parse_sess: sess,
plugin_attributes,
};
+
+ sess
+ .param_attr_spans
+ .borrow()
+ .iter()
+ .for_each(|span| gate_feature!(
+ &ctx,
+ param_attrs,
+ *span,
+ "attributes on function parameters are unstable"
+ ));
+
let visitor = &mut PostExpansionVisitor {
context: &ctx,
builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,