@@ -231,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
231231 } ) ;
232232 let sig = hir:: FnSig {
233233 decl,
234- header : this. lower_fn_header ( * header, hir:: Safety :: Safe ) ,
234+ header : this. lower_fn_header ( * header, hir:: Safety :: Safe , attrs ) ,
235235 span : this. lower_span ( * fn_sig_span) ,
236236 } ;
237237 hir:: ItemKind :: Fn ( sig, generics, body_id)
@@ -609,7 +609,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
609609 fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
610610 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
611611 let owner_id = hir_id. expect_owner ( ) ;
612- self . lower_attrs ( hir_id, & i. attrs ) ;
612+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
613613 let item = hir:: ForeignItem {
614614 owner_id,
615615 ident : self . lower_ident ( i. ident ) ,
@@ -633,7 +633,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
633633 } ) ;
634634
635635 // Unmarked safety in unsafe block defaults to unsafe.
636- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe ) ;
636+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe , attrs ) ;
637637
638638 hir:: ForeignItemKind :: Fn (
639639 hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -748,7 +748,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
748748
749749 fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
750750 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
751- self . lower_attrs ( hir_id, & i. attrs ) ;
751+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
752752 let trait_item_def_id = hir_id. expect_owner ( ) ;
753753
754754 let ( generics, kind, has_default) = match & i. kind {
@@ -775,6 +775,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775775 i. id ,
776776 FnDeclKind :: Trait ,
777777 sig. header . coroutine_kind ,
778+ attrs,
778779 ) ;
779780 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
780781 }
@@ -793,6 +794,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
793794 i. id ,
794795 FnDeclKind :: Trait ,
795796 sig. header . coroutine_kind ,
797+ attrs,
796798 ) ;
797799 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
798800 }
@@ -878,7 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
878880 let has_value = true ;
879881 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
880882 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
881- self . lower_attrs ( hir_id, & i. attrs ) ;
883+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
882884
883885 let ( generics, kind) = match & i. kind {
884886 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -908,6 +910,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
908910 i. id ,
909911 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
910912 sig. header . coroutine_kind ,
913+ attrs,
911914 ) ;
912915
913916 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1322,8 +1325,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13221325 id : NodeId ,
13231326 kind : FnDeclKind ,
13241327 coroutine_kind : Option < CoroutineKind > ,
1328+ attrs : & [ Attribute ] ,
13251329 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1326- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe ) ;
1330+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe , attrs ) ;
13271331 let itctx = ImplTraitContext :: Universal ;
13281332 let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
13291333 this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1335,14 +1339,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
13351339 & mut self ,
13361340 h : FnHeader ,
13371341 default_safety : hir:: Safety ,
1342+ attrs : & [ Attribute ] ,
13381343 ) -> hir:: FnHeader {
13391344 let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
13401345 hir:: IsAsync :: Async ( span)
13411346 } else {
13421347 hir:: IsAsync :: NotAsync
13431348 } ;
1349+
1350+ let safety = self . lower_safety ( h. safety , default_safety) ;
1351+
1352+ // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
1353+ let target_feature =
1354+ attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: target_feature) ) && safety. is_safe ( ) ;
1355+ let safety = ( !target_feature) . then_some ( safety) ;
1356+
13441357 hir:: FnHeader {
1345- safety : self . lower_safety ( h . safety , default_safety ) ,
1358+ safety,
13461359 asyncness,
13471360 constness : self . lower_constness ( h. constness ) ,
13481361 abi : self . lower_extern ( h. ext ) ,
0 commit comments