Skip to content

Commit 9c59e97

Browse files
authored
Rollup merge of rust-lang#129487 - GrigorenkoPV:repr_transparent_external_private_fields, r=compiler-errors
repr_transparent_external_private_fields: special-case some std types Fixes rust-lang#129470 ```@rustbot``` label +A-lint +L-repr_transparent_external_private_fields
2 parents a44e5a9 + 06f2d73 commit 9c59e97

File tree

13 files changed

+113
-1
lines changed

13 files changed

+113
-1
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+5
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
641641
ErrorFollowing, EncodeCrossCrate::Yes,
642642
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
643643
),
644+
rustc_attr!(
645+
rustc_pub_transparent, Normal, template!(Word),
646+
WarnFollowing, EncodeCrossCrate::Yes,
647+
"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
648+
),
644649

645650

646651
// ==========================================================================

compiler/rustc_hir_analysis/src/check/check.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
12591259
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
12601260
ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
12611261
ty::Adt(def, args) => {
1262-
if !def.did().is_local() {
1262+
if !def.did().is_local() && !tcx.has_attr(def.did(), sym::rustc_pub_transparent)
1263+
{
12631264
let non_exhaustive = def.is_variant_list_non_exhaustive()
12641265
|| def
12651266
.variants()

compiler/rustc_passes/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,10 @@ passes_rustc_lint_opt_ty =
657657
`#[rustc_lint_opt_ty]` should be applied to a struct
658658
.label = not a struct
659659
660+
passes_rustc_pub_transparent =
661+
attribute should be applied to `#[repr(transparent)]` types
662+
.label = not a `#[repr(transparent)]` type
663+
660664
passes_rustc_safe_intrinsic =
661665
attribute should be applied to intrinsic functions
662666
.label = not an intrinsic function

compiler/rustc_passes/src/check_attr.rs

+13
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
245245
self.check_coroutine(attr, target);
246246
}
247247
[sym::linkage, ..] => self.check_linkage(attr, span, target),
248+
[sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent( attr.span, span, attrs),
248249
[
249250
// ok
250251
sym::allow
@@ -2381,6 +2382,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23812382
}
23822383
}
23832384
}
2385+
2386+
fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) {
2387+
if !attrs
2388+
.iter()
2389+
.filter(|attr| attr.has_name(sym::repr))
2390+
.filter_map(|attr| attr.meta_item_list())
2391+
.flatten()
2392+
.any(|nmi| nmi.has_name(sym::transparent))
2393+
{
2394+
self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span });
2395+
}
2396+
}
23842397
}
23852398

23862399
impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {

compiler/rustc_passes/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,15 @@ pub struct RustcStdInternalSymbol {
622622
pub span: Span,
623623
}
624624

625+
#[derive(Diagnostic)]
626+
#[diag(passes_rustc_pub_transparent)]
627+
pub struct RustcPubTransparent {
628+
#[primary_span]
629+
pub attr_span: Span,
630+
#[label]
631+
pub span: Span,
632+
}
633+
625634
#[derive(Diagnostic)]
626635
#[diag(passes_link_ordinal)]
627636
pub struct LinkOrdinal {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,7 @@ symbols! {
16741674
rustc_private,
16751675
rustc_proc_macro_decls,
16761676
rustc_promotable,
1677+
rustc_pub_transparent,
16771678
rustc_reallocator,
16781679
rustc_regions,
16791680
rustc_reservation_impl,

library/core/src/cell.rs

+3
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub use once::OnceCell;
306306
/// See the [module-level documentation](self) for more.
307307
#[stable(feature = "rust1", since = "1.0.0")]
308308
#[repr(transparent)]
309+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
309310
pub struct Cell<T: ?Sized> {
310311
value: UnsafeCell<T>,
311312
}
@@ -2055,6 +2056,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
20552056
#[lang = "unsafe_cell"]
20562057
#[stable(feature = "rust1", since = "1.0.0")]
20572058
#[repr(transparent)]
2059+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
20582060
pub struct UnsafeCell<T: ?Sized> {
20592061
value: T,
20602062
}
@@ -2297,6 +2299,7 @@ impl<T> UnsafeCell<*mut T> {
22972299
/// See [`UnsafeCell`] for details.
22982300
#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
22992301
#[repr(transparent)]
2302+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
23002303
pub struct SyncUnsafeCell<T: ?Sized> {
23012304
value: UnsafeCell<T>,
23022305
}

library/core/src/mem/manually_drop.rs

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use crate::ptr;
4747
#[lang = "manually_drop"]
4848
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4949
#[repr(transparent)]
50+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
5051
pub struct ManuallyDrop<T: ?Sized> {
5152
value: T,
5253
}

library/core/src/mem/maybe_uninit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ use crate::{fmt, intrinsics, ptr, slice};
237237
#[lang = "maybe_uninit"]
238238
#[derive(Copy)]
239239
#[repr(transparent)]
240+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
240241
pub union MaybeUninit<T> {
241242
uninit: (),
242243
value: ManuallyDrop<T>,

library/core/src/pin.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ use crate::{cmp, fmt};
10841084
#[lang = "pin"]
10851085
#[fundamental]
10861086
#[repr(transparent)]
1087+
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
10871088
#[derive(Copy, Clone)]
10881089
pub struct Pin<Ptr> {
10891090
// FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(rustc_attrs, transparent_unions)]
2+
3+
#[rustc_pub_transparent]
4+
#[repr(transparent)]
5+
union E<T: Copy> {
6+
value: T,
7+
uninit: (),
8+
}
9+
10+
#[repr(transparent)]
11+
#[rustc_pub_transparent]
12+
struct S<T>(T);
13+
14+
#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
15+
#[repr(C)]
16+
struct S1 {
17+
A: u8,
18+
}
19+
20+
#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
21+
struct S2<T> {
22+
value: T,
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error: attribute should be applied to `#[repr(transparent)]` types
2+
--> $DIR/rustc_pub_transparent.rs:14:1
3+
|
4+
LL | #[rustc_pub_transparent]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
LL | #[repr(C)]
7+
LL | / struct S1 {
8+
LL | | A: u8,
9+
LL | | }
10+
| |_- not a `#[repr(transparent)]` type
11+
12+
error: attribute should be applied to `#[repr(transparent)]` types
13+
--> $DIR/rustc_pub_transparent.rs:20:1
14+
|
15+
LL | #[rustc_pub_transparent]
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^
17+
LL | / struct S2<T> {
18+
LL | | value: T,
19+
LL | | }
20+
| |_- not a `#[repr(transparent)]` type
21+
22+
error: aborting due to 2 previous errors
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ check-pass
2+
3+
#![feature(sync_unsafe_cell)]
4+
#![allow(unused)]
5+
#![deny(repr_transparent_external_private_fields)]
6+
7+
// https://github.com/rust-lang/rust/issues/129470
8+
9+
struct ZST;
10+
11+
#[repr(transparent)]
12+
struct TransparentWithManuallyDropZST {
13+
value: i32,
14+
md: std::mem::ManuallyDrop<ZST>,
15+
mu: std::mem::MaybeUninit<ZST>,
16+
p: std::pin::Pin<ZST>,
17+
pd: std::marker::PhantomData<ZST>,
18+
pp: std::marker::PhantomPinned,
19+
c: std::cell::Cell<ZST>,
20+
uc: std::cell::UnsafeCell<ZST>,
21+
suc: std::cell::SyncUnsafeCell<ZST>,
22+
zst: ZST,
23+
}
24+
25+
fn main() {}

0 commit comments

Comments
 (0)