@@ -44,7 +44,7 @@ use std::collections::HashSet;
4444use syntax:: ast;
4545use syntax:: attr;
4646use syntax:: feature_gate:: { AttributeGate , AttributeType , Stability , deprecated_attributes} ;
47- use syntax_pos:: { Span , SyntaxContext } ;
47+ use syntax_pos:: { BytePos , Span , SyntaxContext } ;
4848use syntax:: symbol:: keywords;
4949
5050use rustc:: hir:: { self , PatKind } ;
@@ -1133,35 +1133,55 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
11331133 fn check_item ( & mut self , cx : & LateContext , it : & hir:: Item ) {
11341134 match it. node {
11351135 hir:: ItemFn ( .., ref generics, _) => {
1136- if attr:: contains_name ( & it. attrs , "no_mangle" ) &&
1137- !attr:: contains_name ( & it. attrs , "linkage" ) {
1136+ if let Some ( no_mangle_attr) = attr:: find_by_name ( & it. attrs , "no_mangle" ) {
1137+ if attr:: contains_name ( & it. attrs , "linkage" ) {
1138+ return ;
1139+ }
11381140 if !cx. access_levels . is_reachable ( it. id ) {
1139- let msg = format ! ( "function {} is marked #[no_mangle], but not exported" ,
1140- it. name) ;
1141- cx. span_lint ( PRIVATE_NO_MANGLE_FNS , it. span , & msg) ;
1141+ let msg = "function is marked #[no_mangle], but not exported" ;
1142+ let mut err = cx. struct_span_lint ( PRIVATE_NO_MANGLE_FNS , it. span , msg) ;
1143+ let insertion_span = it. span . with_hi ( it. span . lo ( ) ) ;
1144+ err. span_suggestion ( insertion_span,
1145+ "try making it public" ,
1146+ "pub " . to_owned ( ) ) ;
1147+ err. emit ( ) ;
11421148 }
11431149 if generics. is_type_parameterized ( ) {
1144- cx. span_lint ( NO_MANGLE_GENERIC_ITEMS ,
1145- it. span ,
1146- "functions generic over types must be mangled" ) ;
1150+ let mut err = cx. struct_span_lint ( NO_MANGLE_GENERIC_ITEMS ,
1151+ it. span ,
1152+ "functions generic over \
1153+ types must be mangled") ;
1154+ err. span_suggestion_short ( no_mangle_attr. span ,
1155+ "remove this attribute" ,
1156+ "" . to_owned ( ) ) ;
1157+ err. emit ( ) ;
11471158 }
11481159 }
11491160 }
11501161 hir:: ItemStatic ( ..) => {
11511162 if attr:: contains_name ( & it. attrs , "no_mangle" ) &&
11521163 !cx. access_levels . is_reachable ( it. id ) {
1153- let msg = format ! ( "static {} is marked #[no_mangle], but not exported" ,
1154- it. name) ;
1155- cx. span_lint ( PRIVATE_NO_MANGLE_STATICS , it. span , & msg) ;
1164+ let msg = "static is marked #[no_mangle], but not exported" ;
1165+ let mut err = cx. struct_span_lint ( PRIVATE_NO_MANGLE_STATICS , it. span , msg) ;
1166+ let insertion_span = it. span . with_hi ( it. span . lo ( ) ) ;
1167+ err. span_suggestion ( insertion_span,
1168+ "try making it public" ,
1169+ "pub " . to_owned ( ) ) ;
1170+ err. emit ( ) ;
11561171 }
11571172 }
11581173 hir:: ItemConst ( ..) => {
11591174 if attr:: contains_name ( & it. attrs , "no_mangle" ) {
11601175 // Const items do not refer to a particular location in memory, and therefore
11611176 // don't have anything to attach a symbol to
1162- let msg = "const items should never be #[no_mangle], consider instead using \
1163- `pub static`";
1164- cx. span_lint ( NO_MANGLE_CONST_ITEMS , it. span , msg) ;
1177+ let msg = "const items should never be #[no_mangle]" ;
1178+ let mut err = cx. struct_span_lint ( NO_MANGLE_CONST_ITEMS , it. span , msg) ;
1179+ // `const` is 5 chars
1180+ let const_span = it. span . with_hi ( BytePos ( it. span . lo ( ) . 0 + 5 ) ) ;
1181+ err. span_suggestion ( const_span,
1182+ "try a static value" ,
1183+ "pub static" . to_owned ( ) ) ;
1184+ err. emit ( ) ;
11651185 }
11661186 }
11671187 _ => { }
0 commit comments