From eac900ac87828d6a4813f0c4a870bcdb439d1175 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 7 Jul 2019 16:45:41 +0300 Subject: 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. --- src/libsyntax_pos/hygiene.rs | 20 +++++++++++++++++--- src/libsyntax_pos/lib.rs | 3 ++- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src/libsyntax_pos') 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, } @@ -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 => ("", "!"), -- cgit 1.4.1-3-g733a5