Auto merge of #63823 - petrochenkov:noapply2, r=matthewjasper
Audit uses of `apply_mark` in built-in macros + Remove default macro transparencies Every use of `apply_mark` in a built-in or procedural macro is supposed to look like this ```rust location.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id)) ``` where `SyntaxContext::root()` means that the built-in/procedural macro is defined directly, rather than expanded from some other macro. However, few people understood what `apply_mark` does, so we had a lot of copy-pasted uses of it looking e.g. like ```rust span = span.apply_mark(ecx.current_expansion.id); ``` , which doesn't really make sense for procedural macros, but at the same time is not too harmful, if the macros use the traditional `macro_rules` hygiene. So, to fight this, we stop using `apply_mark` directly in built-in macro implementations, and follow the example of regular proc macros instead and use analogues of `Span::def_site()` and `Span::call_site()`, which are much more intuitive and less error-prone. - `ecx.with_def_site_ctxt(span)` takes the `span`'s location and combines it with a def-site context. - `ecx.with_call_site_ctxt(span)` takes the `span`'s location and combines it with a call-site context. Even if called multiple times (which sometimes happens due to some historical messiness of the built-in macro code) these functions will produce the same result, unlike `apply_mark` which will grow the mark chain further in this case. --- After `apply_mark`s in built-in macros are eliminated, the remaining `apply_mark`s are very few in number, so we can start passing the previously implicit `Transparency` argument to them explicitly, thus eliminating the need in `default_transparency` fields in hygiene structures and `#[rustc_macro_transparency]` annotations on built-in macros. So, the task of making built-in macros opaque can now be formulated as "eliminate `with_legacy_ctxt` in favor of `with_def_site_ctxt`" rather than "replace `#[rustc_macro_transparency = "semitransparent"]` with `#[rustc_macro_transparency = "opaque"]`". r? @matthewjasper
This commit is contained in:
commit
5ade61a4f1
28 changed files with 152 additions and 179 deletions
|
@ -734,7 +734,6 @@ pub(crate) mod builtin {
|
||||||
#[allow_internal_unstable(fmt_internals)]
|
#[allow_internal_unstable(fmt_internals)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_macro_transparency = "opaque"]
|
|
||||||
macro_rules! format_args {
|
macro_rules! format_args {
|
||||||
($fmt:expr) => ({ /* compiler built-in */ });
|
($fmt:expr) => ({ /* compiler built-in */ });
|
||||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||||
|
@ -747,7 +746,6 @@ pub(crate) mod builtin {
|
||||||
#[allow_internal_unstable(fmt_internals)]
|
#[allow_internal_unstable(fmt_internals)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_macro_transparency = "opaque"]
|
|
||||||
macro_rules! format_args_nl {
|
macro_rules! format_args_nl {
|
||||||
($fmt:expr) => ({ /* compiler built-in */ });
|
($fmt:expr) => ({ /* compiler built-in */ });
|
||||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||||
|
@ -1235,7 +1233,6 @@ pub(crate) mod builtin {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow_internal_unstable(test, rustc_attrs)]
|
#[allow_internal_unstable(test, rustc_attrs)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[rustc_macro_transparency = "semitransparent"]
|
|
||||||
pub macro test($item:item) { /* compiler built-in */ }
|
pub macro test($item:item) { /* compiler built-in */ }
|
||||||
|
|
||||||
/// Attribute macro applied to a function to turn it into a benchmark test.
|
/// Attribute macro applied to a function to turn it into a benchmark test.
|
||||||
|
@ -1243,7 +1240,6 @@ pub(crate) mod builtin {
|
||||||
reason = "`bench` is a part of custom test frameworks which are unstable")]
|
reason = "`bench` is a part of custom test frameworks which are unstable")]
|
||||||
#[allow_internal_unstable(test, rustc_attrs)]
|
#[allow_internal_unstable(test, rustc_attrs)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[rustc_macro_transparency = "semitransparent"]
|
|
||||||
pub macro bench($item:item) { /* compiler built-in */ }
|
pub macro bench($item:item) { /* compiler built-in */ }
|
||||||
|
|
||||||
/// An implementation detail of the `#[test]` and `#[bench]` macros.
|
/// An implementation detail of the `#[test]` and `#[bench]` macros.
|
||||||
|
@ -1251,26 +1247,22 @@ pub(crate) mod builtin {
|
||||||
reason = "custom test frameworks are an unstable feature")]
|
reason = "custom test frameworks are an unstable feature")]
|
||||||
#[allow_internal_unstable(test, rustc_attrs)]
|
#[allow_internal_unstable(test, rustc_attrs)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[rustc_macro_transparency = "semitransparent"]
|
|
||||||
pub macro test_case($item:item) { /* compiler built-in */ }
|
pub macro test_case($item:item) { /* compiler built-in */ }
|
||||||
|
|
||||||
/// Attribute macro applied to a static to register it as a global allocator.
|
/// Attribute macro applied to a static to register it as a global allocator.
|
||||||
#[stable(feature = "global_allocator", since = "1.28.0")]
|
#[stable(feature = "global_allocator", since = "1.28.0")]
|
||||||
#[allow_internal_unstable(rustc_attrs)]
|
#[allow_internal_unstable(rustc_attrs)]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[rustc_macro_transparency = "semitransparent"]
|
|
||||||
pub macro global_allocator($item:item) { /* compiler built-in */ }
|
pub macro global_allocator($item:item) { /* compiler built-in */ }
|
||||||
|
|
||||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
||||||
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
|
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
|
||||||
|
|
||||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow_internal_unstable(core_intrinsics)]
|
#[allow_internal_unstable(core_intrinsics)]
|
||||||
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
|
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
|
||||||
|
|
|
@ -402,7 +402,6 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
|
||||||
parent -> _,
|
parent -> _,
|
||||||
call_site,
|
call_site,
|
||||||
def_site,
|
def_site,
|
||||||
default_transparency,
|
|
||||||
allow_internal_unstable,
|
allow_internal_unstable,
|
||||||
allow_internal_unsafe,
|
allow_internal_unsafe,
|
||||||
local_inner_macros,
|
local_inner_macros,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use std::mem;
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
use syntax::source_map::{SourceMap, StableSourceFileId};
|
use syntax::source_map::{SourceMap, StableSourceFileId};
|
||||||
use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
|
use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
|
||||||
use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData};
|
use syntax_pos::hygiene::{ExpnId, SyntaxContext};
|
||||||
|
|
||||||
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
||||||
|
|
||||||
|
@ -593,8 +593,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
||||||
// don't seem to be used after HIR lowering, so everything should be fine
|
// don't seem to be used after HIR lowering, so everything should be fine
|
||||||
// as long as incremental compilation does not kick in before that.
|
// as long as incremental compilation does not kick in before that.
|
||||||
let location = || Span::with_root_ctxt(lo, hi);
|
let location = || Span::with_root_ctxt(lo, hi);
|
||||||
let recover_from_expn_data = |this: &Self, expn_data, pos| {
|
let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
|
||||||
let span = location().fresh_expansion(expn_data);
|
let span = location().fresh_expansion_with_transparency(expn_data, transparency);
|
||||||
this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
|
this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
|
||||||
span
|
span
|
||||||
};
|
};
|
||||||
|
@ -603,9 +603,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
||||||
location()
|
location()
|
||||||
}
|
}
|
||||||
TAG_EXPN_DATA_INLINE => {
|
TAG_EXPN_DATA_INLINE => {
|
||||||
let expn_data = Decodable::decode(self)?;
|
let (expn_data, transparency) = Decodable::decode(self)?;
|
||||||
recover_from_expn_data(
|
recover_from_expn_data(
|
||||||
self, expn_data, AbsoluteBytePos::new(self.opaque.position())
|
self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TAG_EXPN_DATA_SHORTHAND => {
|
TAG_EXPN_DATA_SHORTHAND => {
|
||||||
|
@ -614,9 +614,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
||||||
if let Some(ctxt) = cached_ctxt {
|
if let Some(ctxt) = cached_ctxt {
|
||||||
Span::new(lo, hi, ctxt)
|
Span::new(lo, hi, ctxt)
|
||||||
} else {
|
} else {
|
||||||
let expn_data =
|
let (expn_data, transparency) =
|
||||||
self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
|
self.with_position(pos.to_usize(), |this| Decodable::decode(this))?;
|
||||||
recover_from_expn_data(self, expn_data, pos)
|
recover_from_expn_data(self, expn_data, transparency, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -819,7 +819,7 @@ where
|
||||||
if span_data.ctxt == SyntaxContext::root() {
|
if span_data.ctxt == SyntaxContext::root() {
|
||||||
TAG_NO_EXPN_DATA.encode(self)
|
TAG_NO_EXPN_DATA.encode(self)
|
||||||
} else {
|
} else {
|
||||||
let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
|
let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data();
|
||||||
if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
|
if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
|
||||||
TAG_EXPN_DATA_SHORTHAND.encode(self)?;
|
TAG_EXPN_DATA_SHORTHAND.encode(self)?;
|
||||||
pos.encode(self)
|
pos.encode(self)
|
||||||
|
@ -827,7 +827,7 @@ where
|
||||||
TAG_EXPN_DATA_INLINE.encode(self)?;
|
TAG_EXPN_DATA_INLINE.encode(self)?;
|
||||||
let pos = AbsoluteBytePos::new(self.position());
|
let pos = AbsoluteBytePos::new(self.position());
|
||||||
self.expn_data_shorthands.insert(expn_id, pos);
|
self.expn_data_shorthands.insert(expn_id, pos);
|
||||||
expn_data.encode(self)
|
(expn_data, transparency).encode(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
|
crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
|
||||||
if let Some(ext) = self.macro_map.get(&def_id) {
|
if let Some(ext) = self.macro_map.get(&def_id) {
|
||||||
return Some(ext.clone());
|
return Some(ext.clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1647,10 +1647,14 @@ impl<'a> Resolver<'a> {
|
||||||
if module.expansion != parent.expansion &&
|
if module.expansion != parent.expansion &&
|
||||||
module.expansion.is_descendant_of(parent.expansion) {
|
module.expansion.is_descendant_of(parent.expansion) {
|
||||||
// The macro is a proc macro derive
|
// The macro is a proc macro derive
|
||||||
if module.expansion.looks_like_proc_macro_derive() {
|
if let Some(&def_id) = self.macro_defs.get(&module.expansion) {
|
||||||
if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
|
if let Some(ext) = self.get_macro_by_def_id(def_id) {
|
||||||
*poisoned = Some(node_id);
|
if !ext.is_builtin && ext.macro_kind() == MacroKind::Derive {
|
||||||
return module.parent;
|
if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
|
||||||
|
*poisoned = Some(node_id);
|
||||||
|
return module.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::attr::{HasAttrs, Stability, Deprecation};
|
||||||
use crate::source_map::SourceMap;
|
use crate::source_map::SourceMap;
|
||||||
use crate::edition::Edition;
|
use crate::edition::Edition;
|
||||||
use crate::ext::expand::{self, AstFragment, Invocation};
|
use crate::ext::expand::{self, AstFragment, Invocation};
|
||||||
use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency};
|
use crate::ext::hygiene::{ExpnId, Transparency};
|
||||||
use crate::mut_visit::{self, MutVisitor};
|
use crate::mut_visit::{self, MutVisitor};
|
||||||
use crate::parse::{self, parser, DirectoryOwnership};
|
use crate::parse::{self, parser, DirectoryOwnership};
|
||||||
use crate::parse::token;
|
use crate::parse::token;
|
||||||
|
@ -549,8 +549,6 @@ pub struct SyntaxExtension {
|
||||||
pub kind: SyntaxExtensionKind,
|
pub kind: SyntaxExtensionKind,
|
||||||
/// Span of the macro definition.
|
/// Span of the macro definition.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// Hygienic properties of spans produced by this macro by default.
|
|
||||||
pub default_transparency: Transparency,
|
|
||||||
/// Whitelist of unstable features that are treated as stable inside this macro.
|
/// Whitelist of unstable features that are treated as stable inside this macro.
|
||||||
pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
|
pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
|
||||||
/// Suppresses the `unsafe_code` lint for code produced by this macro.
|
/// Suppresses the `unsafe_code` lint for code produced by this macro.
|
||||||
|
@ -572,22 +570,6 @@ pub struct SyntaxExtension {
|
||||||
pub is_derive_copy: bool,
|
pub is_derive_copy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyntaxExtensionKind {
|
|
||||||
/// When a syntax extension is constructed,
|
|
||||||
/// its transparency can often be inferred from its kind.
|
|
||||||
fn default_transparency(&self) -> Transparency {
|
|
||||||
match self {
|
|
||||||
SyntaxExtensionKind::Bang(..) |
|
|
||||||
SyntaxExtensionKind::Attr(..) |
|
|
||||||
SyntaxExtensionKind::Derive(..) |
|
|
||||||
SyntaxExtensionKind::NonMacroAttr { .. } => Transparency::Opaque,
|
|
||||||
SyntaxExtensionKind::LegacyBang(..) |
|
|
||||||
SyntaxExtensionKind::LegacyAttr(..) |
|
|
||||||
SyntaxExtensionKind::LegacyDerive(..) => Transparency::SemiTransparent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SyntaxExtension {
|
impl SyntaxExtension {
|
||||||
/// Returns which kind of macro calls this syntax extension.
|
/// Returns which kind of macro calls this syntax extension.
|
||||||
pub fn macro_kind(&self) -> MacroKind {
|
pub fn macro_kind(&self) -> MacroKind {
|
||||||
|
@ -606,7 +588,6 @@ impl SyntaxExtension {
|
||||||
pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
|
pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
|
||||||
SyntaxExtension {
|
SyntaxExtension {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
default_transparency: kind.default_transparency(),
|
|
||||||
allow_internal_unstable: None,
|
allow_internal_unstable: None,
|
||||||
allow_internal_unsafe: false,
|
allow_internal_unsafe: false,
|
||||||
local_inner_macros: false,
|
local_inner_macros: false,
|
||||||
|
@ -646,7 +627,6 @@ impl SyntaxExtension {
|
||||||
parent,
|
parent,
|
||||||
call_site,
|
call_site,
|
||||||
def_site: self.span,
|
def_site: self.span,
|
||||||
default_transparency: self.default_transparency,
|
|
||||||
allow_internal_unstable: self.allow_internal_unstable.clone(),
|
allow_internal_unstable: self.allow_internal_unstable.clone(),
|
||||||
allow_internal_unsafe: self.allow_internal_unsafe,
|
allow_internal_unsafe: self.allow_internal_unsafe,
|
||||||
local_inner_macros: self.local_inner_macros,
|
local_inner_macros: self.local_inner_macros,
|
||||||
|
@ -760,23 +740,39 @@ impl<'a> ExtCtxt<'a> {
|
||||||
pub fn call_site(&self) -> Span {
|
pub fn call_site(&self) -> Span {
|
||||||
self.current_expansion.id.expn_data().call_site
|
self.current_expansion.id.expn_data().call_site
|
||||||
}
|
}
|
||||||
pub fn backtrace(&self) -> SyntaxContext {
|
|
||||||
SyntaxContext::root().apply_mark(self.current_expansion.id)
|
/// Equivalent of `Span::def_site` from the proc macro API,
|
||||||
|
/// except that the location is taken from the span passed as an argument.
|
||||||
|
pub fn with_def_site_ctxt(&self, span: Span) -> Span {
|
||||||
|
span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Opaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equivalent of `Span::call_site` from the proc macro API,
|
||||||
|
/// except that the location is taken from the span passed as an argument.
|
||||||
|
pub fn with_call_site_ctxt(&self, span: Span) -> Span {
|
||||||
|
span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Transparent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
|
||||||
|
/// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
|
||||||
|
/// or with `with_call_site_ctxt` (where necessary).
|
||||||
|
pub fn with_legacy_ctxt(&self, span: Span) -> Span {
|
||||||
|
span.with_ctxt_from_mark(self.current_expansion.id, Transparency::SemiTransparent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns span for the macro which originally caused the current expansion to happen.
|
/// Returns span for the macro which originally caused the current expansion to happen.
|
||||||
///
|
///
|
||||||
/// Stops backtracing at include! boundary.
|
/// Stops backtracing at include! boundary.
|
||||||
pub fn expansion_cause(&self) -> Option<Span> {
|
pub fn expansion_cause(&self) -> Option<Span> {
|
||||||
let mut ctxt = self.backtrace();
|
let mut expn_id = self.current_expansion.id;
|
||||||
let mut last_macro = None;
|
let mut last_macro = None;
|
||||||
loop {
|
loop {
|
||||||
let expn_data = ctxt.outer_expn_data();
|
let expn_data = expn_id.expn_data();
|
||||||
// Stop going up the backtrace once include! is encountered
|
// Stop going up the backtrace once include! is encountered
|
||||||
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
|
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctxt = expn_data.call_site.ctxt();
|
expn_id = expn_data.call_site.ctxt().outer_expn();
|
||||||
last_macro = Some(expn_data.call_site);
|
last_macro = Some(expn_data.call_site);
|
||||||
}
|
}
|
||||||
last_macro
|
last_macro
|
||||||
|
@ -865,7 +861,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
ast::Ident::from_str(st)
|
ast::Ident::from_str(st)
|
||||||
}
|
}
|
||||||
pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
|
pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
|
||||||
let def_site = DUMMY_SP.apply_mark(self.current_expansion.id);
|
let def_site = self.with_def_site_ctxt(DUMMY_SP);
|
||||||
iter::once(Ident::new(kw::DollarCrate, def_site))
|
iter::once(Ident::new(kw::DollarCrate, def_site))
|
||||||
.chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
|
.chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -565,7 +565,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
return fragment_kind.dummy(span);
|
return fragment_kind.dummy(span);
|
||||||
}
|
}
|
||||||
let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path };
|
let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path };
|
||||||
let span = span.with_ctxt(self.cx.backtrace());
|
|
||||||
let items = expander.expand(self.cx, span, &meta, item);
|
let items = expander.expand(self.cx, span, &meta, item);
|
||||||
fragment_kind.expect_from_annotatables(items)
|
fragment_kind.expect_from_annotatables(items)
|
||||||
}
|
}
|
||||||
|
@ -1389,17 +1388,3 @@ impl<'feat> ExpansionConfig<'feat> {
|
||||||
self.features.map_or(false, |features| features.custom_inner_attributes)
|
self.features.map_or(false, |features| features.custom_inner_attributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Marker adds the given mark to the syntax context.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Marker(pub ExpnId);
|
|
||||||
|
|
||||||
impl MutVisitor for Marker {
|
|
||||||
fn visit_span(&mut self, span: &mut Span) {
|
|
||||||
*span = span.apply_mark(self.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_mac(&mut self, mac: &mut ast::Mac) {
|
|
||||||
noop_visit_mac(mac, self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}
|
||||||
use errors::{Diagnostic, DiagnosticBuilder};
|
use errors::{Diagnostic, DiagnosticBuilder};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
|
use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
|
||||||
use syntax_pos::hygiene::{SyntaxContext, Transparency};
|
|
||||||
use syntax_pos::symbol::{kw, sym, Symbol};
|
use syntax_pos::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use proc_macro::{Delimiter, Level, LineColumn, Spacing};
|
use proc_macro::{Delimiter, Level, LineColumn, Spacing};
|
||||||
|
@ -363,16 +362,10 @@ impl<'a> Rustc<'a> {
|
||||||
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
|
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
|
||||||
// No way to determine def location for a proc macro right now, so use call location.
|
// No way to determine def location for a proc macro right now, so use call location.
|
||||||
let location = cx.current_expansion.id.expn_data().call_site;
|
let location = cx.current_expansion.id.expn_data().call_site;
|
||||||
let to_span = |transparency| {
|
|
||||||
location.with_ctxt(
|
|
||||||
SyntaxContext::root()
|
|
||||||
.apply_mark_with_transparency(cx.current_expansion.id, transparency),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Rustc {
|
Rustc {
|
||||||
sess: cx.parse_sess,
|
sess: cx.parse_sess,
|
||||||
def_site: to_span(Transparency::Opaque),
|
def_site: cx.with_def_site_ctxt(location),
|
||||||
call_site: to_span(Transparency::Transparent),
|
call_site: cx.with_call_site_ctxt(location),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ use crate::{ast, attr, attr::TransparencyError};
|
||||||
|
|
||||||
use errors::{DiagnosticBuilder, FatalError};
|
use errors::{DiagnosticBuilder, FatalError};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use syntax_pos::hygiene::Transparency;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
@ -128,6 +129,7 @@ impl<'a> ParserAnyMacro<'a> {
|
||||||
struct MacroRulesMacroExpander {
|
struct MacroRulesMacroExpander {
|
||||||
name: ast::Ident,
|
name: ast::Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
transparency: Transparency,
|
||||||
lhses: Vec<quoted::TokenTree>,
|
lhses: Vec<quoted::TokenTree>,
|
||||||
rhses: Vec<quoted::TokenTree>,
|
rhses: Vec<quoted::TokenTree>,
|
||||||
valid: bool,
|
valid: bool,
|
||||||
|
@ -143,7 +145,9 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
||||||
if !self.valid {
|
if !self.valid {
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses)
|
generic_extension(
|
||||||
|
cx, sp, self.span, self.name, self.transparency, input, &self.lhses, &self.rhses
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +162,7 @@ fn generic_extension<'cx>(
|
||||||
sp: Span,
|
sp: Span,
|
||||||
def_span: Span,
|
def_span: Span,
|
||||||
name: ast::Ident,
|
name: ast::Ident,
|
||||||
|
transparency: Transparency,
|
||||||
arg: TokenStream,
|
arg: TokenStream,
|
||||||
lhses: &[quoted::TokenTree],
|
lhses: &[quoted::TokenTree],
|
||||||
rhses: &[quoted::TokenTree],
|
rhses: &[quoted::TokenTree],
|
||||||
|
@ -187,7 +192,7 @@ fn generic_extension<'cx>(
|
||||||
|
|
||||||
let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
|
let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
|
||||||
// rhs has holes ( `$id` and `$(...)` that need filled)
|
// rhs has holes ( `$id` and `$(...)` that need filled)
|
||||||
let mut tts = transcribe(cx, &named_matches, rhs);
|
let mut tts = transcribe(cx, &named_matches, rhs, transparency);
|
||||||
|
|
||||||
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
||||||
// proper positions in error reporting, while maintaining the macro_backtrace.
|
// proper positions in error reporting, while maintaining the macro_backtrace.
|
||||||
|
@ -415,11 +420,7 @@ pub fn compile(
|
||||||
// that is not lint-checked and trigger the "failed to process buffered lint here" bug.
|
// that is not lint-checked and trigger the "failed to process buffered lint here" bug.
|
||||||
valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses);
|
valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses);
|
||||||
|
|
||||||
let expander: Box<_> =
|
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
|
||||||
Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid });
|
|
||||||
|
|
||||||
let (default_transparency, transparency_error) =
|
|
||||||
attr::find_transparency(&def.attrs, body.legacy);
|
|
||||||
match transparency_error {
|
match transparency_error {
|
||||||
Some(TransparencyError::UnknownTransparency(value, span)) =>
|
Some(TransparencyError::UnknownTransparency(value, span)) =>
|
||||||
sess.span_diagnostic.span_err(
|
sess.span_diagnostic.span_err(
|
||||||
|
@ -432,6 +433,10 @@ pub fn compile(
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let expander: Box<_> = Box::new(MacroRulesMacroExpander {
|
||||||
|
name: def.ident, span: def.span, transparency, lhses, rhses, valid
|
||||||
|
});
|
||||||
|
|
||||||
let allow_internal_unstable =
|
let allow_internal_unstable =
|
||||||
attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
|
attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
|
||||||
attr.meta_item_list()
|
attr.meta_item_list()
|
||||||
|
@ -473,7 +478,6 @@ pub fn compile(
|
||||||
SyntaxExtension {
|
SyntaxExtension {
|
||||||
kind: SyntaxExtensionKind::LegacyBang(expander),
|
kind: SyntaxExtensionKind::LegacyBang(expander),
|
||||||
span: def.span,
|
span: def.span,
|
||||||
default_transparency,
|
|
||||||
allow_internal_unstable,
|
allow_internal_unstable,
|
||||||
allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
|
allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
|
||||||
local_inner_macros,
|
local_inner_macros,
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::ast::Ident;
|
use crate::ast::{Ident, Mac};
|
||||||
use crate::ext::base::ExtCtxt;
|
use crate::ext::base::ExtCtxt;
|
||||||
use crate::ext::expand::Marker;
|
|
||||||
use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
|
use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
|
||||||
use crate::ext::tt::quoted;
|
use crate::ext::tt::quoted;
|
||||||
use crate::mut_visit::noop_visit_tt;
|
use crate::mut_visit::{self, MutVisitor};
|
||||||
use crate::parse::token::{self, NtTT, Token};
|
use crate::parse::token::{self, NtTT, Token};
|
||||||
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
|
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
|
||||||
|
|
||||||
|
@ -11,8 +10,31 @@ use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use syntax_pos::hygiene::{ExpnId, Transparency};
|
||||||
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
// A Marker adds the given mark to the syntax context.
|
||||||
|
struct Marker(ExpnId, Transparency);
|
||||||
|
|
||||||
|
impl MutVisitor for Marker {
|
||||||
|
fn visit_span(&mut self, span: &mut Span) {
|
||||||
|
*span = span.apply_mark(self.0, self.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_mac(&mut self, mac: &mut Mac) {
|
||||||
|
mut_visit::noop_visit_mac(mac, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Marker {
|
||||||
|
fn visit_delim_span(&mut self, dspan: &mut DelimSpan) {
|
||||||
|
self.visit_span(&mut dspan.open);
|
||||||
|
self.visit_span(&mut dspan.close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
|
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
|
||||||
enum Frame {
|
enum Frame {
|
||||||
Delimited { forest: Lrc<quoted::Delimited>, idx: usize, span: DelimSpan },
|
Delimited { forest: Lrc<quoted::Delimited>, idx: usize, span: DelimSpan },
|
||||||
|
@ -68,6 +90,7 @@ pub(super) fn transcribe(
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
interp: &FxHashMap<Ident, NamedMatch>,
|
interp: &FxHashMap<Ident, NamedMatch>,
|
||||||
src: Vec<quoted::TokenTree>,
|
src: Vec<quoted::TokenTree>,
|
||||||
|
transparency: Transparency,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
// Nothing for us to transcribe...
|
// Nothing for us to transcribe...
|
||||||
if src.is_empty() {
|
if src.is_empty() {
|
||||||
|
@ -96,6 +119,7 @@ pub(super) fn transcribe(
|
||||||
// again, and we are done transcribing.
|
// again, and we are done transcribing.
|
||||||
let mut result: Vec<TreeAndJoint> = Vec::new();
|
let mut result: Vec<TreeAndJoint> = Vec::new();
|
||||||
let mut result_stack = Vec::new();
|
let mut result_stack = Vec::new();
|
||||||
|
let mut marker = Marker(cx.current_expansion.id, transparency);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Look at the last frame on the stack.
|
// Look at the last frame on the stack.
|
||||||
|
@ -207,7 +231,7 @@ pub(super) fn transcribe(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the meta-var with the matched token tree from the invocation.
|
// Replace the meta-var with the matched token tree from the invocation.
|
||||||
quoted::TokenTree::MetaVar(mut sp, ident) => {
|
quoted::TokenTree::MetaVar(mut sp, mut ident) => {
|
||||||
// Find the matched nonterminal from the macro invocation, and use it to replace
|
// Find the matched nonterminal from the macro invocation, and use it to replace
|
||||||
// the meta-var.
|
// the meta-var.
|
||||||
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
|
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
|
||||||
|
@ -218,7 +242,7 @@ pub(super) fn transcribe(
|
||||||
if let NtTT(ref tt) = **nt {
|
if let NtTT(ref tt) = **nt {
|
||||||
result.push(tt.clone().into());
|
result.push(tt.clone().into());
|
||||||
} else {
|
} else {
|
||||||
sp = sp.apply_mark(cx.current_expansion.id);
|
marker.visit_span(&mut sp);
|
||||||
let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
|
let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
|
||||||
result.push(token.into());
|
result.push(token.into());
|
||||||
}
|
}
|
||||||
|
@ -232,9 +256,8 @@ pub(super) fn transcribe(
|
||||||
} else {
|
} else {
|
||||||
// If we aren't able to match the meta-var, we push it back into the result but
|
// If we aren't able to match the meta-var, we push it back into the result but
|
||||||
// with modified syntax context. (I believe this supports nested macros).
|
// with modified syntax context. (I believe this supports nested macros).
|
||||||
let ident =
|
marker.visit_span(&mut sp);
|
||||||
Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.id));
|
marker.visit_ident(&mut ident);
|
||||||
sp = sp.apply_mark(cx.current_expansion.id);
|
|
||||||
result.push(TokenTree::token(token::Dollar, sp).into());
|
result.push(TokenTree::token(token::Dollar, sp).into());
|
||||||
result.push(TokenTree::Token(Token::from_ast_ident(ident)).into());
|
result.push(TokenTree::Token(Token::from_ast_ident(ident)).into());
|
||||||
}
|
}
|
||||||
|
@ -246,7 +269,7 @@ pub(super) fn transcribe(
|
||||||
// jump back out of the Delimited, pop the result_stack and add the new results back to
|
// jump back out of the Delimited, pop the result_stack and add the new results back to
|
||||||
// the previous results (from outside the Delimited).
|
// the previous results (from outside the Delimited).
|
||||||
quoted::TokenTree::Delimited(mut span, delimited) => {
|
quoted::TokenTree::Delimited(mut span, delimited) => {
|
||||||
span = span.apply_mark(cx.current_expansion.id);
|
marker.visit_delim_span(&mut span);
|
||||||
stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
|
stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
|
||||||
result_stack.push(mem::take(&mut result));
|
result_stack.push(mem::take(&mut result));
|
||||||
}
|
}
|
||||||
|
@ -254,9 +277,8 @@ pub(super) fn transcribe(
|
||||||
// Nothing much to do here. Just push the token to the result, being careful to
|
// Nothing much to do here. Just push the token to the result, being careful to
|
||||||
// preserve syntax context.
|
// preserve syntax context.
|
||||||
quoted::TokenTree::Token(token) => {
|
quoted::TokenTree::Token(token) => {
|
||||||
let mut marker = Marker(cx.current_expansion.id);
|
|
||||||
let mut tt = TokenTree::Token(token);
|
let mut tt = TokenTree::Token(token);
|
||||||
noop_visit_tt(&mut tt, &mut marker);
|
marker.visit_tt(&mut tt);
|
||||||
result.push(tt.into());
|
result.push(tt.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::parse::Directory;
|
||||||
use crate::parse::token::{self, DelimToken, Token, TokenKind};
|
use crate::parse::token::{self, DelimToken, Token, TokenKind};
|
||||||
use crate::print::pprust;
|
use crate::print::pprust;
|
||||||
|
|
||||||
use syntax_pos::{BytePos, ExpnId, Span, DUMMY_SP};
|
use syntax_pos::{BytePos, Span, DUMMY_SP};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use rustc_data_structures::static_assert_size;
|
use rustc_data_structures::static_assert_size;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
@ -547,11 +547,4 @@ impl DelimSpan {
|
||||||
pub fn entire(self) -> Span {
|
pub fn entire(self) -> Span {
|
||||||
self.open.with_hi(self.close.hi())
|
self.open.with_hi(self.close.hi())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_mark(self, expn_id: ExpnId) -> Self {
|
|
||||||
DelimSpan {
|
|
||||||
open: self.open.apply_mark(expn_id),
|
|
||||||
close: self.close.apply_mark(expn_id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
MacEager::expr(P(ast::Expr {
|
MacEager::expr(P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::InlineAsm(P(inline_asm)),
|
node: ast::ExprKind::InlineAsm(P(inline_asm)),
|
||||||
span: sp.with_ctxt(cx.backtrace()),
|
span: cx.with_legacy_ctxt(sp),
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn expand_assert<'cx>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let sp = sp.apply_mark(cx.current_expansion.id);
|
let sp = cx.with_legacy_ctxt(sp);
|
||||||
let panic_call = Mac {
|
let panic_call = Mac {
|
||||||
path: Path::from_ident(Ident::new(sym::panic, sp)),
|
path: Path::from_ident(Ident::new(sym::panic, sp)),
|
||||||
tts: custom_message.unwrap_or_else(|| {
|
tts: custom_message.unwrap_or_else(|| {
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn expand_cfg(
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: &[tokenstream::TokenTree],
|
tts: &[tokenstream::TokenTree],
|
||||||
) -> Box<dyn base::MacResult + 'static> {
|
) -> Box<dyn base::MacResult + 'static> {
|
||||||
let sp = sp.apply_mark(cx.current_expansion.id);
|
let sp = cx.with_legacy_ctxt(sp);
|
||||||
|
|
||||||
match parse_cfg(cx, sp, tts) {
|
match parse_cfg(cx, sp, tts) {
|
||||||
Ok(cfg) => {
|
Ok(cfg) => {
|
||||||
|
|
|
@ -59,6 +59,6 @@ pub fn expand_syntax_ext(
|
||||||
} else if has_errors {
|
} else if has_errors {
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
let sp = sp.apply_mark(cx.current_expansion.id);
|
let sp = cx.with_legacy_ctxt(sp);
|
||||||
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
|
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.id));
|
let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp));
|
||||||
|
|
||||||
struct ConcatIdentsResult { ident: ast::Ident }
|
struct ConcatIdentsResult { ident: ast::Ident }
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ fn cs_clone_shallow(name: &str,
|
||||||
ty: P<ast::Ty>, span: Span, helper_name: &str) {
|
ty: P<ast::Ty>, span: Span, helper_name: &str) {
|
||||||
// Generate statement `let _: helper_name<ty>;`,
|
// Generate statement `let _: helper_name<ty>;`,
|
||||||
// set the expn ID so we can use the unstable struct.
|
// set the expn ID so we can use the unstable struct.
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let assert_path = cx.path_all(span, true,
|
let assert_path = cx.path_all(span, true,
|
||||||
cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
|
cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
|
||||||
vec![GenericArg::Type(ty)], vec![]);
|
vec![GenericArg::Type(ty)], vec![]);
|
||||||
|
|
|
@ -53,7 +53,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>,
|
||||||
ty: P<ast::Ty>, span: Span, helper_name: &str) {
|
ty: P<ast::Ty>, span: Span, helper_name: &str) {
|
||||||
// Generate statement `let _: helper_name<ty>;`,
|
// Generate statement `let _: helper_name<ty>;`,
|
||||||
// set the expn ID so we can use the unstable struct.
|
// set the expn ID so we can use the unstable struct.
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let assert_path = cx.path_all(span, true,
|
let assert_path = cx.path_all(span, true,
|
||||||
cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
|
cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
|
||||||
vec![GenericArg::Type(ty)], vec![]);
|
vec![GenericArg::Type(ty)], vec![]);
|
||||||
|
|
|
@ -60,7 +60,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||||
};
|
};
|
||||||
|
|
||||||
// We want to make sure we have the ctxt set so that we can use unstable methods
|
// We want to make sure we have the ctxt set so that we can use unstable methods
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
|
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
|
||||||
let builder = Ident::from_str_and_span("debug_trait_builder", span);
|
let builder = Ident::from_str_and_span("debug_trait_builder", span);
|
||||||
let builder_expr = cx.expr_ident(span, builder.clone());
|
let builder_expr = cx.expr_ident(span, builder.clone());
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl<'a> Path<'a> {
|
||||||
PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
|
PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
|
||||||
PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
|
PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
|
||||||
PathKind::Std => {
|
PathKind::Std => {
|
||||||
let def_site = DUMMY_SP.apply_mark(cx.current_expansion.id);
|
let def_site = cx.with_def_site_ctxt(DUMMY_SP);
|
||||||
idents.insert(0, Ident::new(kw::DollarCrate, def_site));
|
idents.insert(0, Ident::new(kw::DollarCrate, def_site));
|
||||||
cx.path_all(span, false, idents, params, Vec::new())
|
cx.path_all(span, false, idents, params, Vec::new())
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ impl MultiItemModifier for BuiltinDerive {
|
||||||
meta_item: &MetaItem,
|
meta_item: &MetaItem,
|
||||||
item: Annotatable)
|
item: Annotatable)
|
||||||
-> Vec<Annotatable> {
|
-> Vec<Annotatable> {
|
||||||
|
// FIXME: Built-in derives often forget to give spans contexts,
|
||||||
|
// so we are doing it here in a centralized way.
|
||||||
|
let span = ecx.with_def_site_ctxt(span);
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
|
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
|
||||||
items
|
items
|
||||||
|
@ -60,7 +63,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
|
||||||
intrinsic: &str,
|
intrinsic: &str,
|
||||||
args: Vec<P<ast::Expr>>)
|
args: Vec<P<ast::Expr>>)
|
||||||
-> P<ast::Expr> {
|
-> P<ast::Expr> {
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
|
let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
|
||||||
let call = cx.expr_call_global(span, path, args);
|
let call = cx.expr_call_global(span, path, args);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sp = sp.apply_mark(cx.current_expansion.id);
|
let sp = cx.with_legacy_ctxt(sp);
|
||||||
let e = match env::var(&*var.as_str()) {
|
let e = match env::var(&*var.as_str()) {
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
|
let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
|
||||||
|
|
|
@ -12,7 +12,7 @@ use syntax::parse::token;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax::tokenstream;
|
use syntax::tokenstream;
|
||||||
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
|
use syntax_pos::{MultiSpan, Span};
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -666,8 +666,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
// passed to this function.
|
// passed to this function.
|
||||||
for (i, e) in self.args.into_iter().enumerate() {
|
for (i, e) in self.args.into_iter().enumerate() {
|
||||||
let name = names_pos[i];
|
let name = names_pos[i];
|
||||||
let span =
|
let span = self.ecx.with_def_site_ctxt(e.span);
|
||||||
DUMMY_SP.with_ctxt(e.span.ctxt().apply_mark(self.ecx.current_expansion.id));
|
|
||||||
pats.push(self.ecx.pat_ident(span, name));
|
pats.push(self.ecx.pat_ident(span, name));
|
||||||
for ref arg_ty in self.arg_unique_types[i].iter() {
|
for ref arg_ty in self.arg_unique_types[i].iter() {
|
||||||
locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
|
locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
|
||||||
|
@ -745,7 +744,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
ty: &ArgumentType,
|
ty: &ArgumentType,
|
||||||
arg: ast::Ident,
|
arg: ast::Ident,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
sp = sp.apply_mark(ecx.current_expansion.id);
|
sp = ecx.with_def_site_ctxt(sp);
|
||||||
let arg = ecx.expr_ident(sp, arg);
|
let arg = ecx.expr_ident(sp, arg);
|
||||||
let trait_ = match *ty {
|
let trait_ = match *ty {
|
||||||
Placeholder(ref tyname) => {
|
Placeholder(ref tyname) => {
|
||||||
|
@ -798,7 +797,7 @@ fn expand_format_args_impl<'cx>(
|
||||||
tts: &[tokenstream::TokenTree],
|
tts: &[tokenstream::TokenTree],
|
||||||
nl: bool,
|
nl: bool,
|
||||||
) -> Box<dyn base::MacResult + 'cx> {
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
sp = sp.apply_mark(ecx.current_expansion.id);
|
sp = ecx.with_def_site_ctxt(sp);
|
||||||
match parse_args(ecx, sp, tts) {
|
match parse_args(ecx, sp, tts) {
|
||||||
Ok((efmt, args, names)) => {
|
Ok((efmt, args, names)) => {
|
||||||
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl))
|
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl))
|
||||||
|
@ -842,7 +841,7 @@ pub fn expand_preparsed_format_args(
|
||||||
let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
|
let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
|
||||||
|
|
||||||
let mut macsp = ecx.call_site();
|
let mut macsp = ecx.call_site();
|
||||||
macsp = macsp.with_ctxt(ecx.backtrace());
|
macsp = ecx.with_def_site_ctxt(macsp);
|
||||||
|
|
||||||
let msg = "format argument must be a string literal";
|
let msg = "format argument must be a string literal";
|
||||||
let fmt_sp = efmt.span;
|
let fmt_sp = efmt.span;
|
||||||
|
|
|
@ -3,7 +3,6 @@ use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident};
|
||||||
use syntax::attr::check_builtin_macro_attribute;
|
use syntax::attr::check_builtin_macro_attribute;
|
||||||
use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
|
use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
|
||||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
use syntax::ext::hygiene::SyntaxContext;
|
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::{kw, sym, Symbol};
|
use syntax::symbol::{kw, sym, Symbol};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -29,7 +28,7 @@ pub fn expand(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a bunch of new items using the AllocFnFactory
|
// Generate a bunch of new items using the AllocFnFactory
|
||||||
let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
|
let span = ecx.with_legacy_ctxt(item.span);
|
||||||
let f = AllocFnFactory {
|
let f = AllocFnFactory {
|
||||||
span,
|
span,
|
||||||
kind: AllocatorKind::Global,
|
kind: AllocatorKind::Global,
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ItemKind::GlobalAsm(P(global_asm)),
|
node: ast::ItemKind::GlobalAsm(P(global_asm)),
|
||||||
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
||||||
span: sp.with_ctxt(cx.backtrace()),
|
span: cx.with_legacy_ctxt(sp),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
})])
|
})])
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr::{self, check_builtin_macro_attribute};
|
use syntax::attr::{self, check_builtin_macro_attribute};
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::ext::hygiene::SyntaxContext;
|
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
use syntax::source_map::respan;
|
use syntax::source_map::respan;
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
|
@ -29,7 +28,7 @@ pub fn expand_test_case(
|
||||||
|
|
||||||
if !ecx.ecfg.should_test { return vec![]; }
|
if !ecx.ecfg.should_test { return vec![]; }
|
||||||
|
|
||||||
let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
|
let sp = ecx.with_legacy_ctxt(attr_sp);
|
||||||
let mut item = anno_item.expect_item();
|
let mut item = anno_item.expect_item();
|
||||||
item = item.map(|mut item| {
|
item = item.map(|mut item| {
|
||||||
item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
|
item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
|
||||||
|
@ -93,8 +92,7 @@ pub fn expand_test_or_bench(
|
||||||
return vec![Annotatable::Item(item)];
|
return vec![Annotatable::Item(item)];
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id);
|
let (sp, attr_sp) = (cx.with_legacy_ctxt(item.span), cx.with_legacy_ctxt(attr_sp));
|
||||||
let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt));
|
|
||||||
|
|
||||||
// Gensym "test" so we can extern crate without conflicting with any local names
|
// Gensym "test" so we can extern crate without conflicting with any local names
|
||||||
let test_id = cx.ident_of("test").gensym();
|
let test_id = cx.ident_of("test").gensym();
|
||||||
|
|
|
@ -119,18 +119,6 @@ impl ExpnId {
|
||||||
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
||||||
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
|
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for enabling some compatibility fallback in resolve.
|
|
||||||
#[inline]
|
|
||||||
pub fn looks_like_proc_macro_derive(self) -> bool {
|
|
||||||
HygieneData::with(|data| {
|
|
||||||
let expn_data = data.expn_data(self);
|
|
||||||
if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind {
|
|
||||||
return expn_data.default_transparency == Transparency::Opaque;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -195,24 +183,25 @@ impl HygieneData {
|
||||||
self.syntax_context_data[ctxt.0 as usize].outer_expn
|
self.syntax_context_data[ctxt.0 as usize].outer_expn
|
||||||
}
|
}
|
||||||
|
|
||||||
fn outer_transparency(&self, ctxt: SyntaxContext) -> Transparency {
|
fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
|
||||||
self.syntax_context_data[ctxt.0 as usize].outer_transparency
|
let data = &self.syntax_context_data[ctxt.0 as usize];
|
||||||
|
(data.outer_expn, data.outer_transparency)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||||
self.syntax_context_data[ctxt.0 as usize].parent
|
self.syntax_context_data[ctxt.0 as usize].parent
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_mark(&self, ctxt: &mut SyntaxContext) -> ExpnId {
|
fn remove_mark(&self, ctxt: &mut SyntaxContext) -> (ExpnId, Transparency) {
|
||||||
let outer_expn = self.outer_expn(*ctxt);
|
let outer_mark = self.outer_mark(*ctxt);
|
||||||
*ctxt = self.parent_ctxt(*ctxt);
|
*ctxt = self.parent_ctxt(*ctxt);
|
||||||
outer_expn
|
outer_mark
|
||||||
}
|
}
|
||||||
|
|
||||||
fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
|
fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
|
||||||
let mut marks = Vec::new();
|
let mut marks = Vec::new();
|
||||||
while ctxt != SyntaxContext::root() {
|
while ctxt != SyntaxContext::root() {
|
||||||
marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
|
marks.push(self.outer_mark(ctxt));
|
||||||
ctxt = self.parent_ctxt(ctxt);
|
ctxt = self.parent_ctxt(ctxt);
|
||||||
}
|
}
|
||||||
marks.reverse();
|
marks.reverse();
|
||||||
|
@ -229,20 +218,14 @@ impl HygieneData {
|
||||||
fn adjust(&self, ctxt: &mut SyntaxContext, expn_id: ExpnId) -> Option<ExpnId> {
|
fn adjust(&self, ctxt: &mut SyntaxContext, expn_id: ExpnId) -> Option<ExpnId> {
|
||||||
let mut scope = None;
|
let mut scope = None;
|
||||||
while !self.is_descendant_of(expn_id, self.outer_expn(*ctxt)) {
|
while !self.is_descendant_of(expn_id, self.outer_expn(*ctxt)) {
|
||||||
scope = Some(self.remove_mark(ctxt));
|
scope = Some(self.remove_mark(ctxt).0);
|
||||||
}
|
}
|
||||||
scope
|
scope
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
|
fn apply_mark(
|
||||||
assert_ne!(expn_id, ExpnId::root());
|
&mut self, ctxt: SyntaxContext, expn_id: ExpnId, transparency: Transparency
|
||||||
self.apply_mark_with_transparency(
|
) -> SyntaxContext {
|
||||||
ctxt, expn_id, self.expn_data(expn_id).default_transparency
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
|
|
||||||
transparency: Transparency) -> SyntaxContext {
|
|
||||||
assert_ne!(expn_id, ExpnId::root());
|
assert_ne!(expn_id, ExpnId::root());
|
||||||
if transparency == Transparency::Opaque {
|
if transparency == Transparency::Opaque {
|
||||||
return self.apply_mark_internal(ctxt, expn_id, transparency);
|
return self.apply_mark_internal(ctxt, expn_id, transparency);
|
||||||
|
@ -376,15 +359,9 @@ impl SyntaxContext {
|
||||||
SyntaxContext(raw)
|
SyntaxContext(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend a syntax context with a given expansion and default transparency for that expansion.
|
|
||||||
pub fn apply_mark(self, expn_id: ExpnId) -> SyntaxContext {
|
|
||||||
HygieneData::with(|data| data.apply_mark(self, expn_id))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extend a syntax context with a given expansion and transparency.
|
/// Extend a syntax context with a given expansion and transparency.
|
||||||
pub fn apply_mark_with_transparency(self, expn_id: ExpnId, transparency: Transparency)
|
pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
|
||||||
-> SyntaxContext {
|
HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
|
||||||
HygieneData::with(|data| data.apply_mark_with_transparency(self, expn_id, transparency))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pulls a single mark off of the syntax context. This effectively moves the
|
/// Pulls a single mark off of the syntax context. This effectively moves the
|
||||||
|
@ -404,7 +381,7 @@ impl SyntaxContext {
|
||||||
/// invocation of f that created g1.
|
/// invocation of f that created g1.
|
||||||
/// Returns the mark that was removed.
|
/// Returns the mark that was removed.
|
||||||
pub fn remove_mark(&mut self) -> ExpnId {
|
pub fn remove_mark(&mut self) -> ExpnId {
|
||||||
HygieneData::with(|data| data.remove_mark(self))
|
HygieneData::with(|data| data.remove_mark(self).0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
|
pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
|
||||||
|
@ -477,8 +454,8 @@ impl SyntaxContext {
|
||||||
let mut scope = None;
|
let mut scope = None;
|
||||||
let mut glob_ctxt = data.modern(glob_span.ctxt());
|
let mut glob_ctxt = data.modern(glob_span.ctxt());
|
||||||
while !data.is_descendant_of(expn_id, data.outer_expn(glob_ctxt)) {
|
while !data.is_descendant_of(expn_id, data.outer_expn(glob_ctxt)) {
|
||||||
scope = Some(data.remove_mark(&mut glob_ctxt));
|
scope = Some(data.remove_mark(&mut glob_ctxt).0);
|
||||||
if data.remove_mark(self) != scope.unwrap() {
|
if data.remove_mark(self).0 != scope.unwrap() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -509,9 +486,9 @@ impl SyntaxContext {
|
||||||
marks.push(data.remove_mark(&mut glob_ctxt));
|
marks.push(data.remove_mark(&mut glob_ctxt));
|
||||||
}
|
}
|
||||||
|
|
||||||
let scope = marks.last().cloned();
|
let scope = marks.last().map(|mark| mark.0);
|
||||||
while let Some(mark) = marks.pop() {
|
while let Some((expn_id, transparency)) = marks.pop() {
|
||||||
*self = data.apply_mark(*self, mark);
|
*self = data.apply_mark(*self, expn_id, transparency);
|
||||||
}
|
}
|
||||||
Some(scope)
|
Some(scope)
|
||||||
})
|
})
|
||||||
|
@ -547,13 +524,11 @@ impl SyntaxContext {
|
||||||
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
|
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `ctxt.outer_expn_with_data()` is equivalent to but faster than
|
|
||||||
/// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
|
pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
|
||||||
HygieneData::with(|data| {
|
HygieneData::with(|data| {
|
||||||
let outer = data.outer_expn(self);
|
let (expn_id, transparency) = data.outer_mark(self);
|
||||||
(outer, data.expn_data(outer).clone())
|
(expn_id, transparency, data.expn_data(expn_id).clone())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,9 +550,15 @@ impl Span {
|
||||||
/// The returned span belongs to the created expansion and has the new properties,
|
/// The returned span belongs to the created expansion and has the new properties,
|
||||||
/// but its location is inherited from the current span.
|
/// but its location is inherited from the current span.
|
||||||
pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
|
pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
|
||||||
|
self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fresh_expansion_with_transparency(
|
||||||
|
self, expn_data: ExpnData, transparency: Transparency
|
||||||
|
) -> Span {
|
||||||
HygieneData::with(|data| {
|
HygieneData::with(|data| {
|
||||||
let expn_id = data.fresh_expn(Some(expn_data));
|
let expn_id = data.fresh_expn(Some(expn_data));
|
||||||
self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
|
self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id, transparency))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,8 +590,6 @@ pub struct ExpnData {
|
||||||
/// The span of the macro definition (possibly dummy).
|
/// The span of the macro definition (possibly dummy).
|
||||||
/// This span serves only informational purpose and is not used for resolution.
|
/// This span serves only informational purpose and is not used for resolution.
|
||||||
pub def_site: Span,
|
pub def_site: Span,
|
||||||
/// Transparency used by `apply_mark` for the expansion with this expansion data by default.
|
|
||||||
pub default_transparency: Transparency,
|
|
||||||
/// List of #[unstable]/feature-gated features that the macro is allowed to use
|
/// List of #[unstable]/feature-gated features that the macro is allowed to use
|
||||||
/// internally without forcing the whole crate to opt-in
|
/// internally without forcing the whole crate to opt-in
|
||||||
/// to them.
|
/// to them.
|
||||||
|
@ -633,7 +612,6 @@ impl ExpnData {
|
||||||
parent: ExpnId::root(),
|
parent: ExpnId::root(),
|
||||||
call_site,
|
call_site,
|
||||||
def_site: DUMMY_SP,
|
def_site: DUMMY_SP,
|
||||||
default_transparency: Transparency::SemiTransparent,
|
|
||||||
allow_internal_unstable: None,
|
allow_internal_unstable: None,
|
||||||
allow_internal_unsafe: false,
|
allow_internal_unsafe: false,
|
||||||
local_inner_macros: false,
|
local_inner_macros: false,
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub mod edition;
|
||||||
use edition::Edition;
|
use edition::Edition;
|
||||||
pub mod hygiene;
|
pub mod hygiene;
|
||||||
pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
|
pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
|
||||||
|
use hygiene::Transparency;
|
||||||
|
|
||||||
mod span_encoding;
|
mod span_encoding;
|
||||||
pub use span_encoding::{Span, DUMMY_SP};
|
pub use span_encoding::{Span, DUMMY_SP};
|
||||||
|
@ -512,10 +513,17 @@ impl Span {
|
||||||
span.ctxt)
|
span.ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Produces a span with the same location as `self` and context produced by a macro with the
|
||||||
|
/// given ID and transparency, assuming that macro was defined directly and not produced by
|
||||||
|
/// some other macro (which is the case for built-in and procedural macros).
|
||||||
|
pub fn with_ctxt_from_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
|
||||||
|
self.with_ctxt(SyntaxContext::root().apply_mark(expn_id, transparency))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn apply_mark(self, mark: ExpnId) -> Span {
|
pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
|
||||||
let span = self.data();
|
let span = self.data();
|
||||||
span.with_ctxt(span.ctxt.apply_mark(mark))
|
span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue