diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index e953c08459963..86dae579ca753 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -113,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind { .help("try using `Ty` instead") .emit(); } else { - if ty.span.ctxt().outer().expn_info().is_some() { + if ty.span.ctxt().outer_expn_info().is_some() { return; } if let Some(t) = is_ty_or_ty_ctxt(cx, ty) { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index c3afca35303c9..f4eff6121c043 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -880,7 +880,7 @@ 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() { + 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, @@ -908,7 +908,7 @@ 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 { - let info = match span.ctxt().outer().expn_info() { + 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, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5a2bf07b065f8..a29b173880a08 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -65,7 +65,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { format: ExpnFormat::CompilerDesugaring(_), def_site: Some(def_span), .. - }) = span.ctxt().outer().expn_info() { + }) = span.ctxt().outer_expn_info() { span = def_span; } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fa993325e2712..0cbc0112a8e10 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2886,7 +2886,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { variant.fields.iter().position(|field| { - self.adjust_ident(ident, variant.def_id, hir::DUMMY_HIR_ID).0 == field.ident.modern() + self.hygienic_eq(ident, field.ident, variant.def_id) }) } @@ -3085,19 +3085,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed /// definition's parent/scope to perform comparison. pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool { - self.adjust_ident(use_name, def_parent_def_id, hir::DUMMY_HIR_ID).0 == def_name.modern() + // We could use `Ident::eq` here, but we deliberately don't. The name + // comparison fails frequently, and we want to avoid the expensive + // `modern()` calls required for the span comparison whenever possible. + use_name.name == def_name.name && + self.adjust_ident(use_name, def_parent_def_id).span.ctxt() == def_name.modern().span.ctxt() } - pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: hir::HirId) -> (Ident, DefId) { - ident = ident.modern(); - let target_expansion = match scope.krate { + fn expansion_that_defined(self, scope: DefId) -> Mark { + match scope.krate { LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index), _ => Mark::root(), - }; - let scope = match ident.span.adjust(target_expansion) { + } + } + + pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident { + ident = ident.modern(); + ident.span.adjust(self.expansion_that_defined(scope)); + ident + } + + pub fn adjust_ident_and_get_scope(self, mut ident: Ident, scope: DefId, block: hir::HirId) + -> (Ident, DefId) { + ident = ident.modern(); + let scope = match ident.span.adjust(self.expansion_that_defined(scope)) { Some(actual_expansion) => self.hir().definitions().parent_module_of_macro_def(actual_expansion), - None if block == hir::DUMMY_HIR_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId None => self.hir().get_module_parent_by_hir_id(block), }; (ident, scope) diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 4a43201dedf37..5d6f7036c3e29 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // at the level above that. let mut span = source_info.span; while span.ctxt() != NO_EXPANSION && span.ctxt() != self.mir.span.ctxt() { - if let Some(info) = span.ctxt().outer().expn_info() { + if let Some(info) = span.ctxt().outer_expn_info() { span = info.call_site; } else { break; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d184c671bbaf8..44b727c6925d9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -158,7 +158,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { if fieldpat.node.is_shorthand { continue; } - if fieldpat.span.ctxt().outer().expn_info().is_some() { + if fieldpat.span.ctxt().outer_expn_info().is_some() { // Don't lint if this is a macro expansion: macro authors // shouldn't have to worry about this kind of style issue // (Issue #49588) @@ -1003,7 +1003,7 @@ impl UnreachablePub { let mut applicability = Applicability::MachineApplicable; match vis.node { hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => { - if span.ctxt().outer().expn_info().is_some() { + if span.ctxt().outer_expn_info().is_some() { applicability = Applicability::MaybeIncorrect; } let def_span = cx.tcx.sess.source_map().def_span(span); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 34f7e04c16420..036820c6d7fa1 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -391,9 +391,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.ctxt().outer() - .expn_info().is_some()) { + if e.span.ctxt().outer_expn_info() + .map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) { return; } let msg = format!("{} argument", call_kind); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a08c028390bf7..20e18d60f076b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -845,7 +845,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> { field: &'tcx ty::FieldDef) { // definition of the field let ident = Ident::new(kw::Invalid, use_ctxt); let current_hir = self.current_item; - let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1; + let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1; if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private", field.ident, def.variant_descr(), self.tcx.def_path_str(def.did)) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 9b7b44025c13f..59e5fc149fc6e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -762,7 +762,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { ItemKind::Use(..) => { // don't suggest placing a use before the prelude // import or other generated ones - if item.span.ctxt().outer().expn_info().is_none() { + if item.span.ctxt().outer_expn_info().is_none() { self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; @@ -772,7 +772,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { ItemKind::ExternCrate(_) => {} // but place them before the first other item _ => if self.span.map_or(true, |span| item.span < span ) { - if item.span.ctxt().outer().expn_info().is_none() { + if item.span.ctxt().outer_expn_info().is_none() { // don't insert between attributes and an item if item.attrs.is_empty() { self.span = Some(item.span.shrink_to_lo()); @@ -2308,7 +2308,7 @@ impl<'a> Resolver<'a> { fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span) -> Option> { - if !module.expansion.is_descendant_of(span.ctxt().outer()) { + if !module.expansion.outer_is_descendant_of(span.ctxt()) { return Some(self.macro_def_scope(span.remove_mark())); } @@ -2344,7 +2344,7 @@ impl<'a> Resolver<'a> { module.expansion.is_descendant_of(parent.expansion) { // The macro is a proc macro derive if module.expansion.looks_like_proc_macro_derive() { - if parent.expansion.is_descendant_of(span.ctxt().outer()) { + if parent.expansion.outer_is_descendant_of(span.ctxt()) { *poisoned = Some(node_id); return module.parent; } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 9bb607a2cc28f..08ab5b8532522 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -413,7 +413,7 @@ impl<'a> Resolver<'a> { // Possibly apply the macro helper hack if kind == MacroKind::Bang && path.len() == 1 && - path[0].ident.span.ctxt().outer().expn_info() + path[0].ident.span.ctxt().outer_expn_info() .map_or(false, |info| info.local_inner_macros) { let root = Ident::new(kw::DollarCrate, path[0].ident.span); path.insert(0, Segment::from_ident(root)); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5b1a2e29c7642..cd53bdc6ed0a0 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -903,7 +903,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }?; let (assoc_ident, def_scope) = - tcx.adjust_ident(binding.item_name, candidate.def_id(), hir_ref_id); + tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id); let assoc_ty = tcx.associated_items(candidate.def_id()).find(|i| { i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident }).expect("missing associated type"); @@ -1433,7 +1433,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }; let trait_did = bound.def_id(); - let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, hir_ref_id); + let (assoc_ident, def_scope) = + tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id); let item = tcx.associated_items(trait_did).find(|i| { Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 5a84e0cb85a6e..5cd95a9d834c4 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -1184,7 +1184,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); let mut inexistent_fields = vec![]; // Typecheck each field. for &Spanned { node: ref field, span } in fields { - let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0; + let ident = tcx.adjust_ident(field.ident, variant.def_id); let field_ty = match used_fields.entry(ident) { Occupied(occupied) => { struct_span_err!(tcx.sess, span, E0025, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c3ea9ff40a843..87fc90f53abca 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check the `expn_info()` to see if this is a macro; if so, it's hard to // extract the text and make a good suggestion, so don't bother. - let is_macro = sp.ctxt().outer().expn_info().is_some(); + let is_macro = sp.ctxt().outer_expn_info().is_some(); match (&expr.node, &expected.sty, &checked_ty.sty) { (_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index d78e013708277..898c15fc77ff7 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -510,7 +510,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { { let is_accessible = if let Some(name) = self.method_name { let item = candidate.item; - let def_scope = self.tcx.adjust_ident(name, item.container.id(), self.body_id).1; + let def_scope = + self.tcx.adjust_ident_and_get_scope(name, item.container.id(), self.body_id).1; item.vis.is_accessible_from(def_scope, self.tcx) } else { true diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index d2fcb987bc2d8..9ef6112a94591 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -892,7 +892,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, ' hir::ItemKind::Use(..) => { // Don't suggest placing a `use` before the prelude // import or other generated ones. - if item.span.ctxt().outer().expn_info().is_none() { + if item.span.ctxt().outer_expn_info().is_none() { self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; @@ -902,7 +902,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, ' hir::ItemKind::ExternCrate(_) => {} // ...but do place them before the first other item. _ => if self.span.map_or(true, |span| item.span < span ) { - if item.span.ctxt().outer().expn_info().is_none() { + if item.span.ctxt().outer_expn_info().is_none() { // Don't insert between attributes and an item. if item.attrs.is_empty() { self.span = Some(item.span.shrink_to_lo()); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c5b85d52566d3..7a6d02cc33b21 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3339,7 +3339,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(base_def, substs) if !base_def.is_enum() => { debug!("struct named {:?}", base_t); let (ident, def_scope) = - self.tcx.adjust_ident(field, base_def.did, self.body_id); + self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id); let fields = &base_def.non_enum_variant().fields; if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) { let field = &fields[index]; @@ -3510,7 +3510,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec { variant.fields.iter().filter(|field| { - let def_scope = self.tcx.adjust_ident(field.ident, variant.def_id, self.body_id).1; + let def_scope = + self.tcx.adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id).1; field.vis.is_accessible_from(def_scope, self.tcx) }) .map(|field| field.ident.name) @@ -3628,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Type-check each field. for field in ast_fields { - let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0; + let ident = tcx.adjust_ident(field.ident, variant.def_id); let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) { seen_fields.insert(ident, field.span); self.write_field_index(field.hir_id, i); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d72193ffe1205..4b5b9ff7bbeee 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -872,7 +872,7 @@ 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 ctxt.outer_expn_info().map_or(None, |info| { if info.format.name() == sym::include { // Stop going up the backtrace once include! is encountered return None; diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index e2171a84e2300..4b6893b242337 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -30,8 +30,8 @@ use errors::SourceMapper; /// 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); + 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, diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index 53730d2d08022..cc05ecf8df5a6 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -680,7 +680,7 @@ impl server::Span for Rustc<'_> { self.sess.source_map().lookup_char_pos(span.lo()).file } fn parent(&mut self, span: Self::Span) -> Option { - span.ctxt().outer().expn_info().map(|i| i.call_site) + span.ctxt().outer_expn_info().map(|i| i.call_site) } fn source(&mut self, span: Self::Span) -> Self::Span { span.source_callsite() diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index e8dcd8171c91f..445d4271d8905 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -112,16 +112,14 @@ impl Mark { HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency) } - pub fn is_descendant_of(mut self, ancestor: Mark) -> bool { - HygieneData::with(|data| { - while self != ancestor { - if self == Mark::root() { - return false; - } - self = data.marks[self.0 as usize].parent; - } - true - }) + pub fn is_descendant_of(self, ancestor: Mark) -> bool { + HygieneData::with(|data| data.is_descendant_of(self, ancestor)) + } + + /// `mark.outer_is_descendant_of(ctxt)` is equivalent to but faster than + /// `mark.is_descendant_of(ctxt.outer())`. + pub fn outer_is_descendant_of(self, ctxt: SyntaxContext) -> bool { + HygieneData::with(|data| data.is_descendant_of(self, data.outer(ctxt))) } /// Computes a mark such that both input marks are descendants of (or equal to) the returned @@ -201,6 +199,24 @@ impl HygieneData { fn with T>(f: F) -> T { GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } + + fn outer(&self, ctxt: SyntaxContext) -> Mark { + self.syntax_contexts[ctxt.0 as usize].outer_mark + } + + fn expn_info(&self, mark: Mark) -> Option { + self.marks[mark.0 as usize].expn_info.clone() + } + + fn is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool { + while mark != ancestor { + if mark == Mark::root() { + return false; + } + mark = self.marks[mark.0 as usize].parent; + } + true + } } pub fn clear_markings() { @@ -416,7 +432,7 @@ impl SyntaxContext { /// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope). pub fn adjust(&mut self, expansion: Mark) -> Option { let mut scope = None; - while !expansion.is_descendant_of(self.outer()) { + while !expansion.outer_is_descendant_of(*self) { scope = Some(self.remove_mark()); } scope @@ -450,7 +466,7 @@ impl SyntaxContext { pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext) -> Option> { let mut scope = None; - while !expansion.is_descendant_of(glob_ctxt.outer()) { + while !expansion.outer_is_descendant_of(glob_ctxt) { scope = Some(glob_ctxt.remove_mark()); if self.remove_mark() != scope.unwrap() { return None; @@ -476,7 +492,7 @@ impl SyntaxContext { } let mut marks = Vec::new(); - while !expansion.is_descendant_of(glob_ctxt.outer()) { + while !expansion.outer_is_descendant_of(glob_ctxt) { marks.push(glob_ctxt.remove_mark()); } @@ -499,7 +515,14 @@ impl SyntaxContext { #[inline] pub fn outer(self) -> Mark { - HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark) + HygieneData::with(|data| data.outer(self)) + } + + /// `ctxt.outer_expn_info()` is equivalent to but faster than + /// `ctxt.outer().expn_info()`. + #[inline] + pub fn outer_expn_info(self) -> Option { + HygieneData::with(|data| data.expn_info(data.outer(self))) } pub fn dollar_crate_name(self) -> Symbol { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index cb5aaf7eb882f..30e075a339613 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -348,18 +348,18 @@ 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) + self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self) } /// The `Span` for the tokens in the previous macro expansion from which `self` was generated, /// if any. pub fn parent(self) -> Option { - self.ctxt().outer().expn_info().map(|i| i.call_site) + self.ctxt().outer_expn_info().map(|i| i.call_site) } /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { - self.ctxt().outer().expn_info().map_or_else(|| { + self.ctxt().outer_expn_info().map_or_else(|| { Edition::from_session() }, |einfo| einfo.edition) } @@ -381,19 +381,19 @@ impl Span { /// corresponding to the source callsite. pub fn source_callee(self) -> Option { fn source_callee(info: ExpnInfo) -> ExpnInfo { - match info.call_site.ctxt().outer().expn_info() { + match info.call_site.ctxt().outer_expn_info() { Some(info) => source_callee(info), None => info, } } - self.ctxt().outer().expn_info().map(source_callee) + self.ctxt().outer_expn_info().map(source_callee) } /// 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() { + match self.ctxt().outer_expn_info() { Some(info) => info .allow_internal_unstable .map_or(false, |features| features.iter().any(|&f| @@ -405,7 +405,7 @@ impl Span { /// Checks if this span arises from a compiler desugaring of kind `kind`. pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool { - match self.ctxt().outer().expn_info() { + match self.ctxt().outer_expn_info() { Some(info) => match info.format { ExpnFormat::CompilerDesugaring(k) => k == kind, _ => false, @@ -417,7 +417,7 @@ impl Span { /// Returns the compiler desugaring that created this span, or `None` /// if this span is not from a desugaring. pub fn compiler_desugaring_kind(&self) -> Option { - match self.ctxt().outer().expn_info() { + match self.ctxt().outer_expn_info() { Some(info) => match info.format { ExpnFormat::CompilerDesugaring(k) => Some(k), _ => None @@ -430,7 +430,7 @@ 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() { + match self.ctxt().outer_expn_info() { Some(info) => info.allow_internal_unsafe, None => false, } @@ -439,7 +439,7 @@ impl Span { pub fn macro_backtrace(mut self) -> Vec { let mut prev_span = DUMMY_SP; let mut result = vec![]; - while let Some(info) = self.ctxt().outer().expn_info() { + while let Some(info) = self.ctxt().outer_expn_info() { // Don't print recursive invocations. if !info.call_site.source_equal(&prev_span) { let (pre, post) = match info.format {