diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 36e29d2dcb2cc..b37051ffc540c 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -330,8 +330,10 @@ impl DefKind { /// 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::Struct => true, DefKind::Fn + | DefKind::Union + | DefKind::Enum | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 27625f791082d..804fbc1ba5efa 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -224,7 +224,7 @@ provide! { tcx, def_id, other, cdata, variances_of => { table } fn_sig => { table } codegen_fn_attrs => { table } - struct_target_features => { table } + struct_target_features => { table_defaulted_array } 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 fbcfbd3befa94..f7b16e13af8a6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1393,7 +1393,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { 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)); + let struct_target_features = self.tcx.struct_target_features(def_id); + if !struct_target_features.is_empty() { + record_defaulted_array!(self.tables.struct_target_features[def_id] <- struct_target_features); + } } if should_encode_visibility(def_kind) { let vis = diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index aec728d42624d..39418ffca700a 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -402,6 +402,7 @@ define_tables! { // individually instead of `DefId`s. module_children_reexports: Table>, cross_crate_inlinable: Table, + struct_target_features: Table>, - optional: attributes: Table>, @@ -427,7 +428,6 @@ define_tables! { 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/tests/ui/target-feature/auxiliary/struct-target-features-crate-dep.rs b/tests/ui/target-feature/auxiliary/struct-target-features-crate-dep.rs new file mode 100644 index 0000000000000..2c5ab9503b0d7 --- /dev/null +++ b/tests/ui/target-feature/auxiliary/struct-target-features-crate-dep.rs @@ -0,0 +1,6 @@ +#![feature(struct_target_features)] + +#[target_feature(enable = "avx")] +pub struct Avx {} + +pub struct NoFeatures {} diff --git a/tests/ui/target-feature/struct-target-features-crate.rs b/tests/ui/target-feature/struct-target-features-crate.rs new file mode 100644 index 0000000000000..84bc02b927939 --- /dev/null +++ b/tests/ui/target-feature/struct-target-features-crate.rs @@ -0,0 +1,23 @@ +//@ only-x86_64 +//@ aux-build: struct-target-features-crate-dep.rs +//@ check-pass +#![feature(target_feature_11)] + +extern crate struct_target_features_crate_dep; + +#[target_feature(enable = "avx")] +fn avx() {} + +fn f(_: struct_target_features_crate_dep::Avx) { + avx(); +} + +fn g(_: struct_target_features_crate_dep::NoFeatures) {} + +fn main() { + if is_x86_feature_detected!("avx") { + let avx = unsafe { struct_target_features_crate_dep::Avx {} }; + f(avx); + } + g(struct_target_features_crate_dep::NoFeatures {}); +}