@@ -54,11 +54,11 @@ use crate::lints::{
5454    BuiltinExplicitOutlives ,  BuiltinExplicitOutlivesSuggestion ,  BuiltinFeatureIssueNote , 
5555    BuiltinIncompleteFeatures ,  BuiltinIncompleteFeaturesHelp ,  BuiltinInternalFeatures , 
5656    BuiltinKeywordIdents ,  BuiltinMissingCopyImpl ,  BuiltinMissingDebugImpl ,  BuiltinMissingDoc , 
57-     BuiltinMutablesTransmutes ,  BuiltinNoMangleGeneric ,   BuiltinNonShorthandFieldPatterns , 
58-     BuiltinSpecialModuleNameUsed ,   BuiltinTrivialBounds ,   BuiltinTypeAliasBounds , 
59-     BuiltinUngatedAsyncFnTrackCaller ,   BuiltinUnpermittedTypeInit ,   BuiltinUnpermittedTypeInitSub , 
60-     BuiltinUnreachablePub ,  BuiltinUnsafe ,  BuiltinUnstableFeatures ,   BuiltinUnusedDocComment , 
61-     BuiltinUnusedDocCommentSub ,  BuiltinWhileTrue ,  InvalidAsmLabel , 
57+     BuiltinMutablesTransmutes ,  BuiltinNoMangleOrExportNameGeneric , 
58+     BuiltinNonShorthandFieldPatterns ,   BuiltinSpecialModuleNameUsed ,   BuiltinTrivialBounds , 
59+     BuiltinTypeAliasBounds ,   BuiltinUngatedAsyncFnTrackCaller ,   BuiltinUnpermittedTypeInit , 
60+     BuiltinUnpermittedTypeInitSub ,   BuiltinUnreachablePub ,  BuiltinUnsafe ,  BuiltinUnstableFeatures , 
61+     BuiltinUnusedDocComment ,   BuiltinUnusedDocCommentSub ,  BuiltinWhileTrue ,  InvalidAsmLabel , 
6262} ; 
6363use  crate :: nonstandard_style:: { MethodLateContext ,  method_context} ; 
6464use  crate :: { 
@@ -992,36 +992,69 @@ declare_lint! {
992992    "generic items must be mangled" 
993993} 
994994
995- declare_lint_pass ! ( InvalidNoMangleItems  => [ NO_MANGLE_CONST_ITEMS ,  NO_MANGLE_GENERIC_ITEMS ] ) ; 
995+ declare_lint !  { 
996+     /// The `export_name_generic_items` lint detects using `#[export_name]` on generic functions. 
997+      /// 
998+      /// ### Example 
999+      /// ```rust,compile_fail 
1000+      /// #[export_name = "exported_name"] 
1001+      /// fn foo<T>() {} 
1002+      /// ``` 
1003+      /// 
1004+      /// {{produces}} 
1005+      /// 
1006+      /// ### Explanation 
1007+      /// 
1008+      /// A function with generics must have its symbol mangled to accommodate 
1009+      /// the generic parameter. The [`export_name` attribute] has no effect in 
1010+      /// this situation, and should be removed. 
1011+      /// 
1012+      /// [`export_name` attribute]: https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute 
1013+      pub  EXPORT_NAME_GENERIC_ITEMS , 
1014+     Warn , 
1015+     "generic items must be mangled, export_name would avoid mangling" 
1016+ } 
1017+ 
1018+ declare_lint_pass ! ( InvalidNoMangleItems  => [ NO_MANGLE_CONST_ITEMS ,  NO_MANGLE_GENERIC_ITEMS ,  EXPORT_NAME_GENERIC_ITEMS ] ) ; 
9961019
9971020impl < ' tcx >  LateLintPass < ' tcx >  for  InvalidNoMangleItems  { 
9981021    fn  check_item ( & mut  self ,  cx :  & LateContext < ' _ > ,  it :  & hir:: Item < ' _ > )  { 
9991022        let  attrs = cx. tcx . hir_attrs ( it. hir_id ( ) ) ; 
1000-         let  check_no_mangle_on_generic_fn = |no_mangle_attr :  & hir:: Attribute , 
1001-                                              impl_generics :  Option < & hir:: Generics < ' _ > > , 
1002-                                              generics :  & hir:: Generics < ' _ > , 
1003-                                              span| { 
1004-             for  param in 
1005-                 generics. params . iter ( ) . chain ( impl_generics. map ( |g| g. params ) . into_iter ( ) . flatten ( ) ) 
1006-             { 
1007-                 match  param. kind  { 
1008-                     GenericParamKind :: Lifetime  {  .. }  => { } 
1009-                     GenericParamKind :: Type  {  .. }  | GenericParamKind :: Const  {  .. }  => { 
1010-                         cx. emit_span_lint ( 
1011-                             NO_MANGLE_GENERIC_ITEMS , 
1012-                             span, 
1013-                             BuiltinNoMangleGeneric  {  suggestion :  no_mangle_attr. span ( )  } , 
1014-                         ) ; 
1015-                         break ; 
1023+         let  check_no_mangle_or_export_name_on_generic_fn =
1024+             |attrs :  & [ hir:: Attribute ] , 
1025+              impl_generics :  Option < & hir:: Generics < ' _ > > , 
1026+              generics :  & hir:: Generics < ' _ > , 
1027+              span| { 
1028+                 let  ( lint,  attr)  =
1029+                     if  let  Some ( export_name_attr)  = attr:: find_by_name ( attrs,  sym:: export_name)  { 
1030+                         ( EXPORT_NAME_GENERIC_ITEMS ,  export_name_attr) 
1031+                     }  else  if  let  Some ( no_mangle_attr)  = attr:: find_by_name ( attrs,  sym:: no_mangle)  { 
1032+                         ( NO_MANGLE_GENERIC_ITEMS ,  no_mangle_attr) 
1033+                     }  else  { 
1034+                         return ; 
1035+                     } ; 
1036+ 
1037+                 for  param in  generics
1038+                     . params 
1039+                     . iter ( ) 
1040+                     . chain ( impl_generics. map ( |g| g. params ) . into_iter ( ) . flatten ( ) ) 
1041+                 { 
1042+                     match  param. kind  { 
1043+                         GenericParamKind :: Lifetime  {  .. }  => { } 
1044+                         GenericParamKind :: Type  {  .. }  | GenericParamKind :: Const  {  .. }  => { 
1045+                             cx. emit_span_lint ( 
1046+                                 lint, 
1047+                                 span, 
1048+                                 BuiltinNoMangleOrExportNameGeneric  {  suggestion :  attr. span ( )  } , 
1049+                             ) ; 
1050+                             break ; 
1051+                         } 
10161052                    } 
10171053                } 
1018-             } 
1019-         } ; 
1054+             } ; 
10201055        match  it. kind  { 
10211056            hir:: ItemKind :: Fn  {  generics,  .. }  => { 
1022-                 if  let  Some ( no_mangle_attr)  = attr:: find_by_name ( attrs,  sym:: no_mangle)  { 
1023-                     check_no_mangle_on_generic_fn ( no_mangle_attr,  None ,  generics,  it. span ) ; 
1024-                 } 
1057+                 check_no_mangle_or_export_name_on_generic_fn ( attrs,  None ,  generics,  it. span ) ; 
10251058            } 
10261059            hir:: ItemKind :: Const ( ..)  => { 
10271060                if  attr:: contains_name ( attrs,  sym:: no_mangle)  { 
@@ -1048,16 +1081,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10481081            hir:: ItemKind :: Impl ( hir:: Impl  {  generics,  items,  .. } )  => { 
10491082                for  it in  * items { 
10501083                    if  let  hir:: AssocItemKind :: Fn  {  .. }  = it. kind  { 
1051-                         if  let  Some ( no_mangle_attr)  =
1052-                             attr:: find_by_name ( cx. tcx . hir_attrs ( it. id . hir_id ( ) ) ,  sym:: no_mangle) 
1053-                         { 
1054-                             check_no_mangle_on_generic_fn ( 
1055-                                 no_mangle_attr, 
1056-                                 Some ( generics) , 
1057-                                 cx. tcx . hir_get_generics ( it. id . owner_id . def_id ) . unwrap ( ) , 
1058-                                 it. span , 
1059-                             ) ; 
1060-                         } 
1084+                         check_no_mangle_or_export_name_on_generic_fn ( 
1085+                             cx. tcx . hir_attrs ( it. id . hir_id ( ) ) , 
1086+                             Some ( generics) , 
1087+                             cx. tcx . hir_get_generics ( it. id . owner_id . def_id ) . unwrap ( ) , 
1088+                             it. span , 
1089+                         ) ; 
10611090                    } 
10621091                } 
10631092            } 
0 commit comments