about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-07 16:45:41 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-11 00:12:57 +0300
commiteac900ac87828d6a4813f0c4a870bcdb439d1175 (patch)
tree88ad61d3fb4de4cd47a36470c2ad9b80df19e867 /src
parentdcd30a4b175364ca1ee1efdcae701a23c5ff7d0b (diff)
downloadrust-eac900ac87828d6a4813f0c4a870bcdb439d1175.tar.gz
rust-eac900ac87828d6a4813f0c4a870bcdb439d1175.zip
hygiene: Make sure each `Mark` has an associated expansion info
The root expansion was missing one.
Expansions created for "derive containers" (see one of the next commits for the description) also didn't get expansion info.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_syntax.rs1
-rw-r--r--src/librustc/lint/mod.rs2
-rw-r--r--src/libsyntax/ext/expand.rs14
-rw-r--r--src/libsyntax_pos/hygiene.rs20
-rw-r--r--src/libsyntax_pos/lib.rs3
5 files changed, 33 insertions, 7 deletions
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 69e8c355019..e0e7988a744 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -408,6 +408,7 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
 });
 
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind {
+    Root,
     Macro(kind, descr),
     Desugaring(kind)
 });
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 3c8b0041a98..e76c2493200 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -885,7 +885,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     };
 
     match info.kind {
-        ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
+        ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
         ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
             if info.def_site.is_dummy() {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 39a8a7af2a3..9a6252779e0 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -5,7 +5,7 @@ use crate::source_map::{dummy_spanned, respan};
 use crate::config::StripUnconfigured;
 use crate::ext::base::*;
 use crate::ext::derive::{add_derived_markers, collect_derives};
-use crate::ext::hygiene::{Mark, SyntaxContext};
+use crate::ext::hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind};
 use crate::ext::placeholders::{placeholder, PlaceholderExpander};
 use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
 use crate::mut_visit::*;
@@ -847,7 +847,17 @@ struct InvocationCollector<'a, 'b> {
 
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
-        let mark = Mark::fresh(self.cx.current_expansion.mark, None);
+        // Expansion info for all the collected invocations is set upon their resolution,
+        // with exception of the "derive container" case which is not resolved and can get
+        // its expansion info immediately.
+        let expn_info = match &kind {
+            InvocationKind::Attr { attr: None, item, .. } => Some(ExpnInfo::default(
+                ExpnKind::Macro(MacroKind::Attr, sym::derive),
+                item.span(), self.cx.parse_sess.edition,
+            )),
+            _ => None,
+        };
+        let mark = Mark::fresh(self.cx.current_expansion.mark, expn_info);
         self.invocations.push(Invocation {
             kind,
             fragment_kind,
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index b72da042d04..5df14439230 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -59,6 +59,9 @@ pub struct Mark(u32);
 #[derive(Debug)]
 struct MarkData {
     parent: Mark,
+    /// Each mark should have an associated expansion info, but sometimes there's a delay between
+    /// creation of a mark and obtaining its info (e.g. macros are collected first and then
+    /// resolved later), so we use an `Option` here.
     expn_info: Option<ExpnInfo>,
 }
 
@@ -155,11 +158,11 @@ crate struct HygieneData {
 }
 
 impl HygieneData {
-    crate fn new() -> Self {
+    crate fn new(edition: Edition) -> Self {
         HygieneData {
             marks: vec![MarkData {
                 parent: Mark::root(),
-                expn_info: None,
+                expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)),
             }],
             syntax_contexts: vec![SyntaxContextData {
                 outer_mark: Mark::root(),
@@ -183,7 +186,15 @@ impl HygieneData {
     }
 
     fn expn_info(&self, mark: Mark) -> Option<&ExpnInfo> {
-        self.marks[mark.0 as usize].expn_info.as_ref()
+        if mark != Mark::root() {
+            Some(self.marks[mark.0 as usize].expn_info.as_ref()
+                     .expect("no expansion info for a mark"))
+        } 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 is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool {
@@ -670,6 +681,8 @@ impl ExpnInfo {
 /// Expansion kind.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum ExpnKind {
+    /// No expansion, aka root expansion. Only `Mark::root()` has this kind.
+    Root,
     /// Expansion produced by a macro.
     /// FIXME: Some code injected by the compiler before HIR lowering also gets this kind.
     Macro(MacroKind, Symbol),
@@ -680,6 +693,7 @@ pub enum ExpnKind {
 impl ExpnKind {
     pub fn descr(&self) -> Symbol {
         match *self {
+            ExpnKind::Root => kw::PathRoot,
             ExpnKind::Macro(_, descr) => descr,
             ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()),
         }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 9258b71518f..5ccfe5f0b8b 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -60,7 +60,7 @@ impl Globals {
         Globals {
             symbol_interner: Lock::new(symbol::Interner::fresh()),
             span_interner: Lock::new(span_encoding::SpanInterner::default()),
-            hygiene_data: Lock::new(hygiene::HygieneData::new()),
+            hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
             edition,
         }
     }
@@ -442,6 +442,7 @@ impl Span {
             // Don't print recursive invocations.
             if !info.call_site.source_equal(&prev_span) {
                 let (pre, post) = match info.kind {
+                    ExpnKind::Root => break,
                     ExpnKind::Desugaring(..) => ("desugaring of ", ""),
                     ExpnKind::Macro(macro_kind, _) => match macro_kind {
                         MacroKind::Bang => ("", "!"),