Skip to content

Commit

Permalink
Rollup merge of rust-lang#120107 - shepmaster:dead-code-repr-transpar…
Browse files Browse the repository at this point in the history
…ent, r=Nilstrieb

dead_code treats #[repr(transparent)] the same as #[repr(C)]

In rust-lang#92972 we enabled linting on unused fields in tuple structs. In rust-lang#118297 that lint was enabled by default. That exposed issues like rust-lang#119659, where the fields of a struct marked `#[repr(transparent)]` were reported by the `dead_code` lint. The language team [decided](rust-lang#119659 (comment)) that the lint should treat `repr(transparent)` the same as `#[repr(C)]`.

Fixes rust-lang#119659
  • Loading branch information
matthiaskrgr authored Jan 19, 2024
2 parents 987445c + aeeaed9 commit 332f8f7
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 14 deletions.
18 changes: 10 additions & 8 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DefId>,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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<'_>]) {
Expand All @@ -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() {
Expand Down Expand Up @@ -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![],
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/boxed/thin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ struct WithHeader<H>(NonNull<u8>, PhantomData<H>);
/// An opaque representation of `WithHeader<H>` to avoid the
/// projection invariance of `<T as Pointee>::Metadata`.
#[repr(transparent)]
#[allow(dead_code)] // Field only used through `WithHeader` type above.
struct WithOpaqueHeader(NonNull<u8>);

impl WithOpaqueHeader {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/issue-miri-1112.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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) {}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/consts/transmute-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) };

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/layout/unsafe-cell-hides-niche.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::sync::{Mutex, RwLock};
struct Wrapper<T>(#[allow(dead_code)] T);

#[repr(transparent)]
struct Transparent<T>(#[allow(dead_code)] T);
struct Transparent<T>(T);

struct NoNiche<T>(UnsafeCell<T>);

Expand Down
14 changes: 14 additions & 0 deletions tests/ui/lint/dead-code/type-in-transparent.rs
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 1 addition & 1 deletion tests/ui/packed/packed-struct-drop-aligned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>);
Expand Down

0 comments on commit 332f8f7

Please sign in to comment.