diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_expand/src/base.rs | 117 |
1 files changed, 81 insertions, 36 deletions
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 6e093811f..c8de60ccb 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -6,21 +6,23 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Nonterminal}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; -use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind}; +use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult}; +use rustc_errors::{ + Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan, PResult, +}; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics}; use rustc_parse::{self, parser, MACRO_ARGUMENTS}; -use rustc_session::{parse::ParseSess, Limit, Session, SessionDiagnostic}; +use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{FileName, Span, DUMMY_SP}; +use rustc_span::{BytePos, FileName, RealFileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::default::Default; @@ -71,7 +73,7 @@ impl Annotatable { } } - pub fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { + pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { match self { Annotatable::Item(item) => item.visit_attrs(f), Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f), @@ -693,10 +695,6 @@ pub struct SyntaxExtension { pub span: Span, /// List of unstable features that are treated as stable inside this macro. pub allow_internal_unstable: Option<Lrc<[Symbol]>>, - /// Suppresses the `unsafe_code` lint for code produced by this macro. - pub allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. - pub local_inner_macros: bool, /// The macro's stability info. pub stability: Option<Stability>, /// The macro's deprecation info. @@ -708,6 +706,13 @@ pub struct SyntaxExtension { /// Built-in macros have a couple of special properties like availability /// in `#[no_implicit_prelude]` modules, so we have to keep this flag. pub builtin_name: Option<Symbol>, + /// Suppresses the `unsafe_code` lint for code produced by this macro. + pub allow_internal_unsafe: bool, + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. + pub local_inner_macros: bool, + /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other + /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? + pub collapse_debuginfo: bool, } impl SyntaxExtension { @@ -729,14 +734,15 @@ impl SyntaxExtension { SyntaxExtension { span: DUMMY_SP, allow_internal_unstable: None, - allow_internal_unsafe: false, - local_inner_macros: false, stability: None, deprecation: None, helper_attrs: Vec::new(), edition, builtin_name: None, kind, + allow_internal_unsafe: false, + local_inner_macros: false, + collapse_debuginfo: false, } } @@ -754,12 +760,13 @@ impl SyntaxExtension { let allow_internal_unstable = attr::allow_internal_unstable(sess, &attrs).collect::<Vec<Symbol>>(); - let mut local_inner_macros = false; - if let Some(macro_export) = sess.find_by_name(attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } + let allow_internal_unsafe = sess.contains_name(attrs, sym::allow_internal_unsafe); + let local_inner_macros = sess + .find_by_name(attrs, sym::macro_export) + .and_then(|macro_export| macro_export.meta_item_list()) + .map_or(false, |l| attr::list_contains_name(&l, sym::local_inner_macros)); + let collapse_debuginfo = sess.contains_name(attrs, sym::collapse_debuginfo); + tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe); let (builtin_name, helper_attrs) = sess .find_by_name(attrs, sym::rustc_builtin_macro) @@ -772,7 +779,7 @@ impl SyntaxExtension { ) }) .unwrap_or_else(|| (None, helper_attrs)); - let (stability, const_stability) = attr::find_stability(&sess, attrs, span); + let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span); if let Some((_, sp)) = const_stability { sess.parse_sess .span_diagnostic @@ -784,19 +791,31 @@ impl SyntaxExtension { ) .emit(); } + if let Some((_, sp)) = body_stability { + sess.parse_sess + .span_diagnostic + .struct_span_err(sp, "macros cannot have body stability attributes") + .span_label(sp, "invalid body stability attribute") + .span_label( + sess.source_map().guess_head_span(span), + "body stability attribute affects this macro", + ) + .emit(); + } SyntaxExtension { kind, span, allow_internal_unstable: (!allow_internal_unstable.is_empty()) .then(|| allow_internal_unstable.into()), - allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe), - local_inner_macros, stability: stability.map(|(s, _)| s), deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d), helper_attrs, edition, builtin_name, + allow_internal_unsafe, + local_inner_macros, + collapse_debuginfo, } } @@ -841,11 +860,12 @@ impl SyntaxExtension { call_site, self.span, self.allow_internal_unstable.clone(), - self.allow_internal_unsafe, - self.local_inner_macros, self.edition, macro_def_id, parent_module, + self.allow_internal_unsafe, + self.local_inner_macros, + self.collapse_debuginfo, ) } } @@ -1091,12 +1111,12 @@ impl<'a> ExtCtxt<'a> { pub fn create_err( &self, - err: impl SessionDiagnostic<'a>, + err: impl IntoDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { self.sess.create_err(err) } - pub fn emit_err(&self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { + pub fn emit_err(&self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.sess.emit_err(err) } @@ -1208,15 +1228,16 @@ pub fn expr_to_spanned_string<'a>( ast::LitKind::Str(s, style) => return Ok((s, style, expr.span)), ast::LitKind::ByteStr(_) => { let mut err = cx.struct_span_err(l.span, err_msg); + let span = expr.span.shrink_to_lo(); err.span_suggestion( - expr.span.shrink_to_lo(), + span.with_hi(span.lo() + BytePos(1)), "consider removing the leading `b`", "", Applicability::MaybeIncorrect, ); Some((err, true)) } - ast::LitKind::Err(_) => None, + ast::LitKind::Err => None, _ => Some((cx.struct_span_err(l.span, err_msg), false)), }, ast::ExprKind::Err => None, @@ -1402,16 +1423,40 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool { if let ast::ItemKind::Enum(enum_def, _) = &item.kind { if let [variant] = &*enum_def.variants { if variant.ident.name == sym::Input { - sess.buffer_lint_with_diagnostic( - &PROC_MACRO_BACK_COMPAT, - item.ident.span, - ast::CRATE_NODE_ID, - "using `procedural-masquerade` crate", - BuiltinLintDiagnostics::ProcMacroBackCompat( - "The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. \ - Versions of this crate below 0.1.7 will eventually stop compiling.".to_string()) - ); - return true; + let filename = sess.source_map().span_to_filename(item.ident.span); + if let FileName::Real(RealFileName::LocalPath(path)) = filename { + if let Some(c) = path + .components() + .flat_map(|c| c.as_os_str().to_str()) + .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental")) + { + let crate_matches = if c.starts_with("allsorts-rental") { + true + } else { + let mut version = c.trim_start_matches("rental-").split("."); + version.next() == Some("0") + && version.next() == Some("5") + && version + .next() + .and_then(|c| c.parse::<u32>().ok()) + .map_or(false, |v| v < 6) + }; + + if crate_matches { + sess.buffer_lint_with_diagnostic( + &PROC_MACRO_BACK_COMPAT, + item.ident.span, + ast::CRATE_NODE_ID, + "using an old version of `rental`", + BuiltinLintDiagnostics::ProcMacroBackCompat( + "older versions of the `rental` crate will stop compiling in future versions of Rust; \ + please update to `rental` v0.5.6, or switch to one of the `rental` alternatives".to_string() + ) + ); + return true; + } + } + } } } } |