@@ -87,9 +87,8 @@ impl<'tcx> LateLintPass<'tcx> for RuntimeSymbols {
8787 } ;
8888
8989 let def_id = item. owner_id . def_id ;
90- let static_ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
9190
92- check_static ( cx, & symbol_name, static_ty , item. span ) ;
91+ check_static ( cx, & symbol_name, def_id , item. span ) ;
9392 }
9493 hir:: ItemKind :: ForeignMod { abi : _, items } => {
9594 for item in items {
@@ -107,9 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for RuntimeSymbols {
107106 check_fn ( cx, & symbol_name. name , fn_sig, did) ;
108107 }
109108 ForeignItemKind :: Static ( ..) => {
110- let def_id = item. owner_id . def_id ;
111- let static_ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
112- check_static ( cx, & symbol_name. name , static_ty, item. span ) ;
109+ check_static ( cx, & symbol_name. name , did, item. span ) ;
113110 }
114111 ForeignItemKind :: Type => return ,
115112 }
@@ -159,7 +156,7 @@ fn check_fn(cx: &LateContext<'_>, symbol_name: &str, sig: FnSig<'_>, did: LocalD
159156 }
160157}
161158
162- fn check_static < ' tcx > ( cx : & LateContext < ' tcx > , symbol_name : & str , static_ty : Ty < ' tcx > , sp : Span ) {
159+ fn check_static < ' tcx > ( cx : & LateContext < ' tcx > , symbol_name : & str , did : LocalDefId , sp : Span ) {
163160 let Some ( expected_symbol) = EXPECTED_SYMBOLS . iter ( ) . find ( |es| es. symbol == symbol_name) else {
164161 // The symbol name does not correspond to a runtime symbols, bail out
165162 return ;
@@ -170,19 +167,32 @@ fn check_static<'tcx>(cx: &LateContext<'tcx>, symbol_name: &str, static_ty: Ty<'
170167 return ;
171168 } ;
172169
173- // Unconditionally report a mismatch, a static cannot ever be a function definition
170+ // Get the static type
171+ let static_ty = cx. tcx . type_of ( did) . instantiate_identity ( ) ;
174172
173+ // Peel Option<...> and get the inner type (see std weak! macro with #[linkage = "extern_weak"])
174+ let inner_static_ty: Ty < ' _ > = match static_ty. kind ( ) {
175+ ty:: Adt ( def, args) if Some ( def. did ( ) ) == cx. tcx . lang_items ( ) . option_type ( ) => {
176+ args. type_at ( 0 )
177+ }
178+ _ => static_ty,
179+ } ;
180+
181+ // Get the expected symbol function signature
175182 let lang_sig =
176183 cx. tcx . erase_and_anonymize_regions ( cx. tcx . fn_sig ( expected_def_id) . instantiate_identity ( ) ) ;
177184 let expected = Ty :: new_fn_ptr ( cx. tcx , lang_sig) ;
178185
179- cx. emit_span_lint (
180- INVALID_RUNTIME_SYMBOL_DEFINITIONS ,
181- sp,
182- RedefiningRuntimeSymbolsDiag :: Static {
183- static_ty,
184- symbol_name : symbol_name. to_string ( ) ,
185- expected_fn_sig : expected,
186- } ,
187- ) ;
186+ // Compare the expected function signature with the static type, report an error if they don't match
187+ if expected != inner_static_ty {
188+ cx. emit_span_lint (
189+ INVALID_RUNTIME_SYMBOL_DEFINITIONS ,
190+ sp,
191+ RedefiningRuntimeSymbolsDiag :: Static {
192+ static_ty,
193+ symbol_name : symbol_name. to_string ( ) ,
194+ expected_fn_sig : expected,
195+ } ,
196+ ) ;
197+ }
188198}
0 commit comments