@@ -25,7 +25,7 @@ use crate::parse::{token, ParseSess};
2525use crate :: symbol:: { Symbol , kw, sym} ;
2626use crate :: tokenstream:: TokenTree ;
2727
28- use errors:: { DiagnosticBuilder , Handler } ;
28+ use errors:: { Applicability , DiagnosticBuilder , Handler } ;
2929use rustc_data_structures:: fx:: FxHashMap ;
3030use rustc_target:: spec:: abi:: Abi ;
3131use syntax_pos:: { Span , DUMMY_SP } ;
@@ -1422,7 +1422,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
14221422 Normal ,
14231423 template ! (
14241424 Word ,
1425- List : r#"/*opt*/ since = "version", /*opt*/ note = "reason"# ,
1425+ List : r#"/*opt*/ since = "version", /*opt*/ note = "reason"" # ,
14261426 NameValueStr : "reason"
14271427 ) ,
14281428 Ungated
@@ -1858,24 +1858,32 @@ impl<'a> PostExpansionVisitor<'a> {
18581858
18591859 match attr. parse_meta ( self . context . parse_sess ) {
18601860 Ok ( meta) => if !should_skip ( name) && !template. compatible ( & meta. node ) {
1861+ let error_msg = format ! ( "malformed `{}` attribute input" , name) ;
18611862 let mut msg = "attribute must be of the form " . to_owned ( ) ;
1863+ let mut suggestions = vec ! [ ] ;
18621864 let mut first = true ;
18631865 if template. word {
18641866 first = false ;
1865- msg. push_str ( & format ! ( "`#[{}{}]`" , name, "" ) ) ;
1867+ let code = format ! ( "#[{}]" , name) ;
1868+ msg. push_str ( & format ! ( "`{}`" , & code) ) ;
1869+ suggestions. push ( code) ;
18661870 }
18671871 if let Some ( descr) = template. list {
18681872 if !first {
18691873 msg. push_str ( " or " ) ;
18701874 }
18711875 first = false ;
1872- msg. push_str ( & format ! ( "`#[{}({})]`" , name, descr) ) ;
1876+ let code = format ! ( "#[{}({})]" , name, descr) ;
1877+ msg. push_str ( & format ! ( "`{}`" , & code) ) ;
1878+ suggestions. push ( code) ;
18731879 }
18741880 if let Some ( descr) = template. name_value_str {
18751881 if !first {
18761882 msg. push_str ( " or " ) ;
18771883 }
1878- msg. push_str ( & format ! ( "`#[{} = \" {}\" ]`" , name, descr) ) ;
1884+ let code = format ! ( "#[{} = \" {}\" ]" , name, descr) ;
1885+ msg. push_str ( & format ! ( "`{}`" , & code) ) ;
1886+ suggestions. push ( code) ;
18791887 }
18801888 if should_warn ( name) {
18811889 self . context . parse_sess . buffer_lint (
@@ -1885,7 +1893,17 @@ impl<'a> PostExpansionVisitor<'a> {
18851893 & msg,
18861894 ) ;
18871895 } else {
1888- self . context . parse_sess . span_diagnostic . span_err ( meta. span , & msg) ;
1896+ self . context . parse_sess . span_diagnostic . struct_span_err ( meta. span , & error_msg)
1897+ . span_suggestions (
1898+ meta. span ,
1899+ if suggestions. len ( ) == 1 {
1900+ "must be of the form"
1901+ } else {
1902+ "the following are the possible correct uses"
1903+ } ,
1904+ suggestions. into_iter ( ) ,
1905+ Applicability :: HasPlaceholders ,
1906+ ) . emit ( ) ;
18891907 }
18901908 }
18911909 Err ( mut err) => err. emit ( ) ,
@@ -2298,6 +2316,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
22982316 let mut err = struct_span_err ! ( span_handler, span, E0557 , "feature has been removed" ) ;
22992317 if let Some ( reason) = reason {
23002318 err. span_note ( span, reason) ;
2319+ } else {
2320+ err. span_label ( span, "feature has been removed" ) ;
23012321 }
23022322 err. emit ( ) ;
23032323 }
@@ -2379,12 +2399,24 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
23792399 None => continue ,
23802400 } ;
23812401
2402+ let bad_input = |span| {
2403+ struct_span_err ! ( span_handler, span, E0556 , "malformed `feature` attribute input" )
2404+ } ;
2405+
23822406 for mi in list {
23832407 let name = match mi. ident ( ) {
23842408 Some ( ident) if mi. is_word ( ) => ident. name ,
2385- _ => {
2386- span_err ! ( span_handler, mi. span( ) , E0556 ,
2387- "malformed feature, expected just one word" ) ;
2409+ Some ( ident) => {
2410+ bad_input ( mi. span ( ) ) . span_suggestion (
2411+ mi. span ( ) ,
2412+ "expected just one word" ,
2413+ format ! ( "{}" , ident. name) ,
2414+ Applicability :: MaybeIncorrect ,
2415+ ) . emit ( ) ;
2416+ continue
2417+ }
2418+ None => {
2419+ bad_input ( mi. span ( ) ) . span_label ( mi. span ( ) , "expected just one word" ) . emit ( ) ;
23882420 continue
23892421 }
23902422 } ;
0 commit comments