1 // compile-flags: --emit=link
4 #![crate_type = "proc-macro"]
6 extern crate proc_macro;
7 use proc_macro::{token_stream, Delimiter, Group, Ident, Span, TokenStream, TokenTree};
8 use std::iter::FromIterator;
10 fn read_ident(iter: &mut token_stream::IntoIter) -> Ident {
12 Some(TokenTree::Ident(i)) => i,
13 _ => panic!("expected ident"),
17 #[proc_macro_derive(DeriveBadSpan)]
18 pub fn derive_bad_span(input: TokenStream) -> TokenStream {
19 let mut input = input.into_iter();
20 assert_eq!(read_ident(&mut input).to_string(), "struct");
21 let ident = read_ident(&mut input);
22 let mut tys = match input.next() {
23 Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => g.stream().into_iter(),
26 let field1 = read_ident(&mut tys);
28 let field2 = read_ident(&mut tys);
30 <TokenStream as FromIterator<TokenTree>>::from_iter(
32 Ident::new("impl", Span::call_site()).into(),
36 <TokenStream as FromIterator<TokenTree>>::from_iter(
38 Ident::new("fn", Span::call_site()).into(),
39 Ident::new("_foo", Span::call_site()).into(),
40 Group::new(Delimiter::Parenthesis, TokenStream::new()).into(),
43 <TokenStream as FromIterator<TokenTree>>::from_iter(
45 Ident::new("if", field1.span()).into(),
46 Ident::new("true", field1.span()).into(),
48 let mut group = Group::new(Delimiter::Brace, TokenStream::new());
49 group.set_span(field1.span());
52 Ident::new("if", field2.span()).into(),
53 Ident::new("true", field2.span()).into(),
55 let mut group = Group::new(Delimiter::Brace, TokenStream::new());
56 group.set_span(field2.span());