@@ -44,7 +44,7 @@ use std::collections::HashSet;
44
44
use syntax:: ast;
45
45
use syntax:: attr;
46
46
use syntax:: feature_gate:: { AttributeGate , AttributeType , Stability , deprecated_attributes} ;
47
- use syntax_pos:: { Span , SyntaxContext } ;
47
+ use syntax_pos:: { BytePos , Span , SyntaxContext } ;
48
48
use syntax:: symbol:: keywords;
49
49
50
50
use rustc:: hir:: { self , PatKind } ;
@@ -1133,35 +1133,55 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
1133
1133
fn check_item ( & mut self , cx : & LateContext , it : & hir:: Item ) {
1134
1134
match it. node {
1135
1135
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
+ }
1138
1140
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 ( ) ;
1142
1148
}
1143
1149
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 ( ) ;
1147
1158
}
1148
1159
}
1149
1160
}
1150
1161
hir:: ItemStatic ( ..) => {
1151
1162
if attr:: contains_name ( & it. attrs , "no_mangle" ) &&
1152
1163
!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 ( ) ;
1156
1171
}
1157
1172
}
1158
1173
hir:: ItemConst ( ..) => {
1159
1174
if attr:: contains_name ( & it. attrs , "no_mangle" ) {
1160
1175
// Const items do not refer to a particular location in memory, and therefore
1161
1176
// 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 ( ) ;
1165
1185
}
1166
1186
}
1167
1187
_ => { }
0 commit comments