@@ -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,11 @@ 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 (
637+ sig. header ,
638+ hir:: Safety :: Unsafe { target_feature : false } ,
639+ attrs,
640+ ) ;
637641
638642 hir:: ForeignItemKind :: Fn (
639643 hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -644,7 +648,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
644648 ForeignItemKind :: Static ( box StaticItem { ty, mutability, expr : _, safety } ) => {
645649 let ty = self
646650 . lower_ty ( ty, ImplTraitContext :: Disallowed ( ImplTraitPosition :: StaticTy ) ) ;
647- let safety = self . lower_safety ( * safety, hir:: Safety :: Unsafe ) ;
651+ let safety =
652+ self . lower_safety ( * safety, hir:: Safety :: Unsafe { target_feature : false } ) ;
648653
649654 hir:: ForeignItemKind :: Static ( ty, * mutability, safety)
650655 }
@@ -748,7 +753,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
748753
749754 fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
750755 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
751- self . lower_attrs ( hir_id, & i. attrs ) ;
756+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
752757 let trait_item_def_id = hir_id. expect_owner ( ) ;
753758
754759 let ( generics, kind, has_default) = match & i. kind {
@@ -775,6 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775780 i. id ,
776781 FnDeclKind :: Trait ,
777782 sig. header . coroutine_kind ,
783+ attrs,
778784 ) ;
779785 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
780786 }
@@ -793,6 +799,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
793799 i. id ,
794800 FnDeclKind :: Trait ,
795801 sig. header . coroutine_kind ,
802+ attrs,
796803 ) ;
797804 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
798805 }
@@ -878,7 +885,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
878885 let has_value = true ;
879886 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
880887 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
881- self . lower_attrs ( hir_id, & i. attrs ) ;
888+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
882889
883890 let ( generics, kind) = match & i. kind {
884891 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -908,6 +915,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
908915 i. id ,
909916 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
910917 sig. header . coroutine_kind ,
918+ attrs,
911919 ) ;
912920
913921 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1322,8 +1330,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13221330 id : NodeId ,
13231331 kind : FnDeclKind ,
13241332 coroutine_kind : Option < CoroutineKind > ,
1333+ attrs : & [ Attribute ] ,
13251334 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1326- let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe ) ;
1335+ let header = self . lower_fn_header ( sig. header , hir:: Safety :: Safe , attrs ) ;
13271336 let itctx = ImplTraitContext :: Universal ;
13281337 let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
13291338 this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1335,12 +1344,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
13351344 & mut self ,
13361345 h : FnHeader ,
13371346 default_safety : hir:: Safety ,
1347+ attrs : & [ Attribute ] ,
13381348 ) -> hir:: FnHeader {
13391349 let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
13401350 hir:: IsAsync :: Async ( span)
13411351 } else {
13421352 hir:: IsAsync :: NotAsync
13431353 } ;
1354+
1355+ let default_safety = if attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: target_feature) )
1356+ && !matches ! ( h. safety, Safety :: Unsafe ( _) )
1357+ && default_safety. is_safe ( )
1358+ {
1359+ hir:: Safety :: Unsafe { target_feature : true }
1360+ } else {
1361+ default_safety
1362+ } ;
1363+
13441364 hir:: FnHeader {
13451365 safety : self . lower_safety ( h. safety , default_safety) ,
13461366 asyncness,
@@ -1394,7 +1414,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13941414
13951415 pub ( super ) fn lower_safety ( & mut self , s : Safety , default : hir:: Safety ) -> hir:: Safety {
13961416 match s {
1397- Safety :: Unsafe ( _) => hir:: Safety :: Unsafe ,
1417+ Safety :: Unsafe ( _) => hir:: Safety :: Unsafe { target_feature : false } ,
13981418 Safety :: Default => default,
13991419 Safety :: Safe ( _) => hir:: Safety :: Safe ,
14001420 }
0 commit comments