From d908e97da34ecc419024ddcf5004033920ebb9a9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 21 Jan 2014 23:09:53 -0800 Subject: [PATCH] Redo exported macro serialization The old method of serializing the AST gives totally bogus spans if the expansion of an imported macro causes compilation errors. The best solution seems to be to serialize the actual textual macro definition and load it the same way the std-macros are. I'm not totally confident that getting the source from the CodeMap will always do the right thing, but it seems to work in simple cases. --- src/librustc/metadata/creader.rs | 2 +- src/librustc/metadata/csearch.rs | 2 +- src/librustc/metadata/decoder.rs | 5 ++--- src/librustc/metadata/encoder.rs | 9 ++++++++- src/librustc/middle/trans/base.rs | 1 + src/librustpkg/util.rs | 2 +- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 20 +++++++++++++++----- src/libsyntax/ext/quote.rs | 1 - src/libsyntax/parse/mod.rs | 2 +- 10 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 1d99283311206..fa2e94b6f8f20 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -420,7 +420,7 @@ impl CrateLoader for Loader { } } - fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[@ast::Item] { + fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[~str] { csearch::get_exported_macros(self.env.sess.cstore, cnum) } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 9955186da462f..3985527232c65 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -310,7 +310,7 @@ pub fn get_macro_registrar_fn(cstore: @cstore::CStore, pub fn get_exported_macros(cstore: @cstore::CStore, crate_num: ast::CrateNum) - -> ~[@ast::Item] { + -> ~[~str] { let cdata = cstore.get_crate_data(crate_num); decoder::get_exported_macros(cdata) } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index abf5b051c7de7..a7e5082bcbbf6 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -23,7 +23,6 @@ use metadata::tydecode::{parse_ty_data, parse_def_id, use middle::ty::{ImplContainer, TraitContainer}; use middle::ty; use middle::typeck; -use middle::astencode; use middle::astencode::vtable_decoder_helpers; use std::at_vec; @@ -1282,12 +1281,12 @@ pub fn get_macro_registrar_fn(cdata: Cmd) -> Option { .map(|doc| item_def_id(doc, cdata)) } -pub fn get_exported_macros(cdata: Cmd) -> ~[@ast::Item] { +pub fn get_exported_macros(cdata: Cmd) -> ~[~str] { let macros = reader::get_doc(reader::Doc(cdata.data()), tag_exported_macros); let mut result = ~[]; reader::tagged_docs(macros, tag_macro_def, |macro_doc| { - result.push(astencode::decode_exported_macro(macro_doc)); + result.push(macro_doc.as_str()); true }); result diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index a7c82ba431778..114b74b02de06 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -37,6 +37,7 @@ use syntax::ast_map; use syntax::ast_util::*; use syntax::attr; use syntax::attr::AttrMetaMethods; +use syntax::codemap; use syntax::diagnostic::SpanHandler; use syntax::parse::token::special_idents; use syntax::ast_util; @@ -71,6 +72,7 @@ pub struct EncodeParams<'a> { cstore: @cstore::CStore, encode_inlined_item: encode_inlined_item<'a>, reachable: @RefCell>, + codemap: @codemap::CodeMap, } struct Stats { @@ -101,6 +103,7 @@ pub struct EncodeContext<'a> { encode_inlined_item: encode_inlined_item<'a>, type_abbrevs: abbrev_map, reachable: @RefCell>, + codemap: @codemap::CodeMap, } pub fn reachable(ecx: &EncodeContext, id: NodeId) -> bool { @@ -1714,8 +1717,10 @@ impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> { fn visit_item(&mut self, item: &Item, _: ()) { match item.node { ItemMac(..) => { + let def = self.ecx.codemap.span_to_snippet(item.span) + .expect("Unable to find source for macro"); self.ebml_w.start_tag(tag_macro_def); - astencode::encode_exported_macro(self.ebml_w, item); + self.ebml_w.wr_str(def); self.ebml_w.end_tag(); } _ => {} @@ -1881,6 +1886,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate) link_meta, reachable, non_inlineable_statics, + codemap, .. } = parms; let type_abbrevs = @RefCell::new(HashMap::new()); @@ -1897,6 +1903,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate) encode_inlined_item: encode_inlined_item, type_abbrevs: type_abbrevs, reachable: reachable, + codemap: codemap, }; let mut ebml_w = writer::Encoder(wr); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index c654bbbd709d9..5b246daa6c5b5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2678,6 +2678,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_ cstore: cx.sess.cstore, encode_inlined_item: ie, reachable: cx.reachable, + codemap: cx.sess.codemap, } } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 4d8f5c668b74f..628c0b937af8d 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -626,7 +626,7 @@ impl<'a> base::CrateLoader for CrateLoader<'a> { self.loader.load_crate(crate) } - fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[@ast::Item] { + fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[~str] { self.loader.get_exported_macros(cnum) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8698220130350..fbaa086c7d30d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -299,7 +299,7 @@ pub struct MacroCrate { pub trait CrateLoader { fn load_crate(&mut self, crate: &ast::ViewItem) -> MacroCrate; - fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> ~[@ast::Item]; + fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> ~[~str]; fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f547f32e21dbc..0534aa39848b8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -406,9 +406,20 @@ pub fn expand_view_item(vi: &ast::ViewItem, fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) { let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(crate); + let crate_name = match crate.node { + ast::ViewItemExternMod(ref name, _, _) => token::ident_to_str(name), + _ => unreachable!(), + }; + let name = format!("<{} macros>", crate_name).to_managed(); + let exported_macros = fld.cx.loader.get_exported_macros(cnum); - for &it in exported_macros.iter() { - expand_item_mac(it, fld); + for source in exported_macros.iter() { + let item = parse::parse_item_from_source_str(name, + source.to_managed(), + fld.cx.cfg(), + fld.cx.parse_sess()) + .expect("expected a serialized item"); + expand_item_mac(item, fld); } let path = match lib { @@ -944,7 +955,6 @@ pub fn inject_std_macros(parse_sess: @parse::ParseSess, let sm = match parse_item_from_source_str(@"", std_macros(), cfg.clone(), - ~[], parse_sess) { Some(item) => item, None => fail!("expected core macros to parse correctly") @@ -1212,7 +1222,7 @@ mod test { fail!("lolwut") } - fn get_exported_macros(&mut self, _: ast::CrateNum) -> ~[@ast::Item] { + fn get_exported_macros(&mut self, _: ast::CrateNum) -> ~[~str] { fail!("lolwut") } @@ -1289,7 +1299,7 @@ mod test { let item_ast = parse::parse_item_from_source_str( @"", src, - cfg,~[],sess); + cfg,sess); match item_ast { Some(_) => (), // success None => fail!("expected this to parse") diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index f840bde6dc142..6faed270875c4 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -250,7 +250,6 @@ pub mod rt { @"", s, self.cfg(), - ~[], self.parse_sess()); match res { Some(ast) => ast, diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 9713f331147c0..e026a11cafe37 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -130,10 +130,10 @@ pub fn parse_item_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - attrs: ~[ast::Attribute], sess: @ParseSess ) -> Option<@ast::Item> { let mut p = new_parser_from_source_str(sess, cfg, name, source); + let attrs = p.parse_outer_attributes(); maybe_aborted(p.parse_item(attrs),p) }