@@ -230,7 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
230230 } ) ;
231231 let sig = hir:: FnSig {
232232 decl,
233- header : this. lower_fn_header ( * header, hir:: Safety :: Safe ) ,
233+ header : this. lower_fn_header ( * header, hir:: Safety :: Safe , attrs ) ,
234234 span : this. lower_span ( * fn_sig_span) ,
235235 } ;
236236 hir:: ItemKind :: Fn ( sig, generics, body_id)
@@ -608,7 +608,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
608608 fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
609609 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
610610 let owner_id = hir_id. expect_owner ( ) ;
611- self . lower_attrs ( hir_id, & i. attrs ) ;
611+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
612612 let item = hir:: ForeignItem {
613613 owner_id,
614614 ident : self . lower_ident ( i. ident ) ,
@@ -632,7 +632,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
632632 } ) ;
633633
634634 // Unmarked safety in unsafe block defaults to unsafe.
635- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe ) ;
635+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Unsafe , attrs ) ;
636636
637637 hir:: ForeignItemKind :: Fn (
638638 hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -747,7 +747,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
747747
748748 fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
749749 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
750- self . lower_attrs ( hir_id, & i. attrs ) ;
750+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
751751 let trait_item_def_id = hir_id. expect_owner ( ) ;
752752
753753 let ( generics, kind, has_default) = match & i. kind {
@@ -774,6 +774,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
774774 i. id ,
775775 FnDeclKind :: Trait ,
776776 sig. header . coroutine_kind ,
777+ attrs,
777778 ) ;
778779 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
779780 }
@@ -792,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
792793 i. id ,
793794 FnDeclKind :: Trait ,
794795 sig. header . coroutine_kind ,
796+ attrs,
795797 ) ;
796798 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
797799 }
@@ -877,7 +879,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
877879 let has_value = true ;
878880 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
879881 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
880- self . lower_attrs ( hir_id, & i. attrs ) ;
882+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
881883
882884 let ( generics, kind) = match & i. kind {
883885 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -907,6 +909,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
907909 i. id ,
908910 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
909911 sig. header . coroutine_kind ,
912+ attrs,
910913 ) ;
911914
912915 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1319,8 +1322,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13191322 id : NodeId ,
13201323 kind : FnDeclKind ,
13211324 coroutine_kind : Option < CoroutineKind > ,
1325+ attrs : & [ hir:: Attribute ] ,
13221326 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1323- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe ) ;
1327+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe , attrs ) ;
13241328 let itctx = ImplTraitContext :: Universal ;
13251329 let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
13261330 this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1332,6 +1336,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13321336 & mut self ,
13331337 h : FnHeader ,
13341338 default_safety : hir:: Safety ,
1339+ attrs : & [ hir:: Attribute ] ,
13351340 ) -> hir:: FnHeader {
13361341 let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
13371342 hir:: IsAsync :: Async ( span)
@@ -1340,7 +1345,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
13401345 } ;
13411346
13421347 let safety = self . lower_safety ( h. safety , default_safety) ;
1343- let safety = safety. into ( ) ;
1348+
1349+ // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
1350+ let safety =
1351+ if attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: target_feature) ) && safety. is_safe ( ) {
1352+ hir:: HeaderSafety :: SafeTargetFeatures
1353+ } else {
1354+ safety. into ( )
1355+ } ;
13441356
13451357 hir:: FnHeader {
13461358 safety,
0 commit comments