提交 aff97384 编写于 作者: V Vadim Petrochenkov

hygiene: Reuse `MacroKind` in `ExpnKind`

Orthogonality and reuse are good.
上级 4dcf9b15
......@@ -408,8 +408,7 @@ fn hash_stable<W: StableHasherResult>(&self,
});
impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind {
MacroAttribute(sym),
MacroBang(sym),
Macro(kind, descr),
Desugaring(kind)
});
......
......@@ -38,6 +38,7 @@
use syntax::source_map::{MultiSpan, ExpnKind, DesugaringKind};
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::edition::Edition;
use syntax::ext::base::MacroKind;
use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
......@@ -884,10 +885,9 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
};
match info.kind {
ExpnKind::MacroAttribute(..) => true, // definitely a plugin
ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
ExpnKind::Desugaring(_) => true, // well, it's "external"
ExpnKind::MacroBang(..) => {
ExpnKind::Macro(MacroKind::Bang, _) => {
if info.def_site.is_dummy() {
// dummy span for the def_site means it's an external macro
return true;
......@@ -898,19 +898,16 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
Err(_) => true,
}
}
ExpnKind::Macro(..) => true, // definitely a plugin
}
}
/// Returns whether `span` originates in a derive macro's expansion
pub fn in_derive_expansion(span: Span) -> bool {
let info = match span.ctxt().outer_expn_info() {
Some(info) => info,
// no ExpnInfo means this span doesn't come from a macro
None => return false,
};
match info.kind {
ExpnKind::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("),
_ => false,
if let Some(info) = span.ctxt().outer_expn_info() {
if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind {
return true;
}
}
false
}
......@@ -11,7 +11,7 @@
respan, ExpnInfo, ExpnKind,
},
ext::{
base::{ExtCtxt, Resolver},
base::{ExtCtxt, MacroKind, Resolver},
build::AstBuilder,
expand::ExpansionConfig,
hygiene::{Mark, SyntaxContext},
......@@ -87,7 +87,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
// Create a fresh Mark for the new macro expansion we are about to do
let mark = Mark::fresh(Mark::root());
mark.set_expn_info(ExpnInfo::with_unstable(
ExpnKind::MacroAttribute(sym::global_allocator), item.span, self.sess.edition,
ExpnKind::Macro(MacroKind::Attr, sym::global_allocator), item.span, self.sess.edition,
&[sym::rustc_attrs],
));
......
......@@ -114,17 +114,21 @@ enum SubNS { Bang, AttrLike }
// We don't want to format a path using pretty-printing,
// `format!("{}", path)`, because that tries to insert
// line-breaks and is slow.
fn fast_print_path(path: &ast::Path) -> String {
let mut path_str = String::with_capacity(64);
for (i, segment) in path.segments.iter().enumerate() {
if i != 0 {
path_str.push_str("::");
}
if segment.ident.name != kw::PathRoot {
path_str.push_str(&segment.ident.as_str())
fn fast_print_path(path: &ast::Path) -> Symbol {
if path.segments.len() == 1 {
return path.segments[0].ident.name
} else {
let mut path_str = String::with_capacity(64);
for (i, segment) in path.segments.iter().enumerate() {
if i != 0 {
path_str.push_str("::");
}
if segment.ident.name != kw::PathRoot {
path_str.push_str(&segment.ident.as_str())
}
}
Symbol::intern(&path_str)
}
path_str
}
impl<'a> base::Resolver for Resolver<'a> {
......@@ -219,14 +223,10 @@ fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force
};
let span = invoc.span();
let path = fast_print_path(path);
let format = match kind {
MacroKind::Derive => format!("derive({})", path),
_ => path.clone(),
};
invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format));
let descr = fast_print_path(path);
invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, descr));
self.check_stability_and_deprecation(&ext, &path, span);
self.check_stability_and_deprecation(&ext, descr, span);
if let Res::Def(_, def_id) = res {
if after_derive {
......@@ -991,7 +991,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
}
}
fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) {
fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, descr: Symbol, span: Span) {
if let Some(stability) = &ext.stability {
if let StabilityLevel::Unstable { reason, issue } = stability.level {
let feature = stability.feature;
......@@ -1000,14 +1000,14 @@ fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, spa
}
}
if let Some(depr) = &stability.rustc_depr {
let (message, lint) = stability::rustc_deprecation_message(depr, path);
let (message, lint) = stability::rustc_deprecation_message(depr, &descr.as_str());
stability::early_report_deprecation(
self.session, &message, depr.suggestion, lint, span
);
}
}
if let Some(depr) = &ext.deprecation {
let (message, lint) = stability::deprecation_message(depr, path);
let (message, lint) = stability::deprecation_message(depr, &descr.as_str());
stability::early_report_deprecation(self.session, &message, None, lint, span);
}
}
......
......@@ -843,7 +843,8 @@ pub fn get_macro_use_data(&self, span: Span) -> Option<MacroRef> {
let callee = span.source_callee()?;
// Ignore attribute macros, their spans are usually mangled
if let ExpnKind::MacroAttribute(_) = callee.kind {
if let ExpnKind::Macro(MacroKind::Attr, _) |
ExpnKind::Macro(MacroKind::Derive, _) = callee.kind {
return None;
}
......
......@@ -640,18 +640,10 @@ pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
}
}
fn expn_kind(&self, descr: Symbol) -> ExpnKind {
match self.kind {
SyntaxExtensionKind::Bang(..) |
SyntaxExtensionKind::LegacyBang(..) => ExpnKind::MacroBang(descr),
_ => ExpnKind::MacroAttribute(descr),
}
}
pub fn expn_info(&self, call_site: Span, descr: &str) -> ExpnInfo {
pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo {
ExpnInfo {
call_site,
kind: self.expn_kind(Symbol::intern(descr)),
kind: ExpnKind::Macro(self.macro_kind(), descr),
def_site: self.span,
default_transparency: self.default_transparency,
allow_internal_unstable: self.allow_internal_unstable.clone(),
......
use crate::attr::HasAttrs;
use crate::ast;
use crate::source_map::{ExpnInfo, ExpnKind};
use crate::ext::base::ExtCtxt;
use crate::ext::base::{ExtCtxt, MacroKind};
use crate::ext::build::AstBuilder;
use crate::parse::parser::PathStyle;
use crate::symbol::{Symbol, sym};
......@@ -46,7 +46,7 @@ pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) ->
pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::Path], item: &mut T)
where T: HasAttrs,
{
let (mut names, mut pretty_name) = (FxHashSet::default(), "derive(".to_owned());
let (mut names, mut pretty_name) = (FxHashSet::default(), String::new());
for (i, path) in traits.iter().enumerate() {
if i > 0 {
pretty_name.push_str(", ");
......@@ -54,11 +54,10 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
pretty_name.push_str(&path.to_string());
names.insert(unwrap_or!(path.segments.get(0), continue).ident.name);
}
pretty_name.push(')');
cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable(
ExpnKind::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition,
&[sym::rustc_attrs, sym::structural_match],
ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span,
cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match],
));
let span = span.with_ctxt(cx.backtrace());
......
use crate::ast;
use crate::attr;
use crate::edition::Edition;
use crate::ext::hygiene::{Mark, SyntaxContext};
use crate::ext::hygiene::{Mark, SyntaxContext, MacroKind};
use crate::symbol::{Ident, Symbol, kw, sym};
use crate::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan};
use crate::ptr::P;
......@@ -17,7 +17,8 @@
fn ignored_span(sp: Span, edition: Edition) -> Span {
let mark = Mark::fresh(Mark::root());
mark.set_expn_info(ExpnInfo::with_unstable(
ExpnKind::MacroAttribute(Symbol::intern("std_inject")), sp, edition, &[sym::prelude_import]
ExpnKind::Macro(MacroKind::Attr, Symbol::intern("std_inject")), sp, edition,
&[sym::prelude_import],
));
sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
}
......
......@@ -21,7 +21,7 @@
use crate::ext::base::{ExtCtxt, Resolver};
use crate::ext::build::AstBuilder;
use crate::ext::expand::ExpansionConfig;
use crate::ext::hygiene::{self, Mark, SyntaxContext};
use crate::ext::hygiene::{self, Mark, SyntaxContext, MacroKind};
use crate::mut_visit::{*, ExpectOne};
use crate::feature_gate::Features;
use crate::util::map_in_place::MapInPlace;
......@@ -280,7 +280,7 @@ fn generate_test_harness(sess: &ParseSess,
};
mark.set_expn_info(ExpnInfo::with_unstable(
ExpnKind::MacroAttribute(sym::test_case), DUMMY_SP, sess.edition,
ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, sess.edition,
&[sym::main, sym::test, sym::rustc_attrs],
));
......
......@@ -5,7 +5,7 @@
use syntax::ast::{self, Ident};
use syntax::attr;
use syntax::source_map::{ExpnInfo, ExpnKind, respan};
use syntax::ext::base::ExtCtxt;
use syntax::ext::base::{ExtCtxt, MacroKind};
use syntax::ext::build::AstBuilder;
use syntax::ext::expand::ExpansionConfig;
use syntax::ext::hygiene::Mark;
......@@ -348,7 +348,7 @@ fn mk_decls(
) -> P<ast::Item> {
let mark = Mark::fresh(Mark::root());
mark.set_expn_info(ExpnInfo::with_unstable(
ExpnKind::MacroAttribute(sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
&[sym::rustc_attrs, Symbol::intern("proc_macro_internals")],
));
let span = DUMMY_SP.apply_mark(mark);
......
......@@ -135,11 +135,9 @@ pub fn outer_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
pub fn looks_like_proc_macro_derive(self) -> bool {
HygieneData::with(|data| {
if data.default_transparency(self) == Transparency::Opaque {
if let Some(expn_info) = &data.marks[self.0 as usize].expn_info {
if let ExpnKind::MacroAttribute(name) = expn_info.kind {
if name.as_str().starts_with("derive(") {
return true;
}
if let Some(expn_info) = data.expn_info(self) {
if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
return true;
}
}
}
......@@ -193,7 +191,7 @@ fn is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool {
}
fn default_transparency(&self, mark: Mark) -> Transparency {
self.marks[mark.0 as usize].expn_info.as_ref().map_or(
self.expn_info(mark).map_or(
Transparency::SemiTransparent, |einfo| einfo.default_transparency
)
}
......@@ -613,7 +611,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
/// Extra information for tracking spans of macro and syntax sugar expansion
/// A subset of properties from both macro definition and macro call available through global data.
/// Avoid using this if you have access to the original definition or call structures.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ExpnInfo {
// --- The part unique to each expansion.
......@@ -627,7 +626,7 @@ pub struct ExpnInfo {
/// call_site span would have its own ExpnInfo, with the call_site
/// pointing to the `foo!` invocation.
pub call_site: Span,
/// The format with which the macro was invoked.
/// The kind of this expansion - macro or compiler desugaring.
pub kind: ExpnKind,
// --- The part specific to the macro/desugaring definition.
......@@ -675,13 +674,12 @@ pub fn with_unstable(kind: ExpnKind, call_site: Span, edition: Edition,
}
}
/// The source of expansion.
/// Expansion kind.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum ExpnKind {
/// e.g., #[derive(...)] <item>
MacroAttribute(Symbol),
/// e.g., `format!()`
MacroBang(Symbol),
/// Expansion produced by a macro.
/// FIXME: Some code injected by the compiler before HIR lowering also gets this kind.
Macro(MacroKind, Symbol),
/// Desugaring done by the compiler during HIR lowering.
Desugaring(DesugaringKind)
}
......@@ -689,8 +687,8 @@ pub enum ExpnKind {
impl ExpnKind {
pub fn descr(&self) -> Symbol {
match *self {
ExpnKind::MacroBang(name) | ExpnKind::MacroAttribute(name) => name,
ExpnKind::Desugaring(kind) => kind.descr(),
ExpnKind::Macro(_, descr) => descr,
ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()),
}
}
}
......@@ -743,8 +741,8 @@ pub enum DesugaringKind {
}
impl DesugaringKind {
pub fn descr(self) -> Symbol {
Symbol::intern(match self {
pub fn descr(self) -> &'static str {
match self {
DesugaringKind::CondTemporary => "if and while condition",
DesugaringKind::Async => "async",
DesugaringKind::Await => "await",
......@@ -752,7 +750,7 @@ pub fn descr(self) -> Symbol {
DesugaringKind::TryBlock => "try block",
DesugaringKind::ExistentialType => "existential type",
DesugaringKind::ForLoop => "for loop",
})
}
}
}
......
......@@ -27,7 +27,7 @@
pub mod edition;
use edition::Edition;
pub mod hygiene;
pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind, DesugaringKind};
pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind, MacroKind, DesugaringKind};
mod span_encoding;
pub use span_encoding::{Span, DUMMY_SP};
......@@ -442,9 +442,12 @@ pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
// Don't print recursive invocations.
if !info.call_site.source_equal(&prev_span) {
let (pre, post) = match info.kind {
ExpnKind::MacroAttribute(..) => ("#[", "]"),
ExpnKind::MacroBang(..) => ("", "!"),
ExpnKind::Desugaring(..) => ("desugaring of `", "`"),
ExpnKind::Macro(macro_kind, _) => match macro_kind {
MacroKind::Bang => ("", "!"),
MacroKind::Attr => ("#[", "]"),
MacroKind::Derive => ("#[derive(", ")]"),
}
};
result.push(MacroBacktrace {
call_site: info.call_site,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册