diff options
| author | bors <bors@rust-lang.org> | 2016-09-11 15:12:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-11 15:12:27 -0700 |
| commit | 0be88eb794949d27331ec45c300a40369b541001 (patch) | |
| tree | f57f3c24d72a7e1af6b75c471eb43ef362f5bfb0 /src/libsyntax_ext | |
| parent | 4812cf392f1fa2258033356dd872fbee58a5406e (diff) | |
| parent | fe41520fceb00427e797cc0b42f449f54967b104 (diff) | |
| download | rust-0be88eb794949d27331ec45c300a40369b541001.tar.gz rust-0be88eb794949d27331ec45c300a40369b541001.zip | |
Auto merge of #36308 - dtolnay:inputitem, r=alexcrichton
Point macros 1.1 errors to the input item
Moved from https://github.com/alexcrichton/rust/pull/6 to continue discussion. Fixes #36218.
Before:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:10:10
|
10 | #[derive(Serialize, Deserialize)]
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:15:15
|
15 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^ the trait `T` cannot be made into an object
```
After:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:11:1
|
11 | struct A {
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:16:1
|
16 | struct B<'a> {
| ^ the trait `T` cannot be made into an object
```
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/deriving/custom.rs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 1f9c24a0dcd..465fc0016e5 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -10,12 +10,14 @@ use std::panic; +use errors::FatalError; use rustc_macro::{TokenStream, __internal}; use syntax::ast::{self, ItemKind}; -use syntax::codemap::Span; +use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan, Span}; use syntax::ext::base::*; use syntax::fold::{self, Folder}; -use errors::FatalError; +use syntax::parse::token::intern; +use syntax::print::pprust; pub struct CustomDerive { inner: fn(TokenStream) -> TokenStream, @@ -31,7 +33,7 @@ impl MultiItemModifier for CustomDerive { fn expand(&self, ecx: &mut ExtCtxt, span: Span, - _meta_item: &ast::MetaItem, + meta_item: &ast::MetaItem, item: Annotatable) -> Vec<Annotatable> { let item = match item { @@ -53,6 +55,17 @@ impl MultiItemModifier for CustomDerive { } } + let input_span = Span { + expn_id: ecx.codemap().record_expansion(ExpnInfo { + call_site: span, + callee: NameAndSpan { + format: MacroAttribute(intern(&pprust::meta_item_to_string(meta_item))), + span: Some(span), + allow_internal_unstable: true, + }, + }), + ..item.span + }; let input = __internal::new_token_stream(item); let res = __internal::set_parse_sess(&ecx.parse_sess, || { let inner = self.inner; @@ -77,9 +90,9 @@ impl MultiItemModifier for CustomDerive { // Right now we have no knowledge of spans at all in custom derive // macros, everything is just parsed as a string. Reassign all spans to - // the #[derive] attribute for better errors here. + // the input `item` for better errors here. item.into_iter().flat_map(|item| { - ChangeSpan { span: span }.fold_item(item) + ChangeSpan { span: input_span }.fold_item(item) }).map(Annotatable::Item).collect() } } |
