1
Fork 0

New #[rustc_pub_transparent] attribute

This commit is contained in:
Pavel Grigorenko 2024-08-24 19:44:12 +03:00
commit b9033bdd92
11 changed files with 86 additions and 0 deletions

View file

@ -641,6 +641,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ErrorFollowing, EncodeCrossCrate::Yes, ErrorFollowing, EncodeCrossCrate::Yes,
"rustc_deprecated_safe_2024 is supposed to be used in libstd only", "rustc_deprecated_safe_2024 is supposed to be used in libstd only",
), ),
rustc_attr!(
rustc_pub_transparent, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes,
"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
),
// ========================================================================== // ==========================================================================

View file

@ -657,6 +657,10 @@ passes_rustc_lint_opt_ty =
`#[rustc_lint_opt_ty]` should be applied to a struct `#[rustc_lint_opt_ty]` should be applied to a struct
.label = not a struct .label = not a struct
passes_rustc_pub_transparent =
attribute should be applied to `#[repr(transparent)]` types
.label = not a `#[repr(transparent)]` type
passes_rustc_safe_intrinsic = passes_rustc_safe_intrinsic =
attribute should be applied to intrinsic functions attribute should be applied to intrinsic functions
.label = not an intrinsic function .label = not an intrinsic function

View file

@ -245,6 +245,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_coroutine(attr, target); self.check_coroutine(attr, target);
} }
[sym::linkage, ..] => self.check_linkage(attr, span, target), [sym::linkage, ..] => self.check_linkage(attr, span, target),
[sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent( attr.span, span, attrs),
[ [
// ok // ok
sym::allow sym::allow
@ -2381,6 +2382,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
} }
} }
fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) {
if !attrs
.iter()
.filter(|attr| attr.has_name(sym::repr))
.filter_map(|attr| attr.meta_item_list())
.flatten()
.any(|nmi| nmi.has_name(sym::transparent))
{
self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span });
}
}
} }
impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {

View file

@ -622,6 +622,15 @@ pub struct RustcStdInternalSymbol {
pub span: Span, pub span: Span,
} }
#[derive(Diagnostic)]
#[diag(passes_rustc_pub_transparent)]
pub struct RustcPubTransparent {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(passes_link_ordinal)] #[diag(passes_link_ordinal)]
pub struct LinkOrdinal { pub struct LinkOrdinal {

View file

@ -1672,6 +1672,7 @@ symbols! {
rustc_private, rustc_private,
rustc_proc_macro_decls, rustc_proc_macro_decls,
rustc_promotable, rustc_promotable,
rustc_pub_transparent,
rustc_reallocator, rustc_reallocator,
rustc_regions, rustc_regions,
rustc_reservation_impl, rustc_reservation_impl,

View file

@ -306,6 +306,7 @@ pub use once::OnceCell;
/// See the [module-level documentation](self) for more. /// See the [module-level documentation](self) for more.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
pub struct Cell<T: ?Sized> { pub struct Cell<T: ?Sized> {
value: UnsafeCell<T>, value: UnsafeCell<T>,
} }
@ -2055,6 +2056,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
#[lang = "unsafe_cell"] #[lang = "unsafe_cell"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
pub struct UnsafeCell<T: ?Sized> { pub struct UnsafeCell<T: ?Sized> {
value: T, value: T,
} }
@ -2297,6 +2299,7 @@ impl<T> UnsafeCell<*mut T> {
/// See [`UnsafeCell`] for details. /// See [`UnsafeCell`] for details.
#[unstable(feature = "sync_unsafe_cell", issue = "95439")] #[unstable(feature = "sync_unsafe_cell", issue = "95439")]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
pub struct SyncUnsafeCell<T: ?Sized> { pub struct SyncUnsafeCell<T: ?Sized> {
value: UnsafeCell<T>, value: UnsafeCell<T>,
} }

View file

@ -47,6 +47,7 @@ use crate::ptr;
#[lang = "manually_drop"] #[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
pub struct ManuallyDrop<T: ?Sized> { pub struct ManuallyDrop<T: ?Sized> {
value: T, value: T,
} }

View file

@ -237,6 +237,7 @@ use crate::{fmt, intrinsics, ptr, slice};
#[lang = "maybe_uninit"] #[lang = "maybe_uninit"]
#[derive(Copy)] #[derive(Copy)]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
pub union MaybeUninit<T> { pub union MaybeUninit<T> {
uninit: (), uninit: (),
value: ManuallyDrop<T>, value: ManuallyDrop<T>,

View file

@ -1084,6 +1084,7 @@ use crate::{cmp, fmt};
#[lang = "pin"] #[lang = "pin"]
#[fundamental] #[fundamental]
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Pin<Ptr> { pub struct Pin<Ptr> {
// FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to: // FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to:

View file

@ -0,0 +1,25 @@
#![feature(rustc_attrs, transparent_unions)]
#[rustc_pub_transparent]
#[repr(transparent)]
union E<T: Copy> {
value: T,
uninit: (),
}
#[repr(transparent)]
#[rustc_pub_transparent]
struct S<T>(T);
#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
#[repr(C)]
struct S1 {
A: u8,
}
#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
struct S2<T> {
value: T,
}
fn main() {}

View file

@ -0,0 +1,23 @@
error: attribute should be applied to `#[repr(transparent)]` types
--> $DIR/rustc_pub_transparent.rs:14:1
|
LL | #[rustc_pub_transparent]
| ^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[repr(C)]
LL | / struct S1 {
LL | | A: u8,
LL | | }
| |_- not a `#[repr(transparent)]` type
error: attribute should be applied to `#[repr(transparent)]` types
--> $DIR/rustc_pub_transparent.rs:20:1
|
LL | #[rustc_pub_transparent]
| ^^^^^^^^^^^^^^^^^^^^^^^^
LL | / struct S2<T> {
LL | | value: T,
LL | | }
| |_- not a `#[repr(transparent)]` type
error: aborting due to 2 previous errors