use tracing::debug;
macro_rules! gate_feature_fn {
+ ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
+ let (visitor, has_feature, span, name, explain, help) =
+ (&*$visitor, $has_feature, $span, $name, $explain, $help);
+ let has_feature: bool = has_feature(visitor.features);
+ debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
+ if !has_feature && !span.allows_unstable($name) {
+ feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
+ .help(help)
+ .emit();
+ }
+ }};
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
let (visitor, has_feature, span, name, explain) =
(&*$visitor, $has_feature, $span, $name, $explain);
}
macro_rules! gate_feature_post {
+ ($visitor: expr, $feature: ident, $span: expr, $explain: expr, $help: expr) => {
+ gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain, $help)
+ };
($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
};
"efiapi ABI is experimental and subject to change"
);
}
+ "C-cmse-nonsecure-call" => {
+ gate_feature_post!(
+ &self,
+ abi_c_cmse_nonsecure_call,
+ span,
+ "C-cmse-nonsecure-call ABI is experimental and subject to change"
+ );
+ }
abi => self
.sess
.parse_sess
gate_feature_post!(
&self,
negative_impls,
- span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(span)),
+ span.to(of_trait.as_ref().map_or(span, |t| t.path.span)),
"negative trait bounds are not yet fully implemented; \
use marker types for now"
);
let spans = sess.parse_sess.gated_spans.spans.borrow();
macro_rules! gate_all {
+ ($gate:ident, $msg:literal, $help:literal) => {
+ if let Some(spans) = spans.get(&sym::$gate) {
+ for span in spans {
+ gate_feature_post!(&visitor, $gate, *span, $msg, $help);
+ }
+ }
+ };
($gate:ident, $msg:literal) => {
if let Some(spans) = spans.get(&sym::$gate) {
for span in spans {
}
gate_all!(if_let_guard, "`if let` guards are experimental");
gate_all!(let_chains, "`let` expressions in this position are experimental");
- gate_all!(async_closure, "async closures are unstable");
+ gate_all!(
+ async_closure,
+ "async closures are unstable",
+ "to use an async block, remove the `||`: `async {`"
+ );
gate_all!(generators, "yield syntax is experimental");
gate_all!(or_patterns, "or-patterns syntax is experimental");
gate_all!(raw_ref_op, "raw address of syntax is experimental");
extended_key_value_attributes,
"arbitrary expressions in key-value attributes are unstable"
);
+ gate_all!(
+ const_generics_defaults,
+ "default values for const generic parameters are experimental"
+ );
if sess.parse_sess.span_diagnostic.err_count() == 0 {
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
// involved, so we only emit errors where there are no other parsing errors.