@@ -2,9 +2,9 @@ use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
2
2
use quote:: { format_ident, quote, ToTokens } ;
3
3
use std:: collections:: BTreeSet as Set ;
4
4
use std:: iter:: FromIterator ;
5
- use syn:: parse:: { Nothing , ParseStream } ;
5
+ use syn:: parse:: ParseStream ;
6
6
use syn:: {
7
- braced, bracketed, parenthesized, token, Attribute , Error , Ident , Index , LitInt , LitStr ,
7
+ braced, bracketed, parenthesized, token, Attribute , Error , Ident , Index , LitInt , LitStr , Meta ,
8
8
Result , Token ,
9
9
} ;
10
10
@@ -54,24 +54,27 @@ pub fn get(input: &[Attribute]) -> Result<Attrs> {
54
54
} ;
55
55
56
56
for attr in input {
57
- if attr. path . is_ident ( "error" ) {
57
+ if attr. path ( ) . is_ident ( "error" ) {
58
58
parse_error_attribute ( & mut attrs, attr) ?;
59
- } else if attr. path . is_ident ( "source" ) {
59
+ } else if attr. path ( ) . is_ident ( "source" ) {
60
60
require_empty_attribute ( attr) ?;
61
61
if attrs. source . is_some ( ) {
62
62
return Err ( Error :: new_spanned ( attr, "duplicate #[source] attribute" ) ) ;
63
63
}
64
64
attrs. source = Some ( attr) ;
65
- } else if attr. path . is_ident ( "backtrace" ) {
65
+ } else if attr. path ( ) . is_ident ( "backtrace" ) {
66
66
require_empty_attribute ( attr) ?;
67
67
if attrs. backtrace . is_some ( ) {
68
68
return Err ( Error :: new_spanned ( attr, "duplicate #[backtrace] attribute" ) ) ;
69
69
}
70
70
attrs. backtrace = Some ( attr) ;
71
- } else if attr. path . is_ident ( "from" ) {
72
- if !attr. tokens . is_empty ( ) {
73
- // Assume this is meant for derive_more crate or something.
74
- continue ;
71
+ } else if attr. path ( ) . is_ident ( "from" ) {
72
+ match attr. meta {
73
+ Meta :: Path ( _) => { }
74
+ Meta :: List ( _) | Meta :: NameValue ( _) => {
75
+ // Assume this is meant for derive_more crate or something.
76
+ continue ;
77
+ }
75
78
}
76
79
if attrs. from . is_some ( ) {
77
80
return Err ( Error :: new_spanned ( attr, "duplicate #[from] attribute" ) ) ;
@@ -166,21 +169,21 @@ fn parse_token_expr(input: ParseStream, mut begin_expr: bool) -> Result<TokenStr
166
169
let delimiter = parenthesized ! ( content in input) ;
167
170
let nested = parse_token_expr ( & content, true ) ?;
168
171
let mut group = Group :: new ( Delimiter :: Parenthesis , nested) ;
169
- group. set_span ( delimiter. span ) ;
172
+ group. set_span ( delimiter. span . join ( ) ) ;
170
173
TokenTree :: Group ( group)
171
174
} else if input. peek ( token:: Brace ) {
172
175
let content;
173
176
let delimiter = braced ! ( content in input) ;
174
177
let nested = parse_token_expr ( & content, true ) ?;
175
178
let mut group = Group :: new ( Delimiter :: Brace , nested) ;
176
- group. set_span ( delimiter. span ) ;
179
+ group. set_span ( delimiter. span . join ( ) ) ;
177
180
TokenTree :: Group ( group)
178
181
} else if input. peek ( token:: Bracket ) {
179
182
let content;
180
183
let delimiter = bracketed ! ( content in input) ;
181
184
let nested = parse_token_expr ( & content, true ) ?;
182
185
let mut group = Group :: new ( Delimiter :: Bracket , nested) ;
183
- group. set_span ( delimiter. span ) ;
186
+ group. set_span ( delimiter. span . join ( ) ) ;
184
187
TokenTree :: Group ( group)
185
188
} else {
186
189
input. parse ( ) ?
@@ -191,8 +194,15 @@ fn parse_token_expr(input: ParseStream, mut begin_expr: bool) -> Result<TokenStr
191
194
}
192
195
193
196
fn require_empty_attribute ( attr : & Attribute ) -> Result < ( ) > {
194
- syn:: parse2 :: < Nothing > ( attr. tokens . clone ( ) ) ?;
195
- Ok ( ( ) )
197
+ let error_span = match & attr. meta {
198
+ Meta :: Path ( _) => return Ok ( ( ) ) ,
199
+ Meta :: List ( meta) => meta. delimiter . span ( ) . open ( ) ,
200
+ Meta :: NameValue ( meta) => meta. eq_token . span ,
201
+ } ;
202
+ Err ( Error :: new (
203
+ error_span,
204
+ "unexpected token in thiserror attribute" ,
205
+ ) )
196
206
}
197
207
198
208
impl ToTokens for Display < ' _ > {
0 commit comments