diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index c875848c..69d70bc3 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -8,6 +8,7 @@ use syntax::ptr::P; use syntax::tokenstream::TokenTree; use bound; +use span; use internals::ast::{Body, Field, Item, Style, Variant}; use internals::{attr, Error}; @@ -44,7 +45,7 @@ pub fn expand_derive_deserialize( let builder = aster::AstBuilder::new().span(span); let impl_item = deserialize_item(cx, &builder, &item); - push(Annotatable::Item(impl_item)) + push(span::record_expansion(cx, impl_item, "Deserialize")) } fn deserialize_item( diff --git a/serde_codegen/src/lib.rs.in b/serde_codegen/src/lib.rs.in index 49726851..08dd5d3c 100644 --- a/serde_codegen/src/lib.rs.in +++ b/serde_codegen/src/lib.rs.in @@ -1,3 +1,4 @@ mod bound; mod de; mod ser; +mod span; diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index 0369ee21..3f549c0f 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -6,6 +6,7 @@ use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ptr::P; use bound; +use span; use internals::ast::{Body, Field, Item, Style, Variant}; use internals::{attr, Error}; @@ -38,7 +39,7 @@ pub fn expand_derive_serialize( let builder = aster::AstBuilder::new().span(span); let impl_item = serialize_item(cx, &builder, &item); - push(Annotatable::Item(impl_item)) + push(span::record_expansion(cx, impl_item, "Serialize")) } fn serialize_item( diff --git a/serde_codegen/src/span.rs b/serde_codegen/src/span.rs new file mode 100644 index 00000000..5421868d --- /dev/null +++ b/serde_codegen/src/span.rs @@ -0,0 +1,43 @@ +use syntax::ast; +use syntax::codemap::{self, ExpnId, Span}; +use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::fold::{self, Folder}; +use syntax::parse::token::intern; +use syntax::ptr::P; + +pub fn record_expansion( + cx: &ExtCtxt, + item: P, + derive: &str, +) -> Annotatable { + let info = codemap::ExpnInfo { + call_site: codemap::DUMMY_SP, + callee: codemap::NameAndSpan { + format: codemap::MacroAttribute(intern(&format!("derive({})", derive))), + span: None, + allow_internal_unstable: false, + }, + }; + let expn_id = cx.codemap().record_expansion(info); + + let mut respanner = Respanner { expn_id: expn_id }; + let item = item.map(|item| respanner.fold_item_simple(item)); + Annotatable::Item(item) +} + +struct Respanner { + expn_id: ExpnId, +} + +impl Folder for Respanner { + fn new_span(&mut self, span: Span) -> Span { + Span { + expn_id: self.expn_id, + .. span + } + } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } +}