@@ -231,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
231231} ) ;
232232let 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 ) ,
235235span : 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> {
610610fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
611611let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
612612let owner_id = hir_id. expect_owner ( ) ;
613- self . lower_attrs ( hir_id, & i. attrs ) ;
613+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
614614let item = hir:: ForeignItem {
615615 owner_id,
616616ident : 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 ,
777777FnDeclKind :: 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 ,
796797FnDeclKind :: 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 ,
912914if 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> {
13391342id : NodeId ,
13401343kind : FnDeclKind ,
13411344coroutine_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 ) ;
13441348let itctx = ImplTraitContext :: Universal ;
13451349let ( 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 ,
13531357h : FnHeader ,
13541358default_safety : hir:: Safety ,
1359+ attrs : & [ hir:: Attribute ] ,
13551360) -> hir:: FnHeader {
13561361let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
13571362 hir:: IsAsync :: Async ( span)
@@ -1360,7 +1365,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
13601365} ;
13611366
13621367let 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 = if attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: target_feature) )
1371+ && safety. is_safe ( )
1372+ && !self . tcx . sess . target . is_like_wasm
1373+ {
1374+ hir:: HeaderSafety :: SafeTargetFeatures
1375+ } else {
1376+ safety. into ( )
1377+ } ;
13641378
13651379 hir:: FnHeader {
13661380 safety,
0 commit comments