@@ -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,11 @@ 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(
637
+ sig.header,
638
+ hir::Safety::Unsafe { target_feature: false },
639
+ attrs,
640
+ );
637
641
638
642
hir::ForeignItemKind::Fn(
639
643
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
@@ -644,7 +648,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
644
648
ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
645
649
let ty = self
646
650
.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 });
648
653
649
654
hir::ForeignItemKind::Static(ty, *mutability, safety)
650
655
}
@@ -748,7 +753,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
748
753
749
754
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
750
755
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);
752
757
let trait_item_def_id = hir_id.expect_owner();
753
758
754
759
let (generics, kind, has_default) = match &i.kind {
@@ -775,6 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775
780
i.id,
776
781
FnDeclKind::Trait,
777
782
sig.header.coroutine_kind,
783
+ attrs,
778
784
);
779
785
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
780
786
}
@@ -793,6 +799,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
793
799
i.id,
794
800
FnDeclKind::Trait,
795
801
sig.header.coroutine_kind,
802
+ attrs,
796
803
);
797
804
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
798
805
}
@@ -878,7 +885,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
878
885
let has_value = true;
879
886
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
880
887
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);
882
889
883
890
let (generics, kind) = match &i.kind {
884
891
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
@@ -908,6 +915,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
908
915
i.id,
909
916
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
910
917
sig.header.coroutine_kind,
918
+ attrs,
911
919
);
912
920
913
921
(generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -1322,8 +1330,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1322
1330
id: NodeId,
1323
1331
kind: FnDeclKind,
1324
1332
coroutine_kind: Option<CoroutineKind>,
1333
+ attrs: &[Attribute],
1325
1334
) -> (&'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 );
1327
1336
let itctx = ImplTraitContext::Universal;
1328
1337
let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1329
1338
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
@@ -1335,12 +1344,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
1335
1344
&mut self,
1336
1345
h: FnHeader,
1337
1346
default_safety: hir::Safety,
1347
+ attrs: &[Attribute],
1338
1348
) -> hir::FnHeader {
1339
1349
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
1340
1350
hir::IsAsync::Async(span)
1341
1351
} else {
1342
1352
hir::IsAsync::NotAsync
1343
1353
};
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
+
1344
1364
hir::FnHeader {
1345
1365
safety: self.lower_safety(h.safety, default_safety),
1346
1366
asyncness,
@@ -1394,7 +1414,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1394
1414
1395
1415
pub(super) fn lower_safety(&mut self, s: Safety, default: hir::Safety) -> hir::Safety {
1396
1416
match s {
1397
- Safety::Unsafe(_) => hir::Safety::Unsafe,
1417
+ Safety::Unsafe(_) => hir::Safety::Unsafe { target_feature: false } ,
1398
1418
Safety::Default => default,
1399
1419
Safety::Safe(_) => hir::Safety::Safe,
1400
1420
}
0 commit comments