From 2a0d374608fc1c9c2da866f7d4c901708581aded Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sat, 29 Jun 2024 08:55:31 +0800 Subject: [PATCH] Add attr externally_constructed indicates pub struct with private fields could be constructed externally --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++ compiler/rustc_feature/src/unstable.rs | 3 ++ compiler/rustc_passes/src/dead.rs | 7 +++- compiler/rustc_span/src/symbol.rs | 2 + ...not-lint-structs-constructed-externally.rs | 41 +++++++++++++++++++ ...eature-gate-externally_constructed_attr.rs | 8 ++++ ...re-gate-externally_constructed_attr.stderr | 13 ++++++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 tests/ui/externally_constructed_attr/not-lint-structs-constructed-externally.rs create mode 100644 tests/ui/feature-gates/feature-gate-externally_constructed_attr.rs create mode 100644 tests/ui/feature-gates/feature-gate-externally_constructed_attr.stderr diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f884f99692779..04c9476449e1e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -432,6 +432,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No), ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes), + gated!( + externally_constructed, Normal, template!(Word), WarnFollowing, + EncodeCrossCrate::Yes, externally_constructed_attr, experimental!(mark_externally_constructed) + ), // Limits: ungated!( diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index ad6f7da893730..bd2836118ef58 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -463,6 +463,9 @@ declare_features! ( (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), /// Allows defining `extern type`s. (unstable, extern_types, "1.23.0", Some(43467)), + /// Allows `#[externally_constructed]` on pub structs with private fields, + /// indicates they will be contructed externally during dead code analysis. + (unstable, externally_constructed_attr, "CURRENT_RUSTC_VERSION", Some(126634)), /// Allow using 128-bit (quad precision) floating point numbers. (unstable, f128, "1.78.0", Some(116909)), /// Allow using 16-bit (half precision) floating point numbers. diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index bbd586386dd27..37748171562b8 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -930,8 +930,11 @@ fn create_and_seed_worklist( // checks impls, impl-items and pub structs with all public fields later 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::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() + || tcx.has_attr(id, sym::externally_constructed), _ => true }) .map(|id| (id, ComesFromAllowExpect::No)) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3b6147c4c0f64..c17300499bf27 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -809,6 +809,8 @@ symbols! { extern_types, external, external_doc, + externally_constructed, + externally_constructed_attr, f, f128, f128_nan, diff --git a/tests/ui/externally_constructed_attr/not-lint-structs-constructed-externally.rs b/tests/ui/externally_constructed_attr/not-lint-structs-constructed-externally.rs new file mode 100644 index 0000000000000..df8009b27e865 --- /dev/null +++ b/tests/ui/externally_constructed_attr/not-lint-structs-constructed-externally.rs @@ -0,0 +1,41 @@ +//@ check-pass +#![feature(externally_constructed_attr)] + +#[repr(C)] +#[externally_constructed] +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)] +#[externally_constructed] +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() {} diff --git a/tests/ui/feature-gates/feature-gate-externally_constructed_attr.rs b/tests/ui/feature-gates/feature-gate-externally_constructed_attr.rs new file mode 100644 index 0000000000000..48eb28a85fdfc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-externally_constructed_attr.rs @@ -0,0 +1,8 @@ +#[repr(C)] +#[externally_constructed] //~ ERROR the `#[mark_externally_constructed]` attribute is an experimental feature +pub struct Foo { + pub i: i16, + align: i16 +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-externally_constructed_attr.stderr b/tests/ui/feature-gates/feature-gate-externally_constructed_attr.stderr new file mode 100644 index 0000000000000..c91d9c1646195 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-externally_constructed_attr.stderr @@ -0,0 +1,13 @@ +error[E0658]: the `#[mark_externally_constructed]` attribute is an experimental feature + --> $DIR/feature-gate-externally_constructed_attr.rs:2:1 + | +LL | #[externally_constructed] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #126634 for more information + = help: add `#![feature(externally_constructed_attr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`.