about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2019-05-27 13:52:11 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2019-05-29 09:32:56 +1000
commitcaea42f6c8ba8f5cc5ed04557ec5d072b107e7b4 (patch)
tree9ddcc6be16ffaabb4d5dfbd86340c043c2e08f3a
parent828f6fdbe57a7b0e6b7bf7194ee9a2079b2779cd (diff)
downloadrust-caea42f6c8ba8f5cc5ed04557ec5d072b107e7b4.tar.gz
rust-caea42f6c8ba8f5cc5ed04557ec5d072b107e7b4.zip
Introduce and use `SyntaxContext::outer_expn_info()`.
It reduces two `hygiene_data` accesses to one on some hot paths.
-rw-r--r--src/librustc/lint/internal.rs2
-rw-r--r--src/librustc/lint/mod.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs2
-rw-r--r--src/librustc_lint/builtin.rs4
-rw-r--r--src/librustc_lint/unused.rs5
-rw-r--r--src/librustc_resolve/lib.rs4
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_typeck/check/demand.rs2
-rw-r--r--src/librustc_typeck/check/method/suggest.rs4
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/source_map.rs4
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs2
-rw-r--r--src/libsyntax_pos/hygiene.rs10
-rw-r--r--src/libsyntax_pos/lib.rs20
15 files changed, 39 insertions, 30 deletions
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index e953c084599..86dae579ca7 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 c3afca35303..f4eff6121c0 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 9019c4a0575..55b5cba2b02 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_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index fed12c9a29f..8f4f0b5b23f 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 d184c671bba..44b727c6925 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 34f7e04c164..036820c6d7f 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_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f9cf95a873f..9fe201b8c5e 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());
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 9bb607a2cc2..08ab5b85325 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/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 724f8d886e8..91c8bb6a743 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -327,7 +327,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/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index dfe21edee41..a1658fd89cd 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/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d72193ffe12..4b5b9ff7bbe 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 8a210db9185..e83cad93d1c 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 53730d2d080..cc05ecf8df5 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<Self::Span> {
-        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 3ffeaf43b85..b4bb6d9c5e8 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -517,6 +517,16 @@ impl SyntaxContext {
         HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark)
     }
 
+    /// `ctxt.outer_expn_info()` is equivalent to but faster than
+    /// `ctxt.outer().expn_info()`.
+    #[inline]
+    pub fn outer_expn_info(self) -> Option<ExpnInfo> {
+        HygieneData::with(|data| {
+            let outer = data.syntax_contexts[self.0 as usize].outer_mark;
+            data.marks[outer.0 as usize].expn_info.clone()
+        })
+    }
+
     pub fn dollar_crate_name(self) -> Symbol {
         HygieneData::with(|data| data.syntax_contexts[self.0 as usize].dollar_crate_name)
     }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index cb5aaf7eb88..30e075a3396 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<Span> {
-        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<ExpnInfo> {
         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<CompilerDesugaringKind> {
-        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<MacroBacktrace> {
         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 {