@@ -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 : body_id, has_body : body. is_some ( ) }
@@ -610,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
610
610
fn lower_foreign_item ( & mut self , i : & ForeignItem ) -> & ' hir hir:: ForeignItem < ' hir > {
611
611
let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
612
612
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 ) ;
614
614
let item = hir:: ForeignItem {
615
615
owner_id,
616
616
ident : self . lower_ident ( i. ident ) ,
@@ -634,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
634
634
} ) ;
635
635
636
636
// 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 ) ;
638
638
639
639
hir:: ForeignItemKind :: Fn (
640
640
hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } ,
@@ -776,6 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
776
776
i. id ,
777
777
FnDeclKind :: Trait ,
778
778
sig. header . coroutine_kind ,
779
+ attrs,
779
780
) ;
780
781
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
781
782
}
@@ -795,6 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795
796
i. id ,
796
797
FnDeclKind :: Trait ,
797
798
sig. header . coroutine_kind ,
799
+ attrs,
798
800
) ;
799
801
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
800
802
}
@@ -911,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911
913
i. id ,
912
914
if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
913
915
sig. header . coroutine_kind ,
916
+ attrs,
914
917
) ;
915
918
916
919
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -1339,8 +1342,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1339
1342
id : NodeId ,
1340
1343
kind : FnDeclKind ,
1341
1344
coroutine_kind : Option < CoroutineKind > ,
1345
+ attrs : & [ hir:: Attribute ] ,
1342
1346
) -> ( & ' 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 ) ;
1344
1348
let itctx = ImplTraitContext :: Universal ;
1345
1349
let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
1346
1350
this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
@@ -1352,14 +1356,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
1352
1356
& mut self ,
1353
1357
h : FnHeader ,
1354
1358
default_safety : hir:: Safety ,
1359
+ attrs : & [ hir:: Attribute ] ,
1355
1360
) -> hir:: FnHeader {
1356
1361
let asyncness = if let Some ( CoroutineKind :: Async { span, .. } ) = h. coroutine_kind {
1357
1362
hir:: IsAsync :: Async ( span)
1358
1363
} else {
1359
1364
hir:: IsAsync :: NotAsync
1360
1365
} ;
1366
+
1367
+ let safety = self . lower_safety ( h. safety , default_safety) ;
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
+ } ;
1376
+
1361
1377
hir:: FnHeader {
1362
- safety : self . lower_safety ( h . safety , default_safety ) ,
1378
+ safety,
1363
1379
asyncness,
1364
1380
constness : self . lower_constness ( h. constness ) ,
1365
1381
abi : self . lower_extern ( h. ext ) ,
0 commit comments