@@ -5,7 +5,8 @@ use rustc_ast::token;
5
5
use rustc_ast:: tokenstream:: { TokenStream , TokenTree } ;
6
6
use rustc_ast:: { self as ast, * } ;
7
7
use rustc_data_structures:: sync:: Lrc ;
8
- use rustc_errors:: { Applicability , ErrorReported } ;
8
+ use rustc_errors:: { struct_span_err, Applicability , ErrorReported } ;
9
+ use rustc_lexer:: is_ident;
9
10
use rustc_parse:: nt_to_tokenstream;
10
11
use rustc_span:: symbol:: sym;
11
12
use rustc_span:: { Span , DUMMY_SP } ;
@@ -182,9 +183,22 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
182
183
. filter_map ( |nmi| match nmi {
183
184
NestedMetaItem :: Literal ( lit) => {
184
185
error_reported_filter_map = true ;
185
- cx. struct_span_err ( lit. span , "expected path to a trait, found literal" )
186
- . help ( "for example, write `#[derive(Debug)]` for `Debug`" )
187
- . emit ( ) ;
186
+ let mut err = struct_span_err ! (
187
+ cx. sess,
188
+ lit. span,
189
+ E0777 ,
190
+ "expected path to a trait, found literal" ,
191
+ ) ;
192
+ let token = lit. token . to_string ( ) ;
193
+ if token. starts_with ( '"' )
194
+ && token. len ( ) > 2
195
+ && is_ident ( & token[ 1 ..token. len ( ) - 1 ] )
196
+ {
197
+ err. help ( & format ! ( "try using `#[derive({})]`" , & token[ 1 ..token. len( ) - 1 ] ) ) ;
198
+ } else {
199
+ err. help ( "for example, write `#[derive(Debug)]` for `Debug`" ) ;
200
+ }
201
+ err. emit ( ) ;
188
202
None
189
203
}
190
204
NestedMetaItem :: MetaItem ( mi) => Some ( mi) ,
0 commit comments