@@ -110,7 +110,7 @@ impl CheckAttrVisitor<'_> {
110
110
sym:: coverage => self . check_coverage ( hir_id, attr, span, target) ,
111
111
sym:: non_exhaustive => self . check_non_exhaustive ( hir_id, attr, span, target) ,
112
112
sym:: marker => self . check_marker ( hir_id, attr, span, target) ,
113
- sym:: target_feature => self . check_target_feature ( hir_id, attr, span, target) ,
113
+ sym:: target_feature => self . check_target_feature ( hir_id, attr, span, target, attrs ) ,
114
114
sym:: thread_local => self . check_thread_local ( attr, span, target) ,
115
115
sym:: track_caller => {
116
116
self . check_track_caller ( hir_id, attr. span , attrs, span, target)
@@ -571,10 +571,36 @@ impl CheckAttrVisitor<'_> {
571
571
attr : & Attribute ,
572
572
span : Span ,
573
573
target : Target ,
574
+ attrs : & [ Attribute ] ,
574
575
) -> bool {
575
576
match target {
576
- Target :: Fn
577
- | Target :: Method ( MethodKind :: Trait { body : true } | MethodKind :: Inherent ) => true ,
577
+ Target :: Fn => {
578
+ // `#[target_feature]` is not allowed in language items.
579
+ if let Some ( ( lang_item, _) ) = hir:: lang_items:: extract ( attrs)
580
+ // Calling functions with `#[target_feature]` is
581
+ // not unsafe on WASM, see #84988
582
+ && !self . tcx . sess . target . is_like_wasm
583
+ && !self . tcx . sess . opts . actually_rustdoc
584
+ {
585
+ let hir:: Node :: Item ( item) = self . tcx . hir ( ) . get ( hir_id) else {
586
+ unreachable ! ( ) ;
587
+ } ;
588
+ let hir:: ItemKind :: Fn ( sig, _, _) = item. kind else {
589
+ // target is `Fn`
590
+ unreachable ! ( ) ;
591
+ } ;
592
+
593
+ self . tcx . sess . emit_err ( errors:: LangItemWithTargetFeature {
594
+ attr_span : attr. span ,
595
+ name : lang_item,
596
+ sig_span : sig. span ,
597
+ } ) ;
598
+ false
599
+ } else {
600
+ true
601
+ }
602
+ }
603
+ Target :: Method ( MethodKind :: Trait { body : true } | MethodKind :: Inherent ) => true ,
578
604
// FIXME: #[target_feature] was previously erroneously allowed on statements and some
579
605
// crates used this, so only emit a warning.
580
606
Target :: Statement => {
0 commit comments