From 499b3098f83d1d855169d14601d694c1c2a38963 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 30 Oct 2023 10:33:24 +1100 Subject: [PATCH] Fix a `FIXME`, by adding a `gate_multi` macro. Note that this adds the `span.allows_unstable` checking that this case previously lacked. --- compiler/rustc_ast_passes/src/feature_gate.rs | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 7dd6bfa1371..3b0b7317861 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -30,7 +30,7 @@ macro_rules! gate { } /// The unusual case, where the `has_feature` condition is non-standard. -macro_rules! gate_alt { +macro_rules! gate_complex { ($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{ if !$has_feature && !$span.allows_unstable($name) { feature_err(&$visitor.sess.parse_sess, $name, $span, $explain).emit(); @@ -38,6 +38,19 @@ macro_rules! gate_alt { }}; } +/// The case involving a multispan. +macro_rules! gate_multi { + ($visitor:expr, $feature:ident, $spans:expr, $explain:expr) => {{ + if !$visitor.features.$feature { + let spans: Vec<_> = + $spans.filter(|span| !span.allows_unstable(sym::$feature)).collect(); + if !spans.is_empty() { + feature_err(&$visitor.sess.parse_sess, sym::$feature, spans, $explain).emit(); + } + } + }}; +} + /// The legacy case. macro_rules! gate_legacy { ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{ @@ -141,23 +154,16 @@ impl<'a> PostExpansionVisitor<'a> { fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) { // Check only lifetime parameters are present and that the lifetime // parameters that are present have no bounds. - let non_lt_param_spans: Vec<_> = params - .iter() - .filter_map(|param| match param.kind { - ast::GenericParamKind::Lifetime { .. } => None, - _ => Some(param.ident.span), - }) - .collect(); - // FIXME: gate_feature_post doesn't really handle multispans... - if !non_lt_param_spans.is_empty() && !self.features.non_lifetime_binders { - feature_err( - &self.sess.parse_sess, - sym::non_lifetime_binders, - non_lt_param_spans, - crate::fluent_generated::ast_passes_forbidden_non_lifetime_param, - ) - .emit(); - } + let non_lt_param_spans = params.iter().filter_map(|param| match param.kind { + ast::GenericParamKind::Lifetime { .. } => None, + _ => Some(param.ident.span), + }); + gate_multi!( + &self, + non_lifetime_binders, + non_lt_param_spans, + crate::fluent_generated::ast_passes_forbidden_non_lifetime_param + ); for param in params { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();