@@ -11,9 +11,9 @@ use rustc_data_structures::fx::FxHashMap;
11
11
use rustc_errors:: StashKey ;
12
12
use rustc_errors:: { Applicability , DiagCtxt , IntoDiagArg , MultiSpan } ;
13
13
use rustc_feature:: { AttributeDuplicates , AttributeType , BuiltinAttribute , BUILTIN_ATTRIBUTE_MAP } ;
14
- use rustc_hir as hir;
15
14
use rustc_hir:: def_id:: LocalModDefId ;
16
15
use rustc_hir:: intravisit:: { self , Visitor } ;
16
+ use rustc_hir:: { self as hir} ;
17
17
use rustc_hir:: {
18
18
self , FnSig , ForeignItem , HirId , Item , ItemKind , TraitItem , CRATE_HIR_ID , CRATE_OWNER_ID ,
19
19
} ;
@@ -519,7 +519,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
519
519
self . dcx ( ) . emit_err ( errors:: NakedTrackedCaller { attr_span } ) ;
520
520
false
521
521
}
522
- Target :: Fn | Target :: Method ( ..) | Target :: ForeignFn | Target :: Closure => true ,
522
+ Target :: Fn => {
523
+ // `#[track_caller]` is not valid on weak lang items because they are called via
524
+ // `extern` declarations and `#[track_caller]` would alter their ABI.
525
+ if let Some ( ( lang_item, _) ) = hir:: lang_items:: extract ( attrs)
526
+ && let Some ( item) = hir:: LangItem :: from_name ( lang_item)
527
+ && item. is_weak ( )
528
+ {
529
+ let sig = self . tcx . hir_node ( hir_id) . fn_sig ( ) . unwrap ( ) ;
530
+
531
+ self . dcx ( ) . emit_err ( errors:: LangItemWithTrackCaller {
532
+ attr_span,
533
+ name : lang_item,
534
+ sig_span : sig. span ,
535
+ } ) ;
536
+ false
537
+ } else {
538
+ true
539
+ }
540
+ }
541
+ Target :: Method ( ..) | Target :: ForeignFn | Target :: Closure => true ,
523
542
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
524
543
// `#[track_caller]` attribute with just a lint, because we previously
525
544
// erroneously allowed it and some crates used it accidentally, to be compatible
0 commit comments