diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 9422a5944881a..d7f17ac4547ab 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -57,7 +57,7 @@ struct MarkSymbolVisitor<'tcx> { tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, live_symbols: LocalDefIdSet, - repr_has_repr_c: bool, + repr_unconditionally_treats_fields_as_live: bool, repr_has_repr_simd: bool, in_pat: bool, ignore_variant_stack: Vec, @@ -365,15 +365,17 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { return; } - let had_repr_c = self.repr_has_repr_c; + let unconditionally_treated_fields_as_live = + self.repr_unconditionally_treats_fields_as_live; let had_repr_simd = self.repr_has_repr_simd; - self.repr_has_repr_c = false; + self.repr_unconditionally_treats_fields_as_live = false; self.repr_has_repr_simd = false; match node { Node::Item(item) => match item.kind { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { let def = self.tcx.adt_def(item.owner_id); - self.repr_has_repr_c = def.repr().c(); + self.repr_unconditionally_treats_fields_as_live = + def.repr().c() || def.repr().transparent(); self.repr_has_repr_simd = def.repr().simd(); intravisit::walk_item(self, item) @@ -411,7 +413,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { _ => {} } self.repr_has_repr_simd = had_repr_simd; - self.repr_has_repr_c = had_repr_c; + self.repr_unconditionally_treats_fields_as_live = unconditionally_treated_fields_as_live; } fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) { @@ -435,11 +437,11 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { fn visit_variant_data(&mut self, def: &'tcx hir::VariantData<'tcx>) { let tcx = self.tcx; - let has_repr_c = self.repr_has_repr_c; + let unconditionally_treat_fields_as_live = self.repr_unconditionally_treats_fields_as_live; let has_repr_simd = self.repr_has_repr_simd; let live_fields = def.fields().iter().filter_map(|f| { let def_id = f.def_id; - if has_repr_c || (f.is_positional() && has_repr_simd) { + if unconditionally_treat_fields_as_live || (f.is_positional() && has_repr_simd) { return Some(def_id); } if !tcx.visibility(f.hir_id.owner.def_id).is_public() { @@ -741,7 +743,7 @@ fn live_symbols_and_ignored_derived_traits( tcx, maybe_typeck_results: None, live_symbols: Default::default(), - repr_has_repr_c: false, + repr_unconditionally_treats_fields_as_live: false, repr_has_repr_simd: false, in_pat: false, ignore_variant_stack: vec![], diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 9463b73b574f9..f83c8f83cc989 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -171,7 +171,6 @@ struct WithHeader(NonNull, PhantomData); /// An opaque representation of `WithHeader` to avoid the /// projection invariance of `::Metadata`. #[repr(transparent)] -#[allow(dead_code)] // Field only used through `WithHeader` type above. struct WithOpaqueHeader(NonNull); impl WithOpaqueHeader { diff --git a/src/tools/miri/tests/fail/issue-miri-1112.rs b/src/tools/miri/tests/fail/issue-miri-1112.rs index 9542673b0d9e1..387253a3f9872 100644 --- a/src/tools/miri/tests/fail/issue-miri-1112.rs +++ b/src/tools/miri/tests/fail/issue-miri-1112.rs @@ -1,7 +1,7 @@ trait Empty {} #[repr(transparent)] -pub struct FunnyPointer(#[allow(dead_code)] dyn Empty); +pub struct FunnyPointer(dyn Empty); #[repr(C)] pub struct Meta { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs index 2283231eb010c..d71d5954a40c7 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -1,7 +1,7 @@ //@compile-flags: -Cdebug-assertions=no #[repr(transparent)] -struct HasDrop(#[allow(dead_code)] u8); +struct HasDrop(u8); impl Drop for HasDrop { fn drop(&mut self) {} diff --git a/tests/ui/consts/transmute-const.rs b/tests/ui/consts/transmute-const.rs index 65e5700d083f6..5044d99ec5183 100644 --- a/tests/ui/consts/transmute-const.rs +++ b/tests/ui/consts/transmute-const.rs @@ -3,7 +3,7 @@ use std::mem; #[repr(transparent)] -struct Foo(#[allow(dead_code)] u32); +struct Foo(u32); const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) }; diff --git a/tests/ui/layout/unsafe-cell-hides-niche.rs b/tests/ui/layout/unsafe-cell-hides-niche.rs index 8d6cea1093363..e87c402f8f964 100644 --- a/tests/ui/layout/unsafe-cell-hides-niche.rs +++ b/tests/ui/layout/unsafe-cell-hides-niche.rs @@ -17,7 +17,7 @@ use std::sync::{Mutex, RwLock}; struct Wrapper(#[allow(dead_code)] T); #[repr(transparent)] -struct Transparent(#[allow(dead_code)] T); +struct Transparent(T); struct NoNiche(UnsafeCell); diff --git a/tests/ui/lint/dead-code/type-in-transparent.rs b/tests/ui/lint/dead-code/type-in-transparent.rs new file mode 100644 index 0000000000000..5dd6f93fd0318 --- /dev/null +++ b/tests/ui/lint/dead-code/type-in-transparent.rs @@ -0,0 +1,14 @@ +// Verify that we do not warn on fields that are part of transparent types. +// check-pass +#![deny(dead_code)] + +#[repr(transparent)] +struct NamedStruct { field: u8 } + +#[repr(transparent)] +struct TupleStruct(u8); + +fn main() { + let _ = NamedStruct { field: 1 }; + let _ = TupleStruct(1); +} diff --git a/tests/ui/packed/packed-struct-drop-aligned.rs b/tests/ui/packed/packed-struct-drop-aligned.rs index 6c2907c86e913..ddfc86f74d3c7 100644 --- a/tests/ui/packed/packed-struct-drop-aligned.rs +++ b/tests/ui/packed/packed-struct-drop-aligned.rs @@ -24,7 +24,7 @@ impl<'a> Drop for Aligned<'a> { } #[repr(transparent)] -struct NotCopy(#[allow(dead_code)] u8); +struct NotCopy(u8); #[repr(packed)] struct Packed<'a>(NotCopy, Aligned<'a>);