@@ -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 : body_id, has_body : body. is_some ( ) }
@@ -610,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
610610 fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
611611 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
612612 let owner_id = hir_id. expect_owner ( ) ;
613- self . lower_attrs ( hir_id, & i. attrs ) ;
613+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
614614 let item = hir:: ForeignItem {
615615 owner_id,
616616 ident : self . lower_ident ( i. ident ) ,
@@ -634,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
634634 } ) ;
635635
636636 // Unmarked safety in unsafe block defaults to unsafe.
637- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe ) ;
637+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe , attrs ) ;
638638
639639 hir:: ForeignItemKind :: Fn (
640640 hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -776,6 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
776776 i. id ,
777777 FnDeclKind :: Trait ,
778778 sig. header . coroutine_kind ,
779+ attrs,
779780 ) ;
780781 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
781782 }
@@ -795,6 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795796 i. id ,
796797 FnDeclKind :: Trait ,
797798 sig. header . coroutine_kind ,
799+ attrs,
798800 ) ;
799801 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
800802 }
@@ -911,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911913 i. id ,
912914 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
913915 sig. header . coroutine_kind ,
916+ attrs,
914917 ) ;
915918
916919 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1339,8 +1342,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13391342 id : NodeId ,
13401343 kind : FnDeclKind ,
13411344 coroutine_kind : Option < CoroutineKind > ,
1345+ attrs : & [ hir:: Attribute ] ,
13421346 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1343- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe ) ;
1347+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe , attrs ) ;
13441348 let itctx = ImplTraitContext :: Universal ;
13451349 let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
13461350 this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1352,6 +1356,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13521356 & mut self ,
13531357 h : FnHeader ,
13541358 default_safety : hir:: Safety ,
1359+ attrs : & [ hir:: Attribute ] ,
13551360 ) -> hir:: FnHeader {
13561361 let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
13571362 hir:: IsAsync :: Async ( span)
@@ -1360,7 +1365,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
13601365 } ;
13611366
13621367 let safety = self . lower_safety ( h. safety , default_safety) ;
1363- let safety = safety. into ( ) ;
1368+
1369+ // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
1370+ let safety =
1371+ if attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: target_feature) ) && safety. is_safe ( ) {
1372+ hir:: HeaderSafety :: SafeTargetFeatures
1373+ } else {
1374+ safety. into ( )
1375+ } ;
13641376
13651377 hir:: FnHeader {
13661378 safety,
0 commit comments