summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_expand/src/base.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_expand/src/base.rs117
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;
+ }
+ }
+ }
}
}
}