Skip to content

Commit

Permalink
Add a new attr indicates pub struct with private fields could be cons…
Browse files Browse the repository at this point in the history
…tructed externally
  • Loading branch information
mu001999 committed Jun 14, 2024
1 parent 8cf5101 commit 0501766
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ 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),
ungated!(externally_constructed, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),

// Limits:
ungated!(
Expand Down
31 changes: 16 additions & 15 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,22 @@ fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
// treat PhantomData and positional ZST as public,
// we don't want to lint types which only have them,
// cause it's a common way to use such types to check things like well-formedness
tcx.adt_def(id).all_fields().all(|field| {
let field_type = tcx.type_of(field.did).instantiate_identity();
if field_type.is_phantom_data() {
return true;
}
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
if is_positional
&& tcx
.layout_of(tcx.param_env(field.did).and(field_type))
.map_or(true, |layout| layout.is_zst())
{
return true;
}
field.vis.is_public()
})
tcx.has_attr(id, sym::externally_constructed)
|| tcx.adt_def(id).all_fields().all(|field| {
let field_type = tcx.type_of(field.did).instantiate_identity();
if field_type.is_phantom_data() {
return true;
}
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
if is_positional
&& tcx
.layout_of(tcx.param_env(field.did).and(field_type))
.map_or(true, |layout| layout.is_zst())
{
return true;
}
field.vis.is_public()
})
}

/// check struct and its fields are public or not,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ symbols! {
extern_types,
external,
external_doc,
externally_constructed,
f,
f128,
f128_nan,
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/lint/dead-code/externally-constructed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@ check-pass

#[externally_constructed]
#[repr(C)]
pub struct Foo {
pub i: i16,
align: i16
}

fn main() {}

0 comments on commit 0501766

Please sign in to comment.