hygiene: Remove Option
s from functions returning ExpnInfo
The expansion info is not optional and should always exist
This commit is contained in:
parent
6cb28b6617
commit
73dee258c1
14 changed files with 98 additions and 155 deletions
|
@ -9,7 +9,6 @@ use errors::Applicability;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast::{Ident, Item, ItemKind};
|
||||
use syntax::symbol::{sym, Symbol};
|
||||
use syntax_pos::ExpnInfo;
|
||||
|
||||
declare_tool_lint! {
|
||||
pub rustc::DEFAULT_HASH_TYPES,
|
||||
|
@ -228,30 +227,20 @@ impl EarlyLintPass for LintPassImpl {
|
|||
if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
|
||||
if let Some(last) = lint_pass.path.segments.last() {
|
||||
if last.ident.name == sym::LintPass {
|
||||
match &lint_pass.path.span.ctxt().outer_expn_info() {
|
||||
Some(info) if is_lint_pass_expansion(info) => {}
|
||||
_ => {
|
||||
cx.struct_span_lint(
|
||||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
"implementing `LintPass` by hand",
|
||||
)
|
||||
.help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
|
||||
.emit();
|
||||
}
|
||||
let expn_info = lint_pass.path.span.ctxt().outer_expn_info();
|
||||
let call_site = expn_info.call_site;
|
||||
if expn_info.kind.descr() != sym::impl_lint_pass &&
|
||||
call_site.ctxt().outer_expn_info().kind.descr() != sym::declare_lint_pass {
|
||||
cx.struct_span_lint(
|
||||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
"implementing `LintPass` by hand",
|
||||
)
|
||||
.help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
|
||||
if expn_info.kind.descr() == sym::impl_lint_pass {
|
||||
true
|
||||
} else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
|
||||
info.kind.descr() == sym::declare_lint_pass
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -885,21 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||
/// This is used to test whether a lint should not even begin to figure out whether it should
|
||||
/// be reported on the current node.
|
||||
pub fn in_external_macro(sess: &Session, 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 {
|
||||
let expn_info = span.ctxt().outer_expn_info();
|
||||
match expn_info.kind {
|
||||
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
|
||||
ExpnKind::Desugaring(_) => true, // well, it's "external"
|
||||
ExpnKind::Macro(MacroKind::Bang, _) => {
|
||||
if info.def_site.is_dummy() {
|
||||
if expn_info.def_site.is_dummy() {
|
||||
// dummy span for the def_site means it's an external macro
|
||||
return true;
|
||||
}
|
||||
match sess.source_map().span_to_snippet(info.def_site) {
|
||||
match sess.source_map().span_to_snippet(expn_info.def_site) {
|
||||
Ok(code) => !code.starts_with("macro_rules"),
|
||||
// no snippet = external macro or compiler-builtin expansion
|
||||
Err(_) => true,
|
||||
|
@ -911,10 +906,8 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
|||
|
||||
/// Returns whether `span` originates in a derive macro's expansion
|
||||
pub fn in_derive_expansion(span: Span) -> bool {
|
||||
if let Some(info) = span.ctxt().outer_expn_info() {
|
||||
if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind {
|
||||
return true;
|
||||
}
|
||||
if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_info().kind {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder};
|
|||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax::symbol::sym;
|
||||
use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind};
|
||||
use syntax_pos::{DUMMY_SP, Span, ExpnKind};
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn report_fulfillment_errors(&self,
|
||||
|
@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// We want to ignore desugarings here: spans are equivalent even
|
||||
// if one is the result of a desugaring and the other is not.
|
||||
let mut span = error.obligation.cause.span;
|
||||
if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. })
|
||||
= span.ctxt().outer_expn_info() {
|
||||
span = def_site;
|
||||
let expn_info = span.ctxt().outer_expn_info();
|
||||
if let ExpnKind::Desugaring(_) = expn_info.kind {
|
||||
span = expn_info.call_site;
|
||||
}
|
||||
|
||||
error_map.entry(span).or_default().push(
|
||||
|
|
|
@ -820,18 +820,14 @@ where
|
|||
TAG_NO_EXPANSION_INFO.encode(self)
|
||||
} else {
|
||||
let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info();
|
||||
if let Some(expn_info) = expn_info {
|
||||
if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
|
||||
TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
|
||||
pos.encode(self)
|
||||
} else {
|
||||
TAG_EXPANSION_INFO_INLINE.encode(self)?;
|
||||
let pos = AbsoluteBytePos::new(self.position());
|
||||
self.expn_info_shorthands.insert(expn_id, pos);
|
||||
expn_info.encode(self)
|
||||
}
|
||||
if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
|
||||
TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
|
||||
pos.encode(self)
|
||||
} else {
|
||||
TAG_NO_EXPANSION_INFO.encode(self)
|
||||
TAG_EXPANSION_INFO_INLINE.encode(self)?;
|
||||
let pos = AbsoluteBytePos::new(self.position());
|
||||
self.expn_info_shorthands.insert(expn_id, pos);
|
||||
expn_info.encode(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1775,10 +1775,7 @@ impl SharedEmitterMain {
|
|||
}
|
||||
}
|
||||
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
|
||||
match ExpnId::from_u32(cookie).expn_info() {
|
||||
Some(ei) => sess.span_err(ei.call_site, &msg),
|
||||
None => sess.err(&msg),
|
||||
}
|
||||
sess.span_err(ExpnId::from_u32(cookie).expn_info().call_site, &msg)
|
||||
}
|
||||
Ok(SharedEmitterMessage::AbortIfErrors) => {
|
||||
sess.abort_if_errors();
|
||||
|
|
|
@ -517,9 +517,8 @@ impl EarlyLintPass for UnusedParens {
|
|||
// trigger in situations that macro authors shouldn't have to care about, e.g.,
|
||||
// when a parenthesized token tree matched in one macro expansion is matched as
|
||||
// an expression in another and used as a fn/method argument (Issue #47775)
|
||||
if e.span.ctxt().outer_expn_info()
|
||||
.map_or(false, |info| info.call_site.from_expansion()) {
|
||||
return;
|
||||
if e.span.ctxt().outer_expn_info().call_site.from_expansion() {
|
||||
return;
|
||||
}
|
||||
let msg = format!("{} argument", call_kind);
|
||||
for arg in args_to_check {
|
||||
|
|
|
@ -346,8 +346,7 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
// Possibly apply the macro helper hack
|
||||
if kind == Some(MacroKind::Bang) && path.len() == 1 &&
|
||||
path[0].ident.span.ctxt().outer_expn_info()
|
||||
.map_or(false, |info| info.local_inner_macros) {
|
||||
path[0].ident.span.ctxt().outer_expn_info().local_inner_macros {
|
||||
let root = Ident::new(kw::DollarCrate, path[0].ident.span);
|
||||
path.insert(0, Segment::from_ident(root));
|
||||
}
|
||||
|
|
|
@ -756,10 +756,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
|
||||
pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
|
||||
pub fn call_site(&self) -> Span {
|
||||
match self.current_expansion.id.expn_info() {
|
||||
Some(expn_info) => expn_info.call_site,
|
||||
None => DUMMY_SP,
|
||||
}
|
||||
self.current_expansion.id.expn_info().call_site
|
||||
}
|
||||
pub fn backtrace(&self) -> SyntaxContext {
|
||||
SyntaxContext::root().apply_mark(self.current_expansion.id)
|
||||
|
@ -772,17 +769,13 @@ impl<'a> ExtCtxt<'a> {
|
|||
let mut ctxt = self.backtrace();
|
||||
let mut last_macro = None;
|
||||
loop {
|
||||
if ctxt.outer_expn_info().map_or(None, |info| {
|
||||
if info.kind.descr() == sym::include {
|
||||
// Stop going up the backtrace once include! is encountered
|
||||
return None;
|
||||
}
|
||||
ctxt = info.call_site.ctxt();
|
||||
last_macro = Some(info.call_site);
|
||||
Some(())
|
||||
}).is_none() {
|
||||
break
|
||||
let expn_info = ctxt.outer_expn_info();
|
||||
// Stop going up the backtrace once include! is encountered
|
||||
if expn_info.is_root() || expn_info.kind.descr() == sym::include {
|
||||
break;
|
||||
}
|
||||
ctxt = expn_info.call_site.ctxt();
|
||||
last_macro = Some(expn_info.call_site);
|
||||
}
|
||||
last_macro
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
}
|
||||
|
||||
if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
|
||||
let info = self.cx.current_expansion.id.expn_info().unwrap();
|
||||
let info = self.cx.current_expansion.id.expn_info();
|
||||
let suggested_limit = self.cx.ecfg.recursion_limit * 2;
|
||||
let mut err = self.cx.struct_span_err(info.call_site,
|
||||
&format!("recursion limit reached while expanding the macro `{}`",
|
||||
|
|
|
@ -362,7 +362,7 @@ pub(crate) struct Rustc<'a> {
|
|||
impl<'a> Rustc<'a> {
|
||||
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
|
||||
// No way to determine def location for a proc macro right now, so use call location.
|
||||
let location = cx.current_expansion.id.expn_info().unwrap().call_site;
|
||||
let location = cx.current_expansion.id.expn_info().call_site;
|
||||
let to_span = |transparency| {
|
||||
location.with_ctxt(
|
||||
SyntaxContext::root()
|
||||
|
@ -677,7 +677,7 @@ impl server::Span for Rustc<'_> {
|
|||
self.sess.source_map().lookup_char_pos(span.lo()).file
|
||||
}
|
||||
fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
||||
span.ctxt().outer_expn_info().map(|i| i.call_site)
|
||||
span.parent()
|
||||
}
|
||||
fn source(&mut self, span: Self::Span) -> Self::Span {
|
||||
span.source_callsite()
|
||||
|
|
|
@ -13,7 +13,6 @@ mod generics;
|
|||
use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind};
|
||||
use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind};
|
||||
use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
|
||||
use crate::ext::hygiene::SyntaxContext;
|
||||
use crate::source_map::{self, respan};
|
||||
use crate::parse::{SeqSep, literal, token};
|
||||
use crate::parse::lexer::UnmatchedBrace;
|
||||
|
|
|
@ -31,12 +31,13 @@ mod tests;
|
|||
/// otherwise return the call site span up to the `enclosing_sp` by
|
||||
/// following the `expn_info` chain.
|
||||
pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
|
||||
let call_site1 = sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
|
||||
let call_site2 = enclosing_sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
|
||||
match (call_site1, call_site2) {
|
||||
(None, _) => sp,
|
||||
(Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
|
||||
(Some(call_site1), _) => original_sp(call_site1, enclosing_sp),
|
||||
let expn_info1 = sp.ctxt().outer_expn_info();
|
||||
let expn_info2 = enclosing_sp.ctxt().outer_expn_info();
|
||||
if expn_info1.is_root() ||
|
||||
!expn_info2.is_root() && expn_info1.call_site == expn_info2.call_site {
|
||||
sp
|
||||
} else {
|
||||
original_sp(expn_info1.call_site, enclosing_sp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,8 @@ impl ExpnId {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn expn_info(self) -> Option<ExpnInfo> {
|
||||
HygieneData::with(|data| data.expn_info(self).cloned())
|
||||
pub fn expn_info(self) -> ExpnInfo {
|
||||
HygieneData::with(|data| data.expn_info(self).clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -139,12 +139,9 @@ impl ExpnId {
|
|||
#[inline]
|
||||
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.expn_info(self) {
|
||||
if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
let expn_info = data.expn_info(self);
|
||||
if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
|
||||
return expn_info.default_transparency == Transparency::Opaque;
|
||||
}
|
||||
false
|
||||
})
|
||||
|
@ -190,16 +187,9 @@ impl HygieneData {
|
|||
self.expn_data[expn_id.0 as usize].parent
|
||||
}
|
||||
|
||||
fn expn_info(&self, expn_id: ExpnId) -> Option<&ExpnInfo> {
|
||||
if expn_id != ExpnId::root() {
|
||||
Some(self.expn_data[expn_id.0 as usize].expn_info.as_ref()
|
||||
.expect("no expansion info for an expansion ID"))
|
||||
} else {
|
||||
// FIXME: Some code relies on `expn_info().is_none()` meaning "no expansion".
|
||||
// Introduce a method for checking for "no expansion" instead and always return
|
||||
// `ExpnInfo` from this function instead of the `Option`.
|
||||
None
|
||||
}
|
||||
fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo {
|
||||
self.expn_data[expn_id.0 as usize].expn_info.as_ref()
|
||||
.expect("no expansion info for an expansion ID")
|
||||
}
|
||||
|
||||
fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool {
|
||||
|
@ -212,12 +202,6 @@ impl HygieneData {
|
|||
true
|
||||
}
|
||||
|
||||
fn default_transparency(&self, expn_id: ExpnId) -> Transparency {
|
||||
self.expn_info(expn_id).map_or(
|
||||
Transparency::SemiTransparent, |einfo| einfo.default_transparency
|
||||
)
|
||||
}
|
||||
|
||||
fn modern(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque
|
||||
}
|
||||
|
@ -256,11 +240,7 @@ impl HygieneData {
|
|||
|
||||
fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
|
||||
while span.from_expansion() && span.ctxt() != to {
|
||||
if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) {
|
||||
span = info.call_site;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
span = self.expn_info(self.outer_expn(span.ctxt())).call_site;
|
||||
}
|
||||
span
|
||||
}
|
||||
|
@ -275,7 +255,9 @@ impl HygieneData {
|
|||
|
||||
fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
|
||||
assert_ne!(expn_id, ExpnId::root());
|
||||
self.apply_mark_with_transparency(ctxt, expn_id, self.default_transparency(expn_id))
|
||||
self.apply_mark_with_transparency(
|
||||
ctxt, expn_id, self.expn_info(expn_id).default_transparency
|
||||
)
|
||||
}
|
||||
|
||||
fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
|
||||
|
@ -285,8 +267,7 @@ impl HygieneData {
|
|||
return self.apply_mark_internal(ctxt, expn_id, transparency);
|
||||
}
|
||||
|
||||
let call_site_ctxt =
|
||||
self.expn_info(expn_id).map_or(SyntaxContext::root(), |info| info.call_site.ctxt());
|
||||
let call_site_ctxt = self.expn_info(expn_id).call_site.ctxt();
|
||||
let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
|
||||
self.modern(call_site_ctxt)
|
||||
} else {
|
||||
|
@ -581,17 +562,17 @@ impl SyntaxContext {
|
|||
/// `ctxt.outer_expn_info()` is equivalent to but faster than
|
||||
/// `ctxt.outer_expn().expn_info()`.
|
||||
#[inline]
|
||||
pub fn outer_expn_info(self) -> Option<ExpnInfo> {
|
||||
HygieneData::with(|data| data.expn_info(data.outer_expn(self)).cloned())
|
||||
pub fn outer_expn_info(self) -> ExpnInfo {
|
||||
HygieneData::with(|data| data.expn_info(data.outer_expn(self)).clone())
|
||||
}
|
||||
|
||||
/// `ctxt.outer_expn_with_info()` is equivalent to but faster than
|
||||
/// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`.
|
||||
#[inline]
|
||||
pub fn outer_expn_with_info(self) -> (ExpnId, Option<ExpnInfo>) {
|
||||
pub fn outer_expn_with_info(self) -> (ExpnId, ExpnInfo) {
|
||||
HygieneData::with(|data| {
|
||||
let outer = data.outer_expn(self);
|
||||
(outer, data.expn_info(outer).cloned())
|
||||
(outer, data.expn_info(outer).clone())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -681,6 +662,11 @@ impl ExpnInfo {
|
|||
..ExpnInfo::default(kind, call_site, edition)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_root(&self) -> bool {
|
||||
if let ExpnKind::Root = self.kind { true } else { false }
|
||||
}
|
||||
}
|
||||
|
||||
/// Expansion kind.
|
||||
|
|
|
@ -355,20 +355,20 @@ impl Span {
|
|||
/// Returns the source span -- this is either the supplied span, or the span for
|
||||
/// the macro callsite that expanded to it.
|
||||
pub fn source_callsite(self) -> Span {
|
||||
self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
|
||||
let expn_info = self.ctxt().outer_expn_info();
|
||||
if !expn_info.is_root() { expn_info.call_site.source_callsite() } else { self }
|
||||
}
|
||||
|
||||
/// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
|
||||
/// if any.
|
||||
pub fn parent(self) -> Option<Span> {
|
||||
self.ctxt().outer_expn_info().map(|i| i.call_site)
|
||||
let expn_info = self.ctxt().outer_expn_info();
|
||||
if !expn_info.is_root() { Some(expn_info.call_site) } else { None }
|
||||
}
|
||||
|
||||
/// Edition of the crate from which this span came.
|
||||
pub fn edition(self) -> edition::Edition {
|
||||
self.ctxt().outer_expn_info().map_or_else(|| {
|
||||
Edition::from_session()
|
||||
}, |einfo| einfo.edition)
|
||||
self.ctxt().outer_expn_info().edition
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -387,49 +387,39 @@ impl Span {
|
|||
/// else returns the `ExpnInfo` for the macro definition
|
||||
/// corresponding to the source callsite.
|
||||
pub fn source_callee(self) -> Option<ExpnInfo> {
|
||||
fn source_callee(info: ExpnInfo) -> ExpnInfo {
|
||||
match info.call_site.ctxt().outer_expn_info() {
|
||||
Some(info) => source_callee(info),
|
||||
None => info,
|
||||
}
|
||||
fn source_callee(expn_info: ExpnInfo) -> ExpnInfo {
|
||||
let next_expn_info = expn_info.call_site.ctxt().outer_expn_info();
|
||||
if !next_expn_info.is_root() { source_callee(next_expn_info) } else { expn_info }
|
||||
}
|
||||
self.ctxt().outer_expn_info().map(source_callee)
|
||||
let expn_info = self.ctxt().outer_expn_info();
|
||||
if !expn_info.is_root() { Some(source_callee(expn_info)) } else { None }
|
||||
}
|
||||
|
||||
/// Checks if a span is "internal" to a macro in which `#[unstable]`
|
||||
/// items can be used (that is, a macro marked with
|
||||
/// `#[allow_internal_unstable]`).
|
||||
pub fn allows_unstable(&self, feature: Symbol) -> bool {
|
||||
match self.ctxt().outer_expn_info() {
|
||||
Some(info) => info
|
||||
.allow_internal_unstable
|
||||
.map_or(false, |features| features.iter().any(|&f|
|
||||
f == feature || f == sym::allow_internal_unstable_backcompat_hack
|
||||
)),
|
||||
None => false,
|
||||
}
|
||||
self.ctxt().outer_expn_info().allow_internal_unstable.map_or(false, |features| {
|
||||
features.iter().any(|&f| {
|
||||
f == feature || f == sym::allow_internal_unstable_backcompat_hack
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks if this span arises from a compiler desugaring of kind `kind`.
|
||||
pub fn is_desugaring(&self, kind: DesugaringKind) -> bool {
|
||||
match self.ctxt().outer_expn_info() {
|
||||
Some(info) => match info.kind {
|
||||
ExpnKind::Desugaring(k) => k == kind,
|
||||
_ => false,
|
||||
},
|
||||
None => false,
|
||||
match self.ctxt().outer_expn_info().kind {
|
||||
ExpnKind::Desugaring(k) => k == kind,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the compiler desugaring that created this span, or `None`
|
||||
/// if this span is not from a desugaring.
|
||||
pub fn desugaring_kind(&self) -> Option<DesugaringKind> {
|
||||
match self.ctxt().outer_expn_info() {
|
||||
Some(info) => match info.kind {
|
||||
ExpnKind::Desugaring(k) => Some(k),
|
||||
_ => None
|
||||
},
|
||||
None => None
|
||||
match self.ctxt().outer_expn_info().kind {
|
||||
ExpnKind::Desugaring(k) => Some(k),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,16 +427,17 @@ impl Span {
|
|||
/// can be used without triggering the `unsafe_code` lint
|
||||
// (that is, a macro marked with `#[allow_internal_unsafe]`).
|
||||
pub fn allows_unsafe(&self) -> bool {
|
||||
match self.ctxt().outer_expn_info() {
|
||||
Some(info) => info.allow_internal_unsafe,
|
||||
None => false,
|
||||
}
|
||||
self.ctxt().outer_expn_info().allow_internal_unsafe
|
||||
}
|
||||
|
||||
pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
|
||||
let mut prev_span = DUMMY_SP;
|
||||
let mut result = vec![];
|
||||
while let Some(info) = self.ctxt().outer_expn_info() {
|
||||
loop {
|
||||
let info = self.ctxt().outer_expn_info();
|
||||
if info.is_root() {
|
||||
break;
|
||||
}
|
||||
// Don't print recursive invocations.
|
||||
if !info.call_site.source_equal(&prev_span) {
|
||||
let (pre, post) = match info.kind {
|
||||
|
|
Loading…
Add table
Reference in a new issue