@@ -231,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
231
231
} ) ;
232
232
let sig = hir:: FnSig {
233
233
decl,
234
- header : this. lower_fn_header ( * header, hir:: Safety :: Safe ) ,
234
+ header : this. lower_fn_header ( * header, hir:: Safety :: Safe , attrs ) ,
235
235
span : this. lower_span ( * fn_sig_span) ,
236
236
} ;
237
237
hir:: ItemKind :: Fn ( sig, generics, body_id)
@@ -609,7 +609,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
609
609
fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
610
610
let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
611
611
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 ) ;
613
613
let item = hir:: ForeignItem {
614
614
owner_id,
615
615
ident : self . lower_ident ( i. ident ) ,
@@ -633,7 +633,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
633
633
} ) ;
634
634
635
635
// 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 ) ;
637
637
638
638
hir:: ForeignItemKind :: Fn (
639
639
hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -748,7 +748,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
748
748
749
749
fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
750
750
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 ) ;
752
752
let trait_item_def_id = hir_id. expect_owner ( ) ;
753
753
754
754
let ( generics, kind, has_default) = match & i. kind {
@@ -775,6 +775,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775
775
i. id ,
776
776
FnDeclKind :: Trait ,
777
777
sig. header . coroutine_kind ,
778
+ attrs,
778
779
) ;
779
780
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
780
781
}
@@ -793,6 +794,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
793
794
i. id ,
794
795
FnDeclKind :: Trait ,
795
796
sig. header . coroutine_kind ,
797
+ attrs,
796
798
) ;
797
799
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
798
800
}
@@ -878,7 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
878
880
let has_value = true ;
879
881
let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
880
882
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 ) ;
882
884
883
885
let ( generics, kind) = match & i. kind {
884
886
AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -908,6 +910,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
908
910
i. id ,
909
911
if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
910
912
sig. header . coroutine_kind ,
913
+ attrs,
911
914
) ;
912
915
913
916
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1322,8 +1325,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1322
1325
id : NodeId ,
1323
1326
kind : FnDeclKind ,
1324
1327
coroutine_kind : Option < CoroutineKind > ,
1328
+ attrs : & [ Attribute ] ,
1325
1329
) -> ( & ' 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 ) ;
1327
1331
let itctx = ImplTraitContext :: Universal ;
1328
1332
let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
1329
1333
this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1335,14 +1339,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
1335
1339
& mut self ,
1336
1340
h : FnHeader ,
1337
1341
default_safety : hir:: Safety ,
1342
+ attrs : & [ Attribute ] ,
1338
1343
) -> hir:: FnHeader {
1339
1344
let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
1340
1345
hir:: IsAsync :: Async ( span)
1341
1346
} else {
1342
1347
hir:: IsAsync :: NotAsync
1343
1348
} ;
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
+
1344
1357
hir:: FnHeader {
1345
- safety : self . lower_safety ( h . safety , default_safety ) ,
1358
+ safety,
1346
1359
asyncness,
1347
1360
constness : self . lower_constness ( h. constness ) ,
1348
1361
abi : self . lower_extern ( h. ext ) ,
0 commit comments