From b925ac9482fc3bc4057d9e9891eb1600dd04bbc0 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sat, 29 Jun 2024 08:03:47 +0800 Subject: [PATCH] Skip pub structs with repr(c) and repr(transparent) in dead code analysis --- compiler/rustc_passes/src/dead.rs | 5 ++- ...not-lint-structs-constructed-externally.rs | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/dead-code/not-lint-structs-constructed-externally.rs diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index bbd586386dd27..190ee0dc1b99a 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -931,7 +931,10 @@ fn create_and_seed_worklist( match tcx.def_kind(id) { DefKind::Impl { .. } => false, DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer), - DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(), + DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some() || { + let def = tcx.adt_def(id); + def.repr().c() || def.repr().transparent() + }, _ => true }) .map(|id| (id, ComesFromAllowExpect::No)) diff --git a/tests/ui/lint/dead-code/not-lint-structs-constructed-externally.rs b/tests/ui/lint/dead-code/not-lint-structs-constructed-externally.rs new file mode 100644 index 0000000000000..06ff750f2903e --- /dev/null +++ b/tests/ui/lint/dead-code/not-lint-structs-constructed-externally.rs @@ -0,0 +1,39 @@ +//@ check-pass +#![deny(dead_code)] + +#[repr(C)] +pub struct Foo { + pub i: i16, + align: i16 +} + +mod ffi { + use super::*; + + extern "C" { + pub fn DomPromise_AddRef(promise: *const Promise); + pub fn DomPromise_Release(promise: *const Promise); + } +} + +#[repr(C)] +pub struct Promise { + private: [u8; 0], + __nosync: ::std::marker::PhantomData<::std::rc::Rc>, +} + +pub unsafe trait RefCounted { + unsafe fn addref(&self); + unsafe fn release(&self); +} + +unsafe impl RefCounted for Promise { + unsafe fn addref(&self) { + ffi::DomPromise_AddRef(self) + } + unsafe fn release(&self) { + ffi::DomPromise_Release(self) + } +} + +fn main() {}