use errors::{Applicability, DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lock;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug;
(active, nll, "1.0.0", Some(43234), None),
// Allows using slice patterns.
- (active, slice_patterns, "1.0.0", Some(23121), None),
+ (active, slice_patterns, "1.0.0", Some(62254), None),
// Allows the definition of `const` functions with some advanced features.
(active, const_fn, "1.2.0", Some(57563), None),
// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
(active, lint_reasons, "1.31.0", Some(54503), None),
- // Allows paths to enum variants on type aliases.
- (active, type_alias_enum_variants, "1.31.0", Some(49683), None),
-
// Allows exhaustive integer pattern matching on `usize` and `isize`.
(active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
// Allows explicit discriminants on non-unit enum variants.
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
+ // Allows `impl Trait` with multiple unrelated lifetimes.
+ (active, member_constraints, "1.37.0", Some(61977), None),
+
+ // Allows `async || body` closures.
+ (active, async_closure, "1.37.0", Some(62290), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
(removed, allocator, "1.0.0", None, None, None),
(removed, simd, "1.0.0", Some(27731), None,
Some("removed in favor of `#[repr(simd)]`")),
- (removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
+ (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
Some("merged into `#![feature(slice_patterns)]`")),
(removed, macro_reexport, "1.0.0", Some(29638), None,
Some("subsumed by `pub use`")),
(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 paths to enum variants on type aliases including `Self`.
+ (accepted, type_alias_enum_variants, "1.37.0", Some(49683), 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),
attribute is just used for rustc unit \
tests and will never be stable",
cfg_fn!(rustc_attrs))),
+ (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "the `#[rustc_dump_env_program_clauses]` \
+ attribute is just used for rustc unit \
+ tests and will never be stable",
+ cfg_fn!(rustc_attrs))),
+ (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "the `#[rustc_object_lifetime_default]` \
+ attribute is just used for rustc unit \
+ tests and will never be stable",
+ cfg_fn!(rustc_attrs))),
(sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"the `#[rustc_test_marker]` attribute \
"internal implementation detail",
cfg_fn!(rustc_attrs))),
+ (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "internal implementation detail",
+ cfg_fn!(rustc_attrs))),
+
+ (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "internal implementation detail",
+ cfg_fn!(rustc_attrs))),
+
+ (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
+ "internal implementation detail",
+ cfg_fn!(rustc_attrs))),
+
+ (sym::rustc_allow_const_fn_ptr, 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",
}
debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
return;
+ } else {
+ for segment in &attr.path.segments {
+ if segment.ident.as_str().starts_with("rustc") {
+ let msg = "attributes starting with `rustc` are \
+ reserved for use by the `rustc` compiler";
+ gate_feature!(self, rustc_attrs, segment.ident.span, msg);
+ }
+ }
}
for &(n, ty) in self.plugin_attributes {
if attr.path == n {
return;
}
}
- if !attr::is_known(attr) {
- if attr.name_or_empty().as_str().starts_with("rustc_") {
- let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
- are reserved for internal compiler diagnostics";
- gate_feature!(self, rustc_attrs, attr.span, msg);
- } else if !is_macro {
- // Only run the custom attribute lint during regular feature gate
- // checking. Macro gating runs before the plugin attributes are
- // registered, so we skip this in that case.
- let msg = format!("The attribute `{}` is currently unknown to the compiler and \
- may have meaning added to it in the future", attr.path);
- gate_feature!(self, custom_attribute, attr.span, &msg);
- }
+ if !is_macro && !attr::is_known(attr) {
+ // Only run the custom attribute lint during regular feature gate
+ // checking. Macro gating runs before the plugin attributes are
+ // registered, so we skip this in that case.
+ let msg = format!("The attribute `{}` is currently unknown to the compiler and \
+ may have meaning added to it in the future", attr.path);
+ gate_feature!(self, custom_attribute, attr.span, &msg);
}
}
}
"labels on blocks are unstable");
}
}
- ast::ExprKind::Closure(_, ast::IsAsync::Async { .. }, ..) => {
- gate_feature_post!(&self, async_await, e.span, "async closures are unstable");
- }
ast::ExprKind::Async(..) => {
gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
}
features
}
+fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
+ vec.borrow().iter().for_each(f);
+}
+
pub fn check_crate(krate: &ast::Crate,
sess: &ParseSess,
features: &Features,
plugin_attributes,
};
- sess
- .param_attr_spans
- .borrow()
- .iter()
- .for_each(|span| gate_feature!(
- &ctx,
- param_attrs,
- *span,
- "attributes on function parameters are unstable"
- ));
-
- sess
- .let_chains_spans
- .borrow()
- .iter()
- .for_each(|span| gate_feature!(
- &ctx,
- let_chains,
- *span,
- "`let` expressions in this position are experimental"
- ));
+ for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
+ &ctx,
+ param_attrs,
+ *span,
+ "attributes on function parameters are unstable"
+ ));
+
+ for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
+ &ctx,
+ let_chains,
+ *span,
+ "`let` expressions in this position are experimental"
+ ));
+
+ for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
+ &ctx,
+ async_closure,
+ *span,
+ "async closures are unstable"
+ ));
let visitor = &mut PostExpansionVisitor {
context: &ctx,