@@ -5,7 +5,8 @@ use rustc_ast::token;
55use rustc_ast:: tokenstream:: { TokenStream , TokenTree } ;
66use rustc_ast:: { self as ast, * } ;
77use 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;
910use rustc_parse:: nt_to_tokenstream;
1011use rustc_span:: symbol:: sym;
1112use rustc_span:: { Span , DUMMY_SP } ;
@@ -182,9 +183,22 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
182183 . filter_map ( |nmi| match nmi {
183184 NestedMetaItem :: Literal ( lit) => {
184185 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 ( ) ;
188202 None
189203 }
190204 NestedMetaItem :: MetaItem ( mi) => Some ( mi) ,
0 commit comments