about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJakub Beránek <jakub.beranek@vsb.cz>2024-09-01 16:35:53 +0200
committerJakub Beránek <jakub.beranek@vsb.cz>2024-09-01 16:35:53 +0200
commit47e6b5deed5cc79c677def8d1a165658fa79d810 (patch)
treefe0d774466eaa37667d6fffbee6ab644854098cc /compiler
parent1a1cc050d8efc906ede39f444936ade1fdc9c6cb (diff)
downloadrust-47e6b5deed5cc79c677def8d1a165658fa79d810.tar.gz
rust-47e6b5deed5cc79c677def8d1a165658fa79d810.zip
Revert "Auto merge of #127537 - veluca93:struct_tf, r=BoxyUwU"
This reverts commit acb4e8b6251f1d8da36f08e7a70fa23fc581839e, reversing
changes made to 100fde5246bf56f22fb5cc85374dd841296fce0e.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs125
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/def.rs35
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_mir_build/messages.ftl16
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs46
-rw-r--r--compiler/rustc_mir_build/src/errors.rs35
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs33
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
19 files changed, 27 insertions, 308 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 209750d6ba6..4ab20c154cc 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,6 +1,5 @@
 use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
-use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{struct_span_code_err, DiagMessage, SubdiagMessage};
 use rustc_hir as hir;
@@ -9,7 +8,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
 use rustc_hir::{lang_items, LangItem};
 use rustc_middle::middle::codegen_fn_attrs::{
-    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, TargetFeature,
+    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
 };
 use rustc_middle::mir::mono::Linkage;
 use rustc_middle::query::Providers;
@@ -18,7 +17,6 @@ use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span};
-use rustc_target::abi::VariantIdx;
 use rustc_target::spec::{abi, SanitizerSet};
 
 use crate::errors;
@@ -80,13 +78,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     let mut link_ordinal_span = None;
     let mut no_sanitize_span = None;
 
-    let fn_sig_outer = || {
-        use DefKind::*;
-
-        let def_kind = tcx.def_kind(did);
-        if let Fn | AssocFn | Variant | Ctor(..) = def_kind { Some(tcx.fn_sig(did)) } else { None }
-    };
-
     for attr in attrs.iter() {
         // In some cases, attribute are only valid on functions, but it's the `check_attr`
         // pass that check that they aren't used anywhere else, rather this module.
@@ -94,12 +85,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         // functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
         // report a delayed bug, just in case `check_attr` isn't doing its job.
         let fn_sig = || {
-            let sig = fn_sig_outer();
-            if sig.is_none() {
+            use DefKind::*;
+
+            let def_kind = tcx.def_kind(did);
+            if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
+                Some(tcx.fn_sig(did))
+            } else {
                 tcx.dcx()
                     .span_delayed_bug(attr.span, "this attribute can only be applied to functions");
+                None
             }
-            sig
         };
 
         let Some(Ident { name, .. }) = attr.ident() else {
@@ -618,93 +613,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         }
     }
 
-    if let Some(sig) = fn_sig_outer() {
-        // Collect target features from types reachable from arguments.
-        // We define a type as "reachable" if:
-        //  - it is a function argument
-        //  - it is a field of a reachable struct
-        //  - there is a reachable reference to it
-        // FIXME(struct_target_features): we may want to cache the result of this computation.
-        let mut visited_types = FxHashSet::default();
-        let mut reachable_types: Vec<_> = sig.skip_binder().inputs().skip_binder().to_owned();
-        let mut additional_tf = vec![];
-
-        while let Some(ty) = reachable_types.pop() {
-            if visited_types.contains(&ty) {
-                continue;
-            }
-            visited_types.insert(ty);
-            match ty.kind() {
-                ty::Alias(..) => {
-                    if let Ok(t) =
-                        tcx.try_normalize_erasing_regions(tcx.param_env(did.to_def_id()), ty)
-                    {
-                        reachable_types.push(t)
-                    }
-                }
-
-                ty::Ref(_, inner, _) => reachable_types.push(*inner),
-                ty::Tuple(tys) => reachable_types.extend(tys.iter()),
-                ty::Adt(adt_def, args) => {
-                    additional_tf.extend_from_slice(tcx.struct_target_features(adt_def.did()));
-                    // This only recurses into structs as i.e. an Option<TargetFeature> is an ADT
-                    // that doesn't actually always contain a TargetFeature.
-                    if adt_def.is_struct() {
-                        reachable_types.extend(
-                            adt_def
-                                .variant(VariantIdx::from_usize(0))
-                                .fields
-                                .iter()
-                                .map(|field| field.ty(tcx, args)),
-                        );
-                    }
-                }
-                ty::Bool
-                | ty::Char
-                | ty::Int(..)
-                | ty::Uint(..)
-                | ty::Float(..)
-                | ty::Foreign(..)
-                | ty::Str
-                | ty::Array(..)
-                | ty::Pat(..)
-                | ty::Slice(..)
-                | ty::RawPtr(..)
-                | ty::FnDef(..)
-                | ty::FnPtr(..)
-                | ty::Dynamic(..)
-                | ty::Closure(..)
-                | ty::CoroutineClosure(..)
-                | ty::Coroutine(..)
-                | ty::CoroutineWitness(..)
-                | ty::Never
-                | ty::Param(..)
-                | ty::Bound(..)
-                | ty::Placeholder(..)
-                | ty::Infer(..)
-                | ty::Error(..) => (),
-            }
-        }
-
-        // FIXME(struct_target_features): is this really necessary?
-        if !additional_tf.is_empty() && sig.skip_binder().abi() != abi::Abi::Rust {
-            tcx.dcx().span_err(
-                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
-                "cannot use a struct with target features in a function with non-Rust ABI",
-            );
-        }
-        if !additional_tf.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
-            tcx.dcx().span_err(
-                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
-                "cannot use a struct with target features in a #[inline(always)] function",
-            );
-        }
-        codegen_fn_attrs
-            .target_features
-            .extend(additional_tf.iter().map(|tf| TargetFeature { implied: true, ..*tf }));
-    }
-
-    // If a function uses non-default target_features it can't be inlined into general
+    // If a function uses #[target_feature] it can't be inlined into general
     // purpose functions as they wouldn't have the right target features
     // enabled. For that reason we also forbid #[inline(always)] as it can't be
     // respected.
@@ -849,20 +758,6 @@ fn check_link_name_xor_ordinal(
     }
 }
 
-fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeature] {
-    let mut features = vec![];
-    let supported_features = tcx.supported_target_features(LOCAL_CRATE);
-    for attr in tcx.get_attrs(def_id, sym::target_feature) {
-        from_target_feature(tcx, attr, supported_features, &mut features);
-    }
-    tcx.arena.alloc_slice(&features)
-}
-
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        codegen_fn_attrs,
-        should_inherit_track_caller,
-        struct_target_features,
-        ..*providers
-    };
+    *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
 }
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 7ea037ca8b2..ffeaa861220 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -597,8 +597,6 @@ declare_features! (
     (unstable, strict_provenance, "1.61.0", Some(95228)),
     /// Allows string patterns to dereference values to match them.
     (unstable, string_deref_patterns, "1.67.0", Some(87121)),
-    /// Allows structs to carry target_feature information.
-    (incomplete, struct_target_features, "CURRENT_RUSTC_VERSION", Some(129107)),
     /// Allows the use of `#[target_feature]` on safe functions.
     (unstable, target_feature_11, "1.45.0", Some(69098)),
     /// Allows using `#[thread_local]` on `static` items.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index c5dc4dacab6..bd55617d84e 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -326,41 +326,6 @@ impl DefKind {
             | DefKind::ExternCrate => false,
         }
     }
-
-    /// Whether `query struct_target_features` should be used with this definition.
-    pub fn has_struct_target_features(self) -> bool {
-        match self {
-            DefKind::Struct | DefKind::Union | DefKind::Enum => true,
-            DefKind::Fn
-            | DefKind::AssocFn
-            | DefKind::Ctor(..)
-            | DefKind::Closure
-            | DefKind::Static { .. }
-            | DefKind::Mod
-            | DefKind::Variant
-            | DefKind::Trait
-            | DefKind::TyAlias
-            | DefKind::ForeignTy
-            | DefKind::TraitAlias
-            | DefKind::AssocTy
-            | DefKind::Const
-            | DefKind::AssocConst
-            | DefKind::Macro(..)
-            | DefKind::Use
-            | DefKind::ForeignMod
-            | DefKind::OpaqueTy
-            | DefKind::Impl { .. }
-            | DefKind::Field
-            | DefKind::TyParam
-            | DefKind::ConstParam
-            | DefKind::LifetimeParam
-            | DefKind::AnonConst
-            | DefKind::InlineConst
-            | DefKind::SyntheticCoroutineBody
-            | DefKind::GlobalAsm
-            | DefKind::ExternCrate => false,
-        }
-    }
 }
 
 /// The resolution of a path or export.
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 865e9be0a67..d97c590bd41 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -851,8 +851,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     }
 
                     // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
-                    // FIXME(struct_target_features): should this be true also for functions that inherit
-                    // target features from structs?
 
                     if b_hdr.safety == hir::Safety::Safe
                         && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index a82340e3d61..0f46cacc27a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -254,7 +254,6 @@ provide! { tcx, def_id, other, cdata,
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
-    struct_target_features => { table }
     impl_trait_header => { table }
     const_param_default => { table }
     object_lifetime_default => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 919623cff60..88256c4db04 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1392,9 +1392,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if def_kind.has_codegen_attrs() {
                 record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
             }
-            if def_kind.has_struct_target_features() {
-                record_array!(self.tables.struct_target_features[def_id] <- self.tcx.struct_target_features(def_id));
-            }
             if should_encode_visibility(def_kind) {
                 let vis =
                     self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 987ee3f07e9..a84923130c3 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -19,7 +19,7 @@ use rustc_macros::{
     Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable,
 };
 use rustc_middle::metadata::ModChild;
-use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::middle::lib_features::FeatureStability;
@@ -427,7 +427,6 @@ define_tables! {
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
-    struct_target_features: Table<DefIndex, LazyArray<TargetFeature>>,
     impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
     const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>>>,
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index c098a739592..b7d290e58d2 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -26,8 +26,8 @@ pub struct CodegenFnAttrs {
     /// be set when `link_name` is set. This is for foreign items with the
     /// "raw-dylib" kind.
     pub link_ordinal: Option<u16>,
-    /// All the target features that are enabled for this function. Some features might be enabled
-    /// implicitly.
+    /// The `#[target_feature(enable = "...")]` attribute and the enabled
+    /// features (only enabled features are supported right now).
     pub target_features: Vec<TargetFeature>,
     /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
     pub linkage: Option<Linkage>,
@@ -55,8 +55,8 @@ pub struct CodegenFnAttrs {
 pub struct TargetFeature {
     /// The name of the target feature (e.g. "avx")
     pub name: Symbol,
-    /// The feature is implied by another feature or by an argument, rather than explicitly
-    /// added by the `#[target_feature]` attribute
+    /// The feature is implied by another feature, rather than explicitly added by the
+    /// `#[target_feature]` attribute
     pub implied: bool,
 }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b6443778c93..d6bdc1af0d2 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -47,7 +47,7 @@ use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintExpectation;
 use crate::metadata::ModChild;
-use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
+use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use crate::middle::lib_features::LibFeatures;
@@ -1249,11 +1249,6 @@ rustc_queries! {
         feedable
     }
 
-    query struct_target_features(def_id: DefId) -> &'tcx [TargetFeature] {
-        separate_provide_extern
-        desc { |tcx| "computing target features for struct `{}`", tcx.def_path_str(def_id) }
-    }
-
     query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
         desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
     }
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index be611e19b49..7e1255f606c 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -59,7 +59,6 @@ trivially_parameterized_over_tcx! {
     std::string::String,
     crate::metadata::ModChild,
     crate::middle::codegen_fn_attrs::CodegenFnAttrs,
-    crate::middle::codegen_fn_attrs::TargetFeature,
     crate::middle::debugger_visualizer::DebuggerVisualizerFile,
     crate::middle::exported_symbols::SymbolExportInfo,
     crate::middle::lib_features::FeatureStability,
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index a42e8ff0168..7a10e627ccd 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -125,17 +125,6 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
-mir_build_initializing_type_with_target_feature_requires_unsafe =
-    initializing type with `target_feature` attr is unsafe and requires unsafe block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
-mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
-    initializing type with `target_feature` attr is unsafe and requires unsafe function or block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
-
 mir_build_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
@@ -398,11 +387,6 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
-mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe =
-    initializing type with `target_feature` attr is unsafe and requires unsafe block
-    .note = this struct can only be constructed if the corresponding `target_feature`s are available
-    .label = initializing type with `target_feature` attr
-
 mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 4ce796cea7a..c7fcfe3ce2a 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -461,18 +461,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     };
                     self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
                 } else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
-                    // If the called function has explicit target features the calling function hasn't,
+                    // If the called function has target features the calling function hasn't,
                     // the call requires `unsafe`. Don't check this on wasm
                     // targets, though. For more information on wasm see the
                     // is_like_wasm check in hir_analysis/src/collect.rs
-                    // Implicit target features are OK because they are either a consequence of some
-                    // explicit target feature (which is checked to be present in the caller) or
-                    // come from a witness argument.
                     let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
                     if !self.tcx.sess.target.options.is_like_wasm
                         && !callee_features.iter().all(|feature| {
-                            feature.implied
-                                || self.body_target_features.iter().any(|f| f.name == feature.name)
+                            self.body_target_features.iter().any(|f| f.name == feature.name)
                         })
                     {
                         let missing: Vec<_> = callee_features
@@ -546,16 +542,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => {
-                match self.tcx.layout_scalar_valid_range(adt_def.did()) {
-                    (Bound::Unbounded, Bound::Unbounded) => {}
-                    _ => self.requires_unsafe(expr.span, InitializingTypeWith),
-                }
-                if !self.tcx.struct_target_features(adt_def.did()).is_empty() {
-                    self.requires_unsafe(expr.span, ConstructingTargetFeaturesType)
-                }
-            }
-
+            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
+                (Bound::Unbounded, Bound::Unbounded) => {}
+                _ => self.requires_unsafe(expr.span, InitializingTypeWith),
+            },
             ExprKind::Closure(box ClosureExpr {
                 closure_id,
                 args: _,
@@ -657,7 +647,6 @@ enum UnsafeOpKind {
     CallToUnsafeFunction(Option<DefId>),
     UseOfInlineAssembly,
     InitializingTypeWith,
-    ConstructingTargetFeaturesType,
     UseOfMutableStatic,
     UseOfExternStatic,
     DerefOfRawPointer,
@@ -739,15 +728,6 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
-            ConstructingTargetFeaturesType => tcx.emit_node_span_lint(
-                UNSAFE_OP_IN_UNSAFE_FN,
-                hir_id,
-                span,
-                UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
-                    span,
-                    unsafe_not_inherited_note,
-                },
-            ),
             UseOfMutableStatic => tcx.emit_node_span_lint(
                 UNSAFE_OP_IN_UNSAFE_FN,
                 hir_id,
@@ -905,20 +885,6 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 });
             }
-            ConstructingTargetFeaturesType if unsafe_op_in_unsafe_fn_allowed => {
-                dcx.emit_err(
-                    InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
-                        span,
-                        unsafe_not_inherited_note,
-                    },
-                );
-            }
-            ConstructingTargetFeaturesType => {
-                dcx.emit_err(InitializingTypeWithTargetFeatureRequiresUnsafe {
-                    span,
-                    unsafe_not_inherited_note,
-                });
-            }
             UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
                 dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index e7d6239aa9b..7f9eefd1d52 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -87,16 +87,6 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
-#[note]
-pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
@@ -261,17 +251,6 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
-#[note]
-pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafe {
-    #[primary_span]
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
-}
-
-#[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
     code = E0133
@@ -286,20 +265,6 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(
-    mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = E0133
-)]
-#[note]
-pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
-    #[primary_span]
-    #[label]
-    pub(crate) span: Span,
-    #[subdiagnostic]
-    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
-}
-
-#[derive(Diagnostic)]
 #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UseOfMutableStaticRequiresUnsafe {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 38450fc288a..e7f208d5ad5 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -672,10 +672,6 @@ passes_should_be_applied_to_fn =
         *[false] not a function definition
     }
 
-passes_should_be_applied_to_fn_or_unit_struct =
-    attribute should be applied to a function definition or unit struct
-    .label = not a function definition or a unit struct
-
 passes_should_be_applied_to_static =
     attribute should be applied to a static
     .label = not a static
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5dbb3854c8f..21478a44b0e 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -747,35 +747,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             Target::Field | Target::Arm | Target::MacroDef => {
                 self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
             }
-            Target::Struct if self.tcx.features().struct_target_features => {
-                let ty = self.tcx.hir_node(hir_id).expect_item();
-                match ty.kind {
-                    ItemKind::Struct(data, _) => {
-                        if data.fields().len() != 0 {
-                            self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
-                                attr_span: attr.span,
-                                defn_span: span,
-                            });
-                        }
-                    }
-                    _ => {
-                        panic!("Target::Struct for a non-struct");
-                    }
-                }
-            }
             _ => {
-                if self.tcx.features().struct_target_features {
-                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
-                        attr_span: attr.span,
-                        defn_span: span,
-                    });
-                } else {
-                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                        attr_span: attr.span,
-                        defn_span: span,
-                        on_crate: hir_id == CRATE_HIR_ID,
-                    });
-                }
+                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
+                    attr_span: attr.span,
+                    defn_span: span,
+                    on_crate: hir_id == CRATE_HIR_ID,
+                });
             }
         }
     }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 1e9ab7af9be..f5d982e1a5c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -83,15 +83,6 @@ pub(crate) struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_fn_or_unit_struct)]
-pub(crate) struct AttrShouldBeAppliedToFnOrUnitStruct {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn, code = E0739)]
 pub(crate) struct TrackedCallerWrongLocation {
     #[primary_span]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 16f5e55835e..34765209605 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1858,7 +1858,6 @@ symbols! {
         stringify,
         struct_field_attributes,
         struct_inherit,
-        struct_target_features,
         struct_variant,
         structural_match,
         structural_peq,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 3fdfca50dce..effd9f8cb0c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -439,8 +439,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let is_target_feature_fn = if let ty::FnDef(def_id, _) =
                             *leaf_trait_ref.skip_binder().self_ty().kind()
                         {
-                            // FIXME(struct_target_features): should a function that inherits
-                            // target_features through arguments implement Fn traits?
                             !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                         } else {
                             false
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 7895a420476..96faa5236b1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -546,8 +546,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
             ty::FnDef(def_id, args) => {
                 let tcx = self.tcx();
-                // FIXME(struct_target_features): should a function that inherits target_features
-                // through an argument implement Fn traits?
                 if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
                     && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                 {