@@ -87,6 +87,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8787 let mut link_ordinal_span = None ;
8888 let mut no_sanitize_span = None ;
8989 let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState :: default ( ) ;
90+ let mut no_mangle_span = None ;
9091
9192 for attr in attrs. iter ( ) {
9293 // In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -139,6 +140,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
139140 }
140141 sym:: naked => codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NAKED ,
141142 sym:: no_mangle => {
143+ no_mangle_span = Some ( attr. span ( ) ) ;
142144 if tcx. opt_item_name ( did. to_def_id ( ) ) . is_some ( ) {
143145 codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_MANGLE ;
144146 mixed_export_name_no_mangle_lint_state. track_no_mangle (
@@ -151,7 +153,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
151153 . struct_span_err (
152154 attr. span ( ) ,
153155 format ! (
154- "`#[no_mangle]` cannot be used on {} {} as it has no name" ,
156+ "`#[unsafe( no_mangle) ]` cannot be used on {} {} as it has no name" ,
155157 tcx. def_descr_article( did. to_def_id( ) ) ,
156158 tcx. def_descr( did. to_def_id( ) ) ,
157159 ) ,
@@ -608,11 +610,55 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
608610 // strippable by the linker.
609611 //
610612 // Additionally weak lang items have predetermined symbol names.
611- if let Some ( ( name, _ ) ) = lang_items:: extract ( attrs)
613+ if let Some ( ( name, span ) ) = lang_items:: extract ( attrs)
612614 && let Some ( lang_item) = LangItem :: from_name ( name)
613615 {
616+ let has_no_mangle = codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: NO_MANGLE ) ;
614617 if WEAK_LANG_ITEMS . contains ( & lang_item) {
615618 codegen_fn_attrs. flags |= CodegenFnAttrFlags :: RUSTC_STD_INTERNAL_SYMBOL ;
619+ if has_no_mangle {
620+ // This should never use the default as `no_mangle` is present in the attributes list
621+ let no_mangle_span = no_mangle_span. unwrap_or_default ( ) ;
622+ let label_attr = format ! ( "this defines it as the `{}` item" , lang_item. name( ) ) ;
623+ let label = format ! ( "is the {} item" , lang_item. name( ) ) ;
624+ let mut err = tcx. dcx ( )
625+ . struct_span_err ( no_mangle_span, "`#[unsafe(no_mangle)]` cannot be used on weak language items" )
626+ . with_note ( "The linker requires specific names for internal language items," )
627+ . with_note ( "like panic handlers, eh personality functions or eh catch typeinfo variables." )
628+ . with_span_label ( tcx. def_span ( did) , label)
629+ . with_span_label ( span, label_attr) ;
630+ if let Some ( link_name) = lang_item. link_name ( ) {
631+ let renamed =
632+ format ! ( "In this case it is automatically renamed to `{}`" , link_name) ;
633+ err = err. with_note ( renamed) ;
634+ }
635+ err. emit ( ) ;
636+ }
637+ } else {
638+ if has_no_mangle {
639+ // This should never use the default as `no_mangle` is present in the attributes list
640+ let no_mangle_span = no_mangle_span. unwrap_or_default ( ) ;
641+ let label_attr = format ! ( "this defines it as the `{}` item" , lang_item. name( ) ) ;
642+ let label = format ! ( "is the {} item" , lang_item. name( ) ) ;
643+ let mut warn = tcx
644+ . dcx ( )
645+ . struct_span_warn (
646+ no_mangle_span,
647+ "`#[unsafe(no_mangle)]` should not be used on std internal language items" ,
648+ )
649+ . with_note ( "The linker requires specific names for internal language items," )
650+ . with_note ( "as they might require a specific link name in the future." )
651+ . with_span_label ( tcx. def_span ( did) , label)
652+ . with_span_label ( span, label_attr) ;
653+ if let Some ( link_name) = lang_item. link_name ( ) {
654+ let renamed = format ! (
655+ "In this case this should be automatically renamed to `{}`" ,
656+ link_name
657+ ) ;
658+ warn = warn. with_note ( renamed) ;
659+ }
660+ warn. emit ( ) ;
661+ }
616662 }
617663 if let Some ( link_name) = lang_item. link_name ( ) {
618664 codegen_fn_attrs. export_name = Some ( link_name) ;
0 commit comments