diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 2cb3c5d8965c8..d849305d99636 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -898,7 +898,7 @@ fn create_and_seed_worklist( match tcx.def_kind(id) { DefKind::Impl { .. } => false, DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer), - DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()), + DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(), _ => true }) .map(|id| (id, ComesFromAllowExpect::No)) diff --git a/tests/ui/lint/dead-code/allow-unconstructed-pub-struct.rs b/tests/ui/lint/dead-code/allow-unconstructed-pub-struct.rs new file mode 100644 index 0000000000000..8cd1524045b15 --- /dev/null +++ b/tests/ui/lint/dead-code/allow-unconstructed-pub-struct.rs @@ -0,0 +1,33 @@ +//@ check-pass + +mod ffi { + use super::*; + + extern "C" { + pub fn DomPromise_AddRef(promise: *const Promise); + pub fn DomPromise_Release(promise: *const Promise); + } +} + +#[repr(C)] +#[allow(unused)] +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() {}