Rollup merge of #147185 - RalfJung:repr-c-not-zst, r=petrochenkov

repr(transparent): do not consider repr(C) types to be 1-ZST

Context: https://github.com/rust-lang/unsafe-code-guidelines/issues/552

This experiments with a [suggestion](https://github.com/rust-lang/rfcs/pull/3845#discussion_r2388463698) by ```@RustyYato``` to stop considering repr(C) types as 1-ZST for the purpose of repr(transparent). If we go with https://github.com/rust-lang/rfcs/pull/3845 (or another approach for fixing repr(C)), they will anyway not be ZST on all targets any more, so this removes a portability hazard. Furthermore, zero-sized repr(C) structs [may have to be treated](https://github.com/rust-lang/unsafe-code-guidelines/issues/552#issuecomment-3250657813) as non-ZST for the win64 ABI (at least that's what gcc/clang do), so allowing them to be ignored in repr(transparent) types is not entirely coherent.

Turns out we already have an FCW for repr(transparent), namely https://github.com/rust-lang/rust/issues/78586. This extends that lint to also check for repr(C).
This commit is contained in:
Stuart Cook 2025-10-28 20:39:32 +11:00 committed by GitHub
commit ef8003bbb9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 584 additions and 125 deletions

View file

@ -12,9 +12,7 @@ use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::{LangItem, Node, attrs, find_attr, intravisit};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
use rustc_lint_defs::builtin::{
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
};
use rustc_lint_defs::builtin::{REPR_TRANSPARENT_NON_ZST_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
@ -1509,8 +1507,25 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
}
let typing_env = ty::TypingEnv::non_body_analysis(tcx, adt.did());
// For each field, figure out if it's known to have "trivial" layout (i.e., is a 1-ZST), with
// "known" respecting #[non_exhaustive] attributes.
// For each field, figure out if it has "trivial" layout (i.e., is a 1-ZST).
// Even some 1-ZST fields are not allowed though, if they have `non_exhaustive` or private
// fields or `repr(C)`. We call those fields "unsuited".
struct FieldInfo<'tcx> {
span: Span,
trivial: bool,
unsuited: Option<UnsuitedInfo<'tcx>>,
}
struct UnsuitedInfo<'tcx> {
/// The source of the problem, a type that is found somewhere within the field type.
ty: Ty<'tcx>,
reason: UnsuitedReason,
}
enum UnsuitedReason {
NonExhaustive,
PrivateField,
ReprC,
}
let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
let layout = tcx.layout_of(typing_env.as_query_input(ty));
@ -1518,22 +1533,20 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
let span = tcx.hir_span_if_local(field.did).unwrap();
let trivial = layout.is_ok_and(|layout| layout.is_1zst());
if !trivial {
return (span, trivial, None);
// No need to even compute `unsuited`.
return FieldInfo { span, trivial, unsuited: None };
}
// Even some 1-ZST fields are not allowed though, if they have `non_exhaustive`.
fn check_non_exhaustive<'tcx>(
fn check_unsuited<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
t: Ty<'tcx>,
) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
ty: Ty<'tcx>,
) -> ControlFlow<UnsuitedInfo<'tcx>> {
// We can encounter projections during traversal, so ensure the type is normalized.
let t = tcx.try_normalize_erasing_regions(typing_env, t).unwrap_or(t);
match t.kind() {
ty::Tuple(list) => {
list.iter().try_for_each(|t| check_non_exhaustive(tcx, typing_env, t))
}
ty::Array(ty, _) => check_non_exhaustive(tcx, typing_env, *ty),
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
match ty.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)),
ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty),
ty::Adt(def, args) => {
if !def.did().is_local()
&& !find_attr!(
@ -1548,28 +1561,36 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
.any(ty::VariantDef::is_field_list_non_exhaustive);
let has_priv = def.all_fields().any(|f| !f.vis.is_public());
if non_exhaustive || has_priv {
return ControlFlow::Break((
def.descr(),
def.did(),
args,
non_exhaustive,
));
return ControlFlow::Break(UnsuitedInfo {
ty,
reason: if non_exhaustive {
UnsuitedReason::NonExhaustive
} else {
UnsuitedReason::PrivateField
},
});
}
}
if def.repr().c() {
return ControlFlow::Break(UnsuitedInfo {
ty,
reason: UnsuitedReason::ReprC,
});
}
def.all_fields()
.map(|field| field.ty(tcx, args))
.try_for_each(|t| check_non_exhaustive(tcx, typing_env, t))
.try_for_each(|t| check_unsuited(tcx, typing_env, t))
}
_ => ControlFlow::Continue(()),
}
}
(span, trivial, check_non_exhaustive(tcx, typing_env, ty).break_value())
FieldInfo { span, trivial, unsuited: check_unsuited(tcx, typing_env, ty).break_value() }
});
let non_trivial_fields = field_infos
.clone()
.filter_map(|(span, trivial, _non_exhaustive)| if !trivial { Some(span) } else { None });
.filter_map(|field| if !field.trivial { Some(field.span) } else { None });
let non_trivial_count = non_trivial_fields.clone().count();
if non_trivial_count >= 2 {
bad_non_zero_sized_fields(
@ -1581,36 +1602,40 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
);
return;
}
let mut prev_non_exhaustive_1zst = false;
for (span, _trivial, non_exhaustive_1zst) in field_infos {
if let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive_1zst {
let mut prev_unsuited_1zst = false;
for field in field_infos {
if let Some(unsuited) = field.unsuited {
assert!(field.trivial);
// If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
// Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
if non_trivial_count > 0 || prev_non_exhaustive_1zst {
if non_trivial_count > 0 || prev_unsuited_1zst {
tcx.node_span_lint(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
REPR_TRANSPARENT_NON_ZST_FIELDS,
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span,
field.span,
|lint| {
lint.primary_message(
"zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types",
);
let note = if non_exhaustive {
"is marked with `#[non_exhaustive]`"
} else {
"contains private fields"
let title = match unsuited.reason {
UnsuitedReason::NonExhaustive => "external non-exhaustive types",
UnsuitedReason::PrivateField => "external types with private fields",
UnsuitedReason::ReprC => "`repr(C)` types",
};
lint.primary_message(
format!("zero-sized fields in `repr(transparent)` cannot contain {title}"),
);
let note = match unsuited.reason {
UnsuitedReason::NonExhaustive => "is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.",
UnsuitedReason::PrivateField => "contains private fields, so it could become non-zero-sized in the future.",
UnsuitedReason::ReprC => "is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.",
};
let field_ty = tcx.def_path_str_with_args(def_id, args);
lint.note(format!(
"this {descr} contains `{field_ty}`, which {note}, \
and makes it not a breaking change to become \
non-zero-sized in the future."
"this field contains `{field_ty}`, which {note}",
field_ty = unsuited.ty,
));
},
)
);
} else {
prev_non_exhaustive_1zst = true;
prev_unsuited_1zst = true;
}
}
}

View file

@ -362,6 +362,10 @@ fn register_builtins(store: &mut LintStore) {
store.register_renamed("static_mut_ref", "static_mut_refs");
store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries");
store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes");
store.register_renamed(
"repr_transparent_external_private_fields",
"repr_transparent_non_zst_fields",
);
// These were moved to tool lints, but rustc still sees them when compiling normally, before
// tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use

View file

@ -86,7 +86,7 @@ declare_lint_pass! {
REFINING_IMPL_TRAIT_INTERNAL,
REFINING_IMPL_TRAIT_REACHABLE,
RENAMED_AND_REMOVED_LINTS,
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
REPR_TRANSPARENT_NON_ZST_FIELDS,
RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
@ -3011,10 +3011,9 @@ declare_lint! {
}
declare_lint! {
/// The `repr_transparent_external_private_fields` lint
/// The `repr_transparent_non_zst_fields` lint
/// detects types marked `#[repr(transparent)]` that (transitively)
/// contain an external ZST type marked `#[non_exhaustive]` or containing
/// private fields
/// contain a type that is not guaranteed to remain a ZST type under all configurations.
///
/// ### Example
///
@ -3022,8 +3021,13 @@ declare_lint! {
/// #![deny(repr_transparent_external_private_fields)]
/// use foo::NonExhaustiveZst;
///
/// #[repr(C)]
/// struct CZst([u8; 0]);
///
/// #[repr(transparent)]
/// struct Bar(u32, ([u32; 0], NonExhaustiveZst));
/// #[repr(transparent)]
/// struct Baz(u32, CZst);
/// ```
///
/// This will produce:
@ -3042,26 +3046,39 @@ declare_lint! {
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
/// = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
/// = note: this struct contains `NonExhaustiveZst`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
/// = note: this field contains `NonExhaustiveZst`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
///
/// error: zero-sized fields in repr(transparent) cannot contain `#[repr(C)]` types
/// --> src/main.rs:5:28
/// |
/// 5 | struct Baz(u32, CZst);
/// | ^^^^
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
/// = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
/// = note: this field contains `CZst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
/// ```
///
/// ### Explanation
///
/// Previous, Rust accepted fields that contain external private zero-sized types,
/// even though it should not be a breaking change to add a non-zero-sized field to
/// that private type.
/// Previous, Rust accepted fields that contain external private zero-sized types, even though
/// those types could gain a non-zero-sized field in a future, semver-compatible update.
///
/// Rust also accepted fields that contain `repr(C)` zero-sized types, even though those types
/// are not guaranteed to be zero-sized on all targets, and even though those types can
/// make a difference for the ABI (and therefore cannot be ignored by `repr(transparent)`).
///
/// This is a [future-incompatible] lint to transition this
/// to a hard error in the future. See [issue #78586] for more details.
///
/// [issue #78586]: https://github.com/rust-lang/rust/issues/78586
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
Warn,
pub REPR_TRANSPARENT_NON_ZST_FIELDS,
Deny,
"transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseError,
reference: "issue #78586 <https://github.com/rust-lang/rust/issues/78586>",
report_in_deps: true,
};
}

View file

@ -403,7 +403,7 @@ pub enum FutureIncompatibilityReason {
///
/// After a lint has been in this state for a while and you feel like it is ready to graduate
/// to warning everyone, consider setting [`FutureIncompatibleInfo::report_in_deps`] to true.
/// (see it's documentation for more guidance)
/// (see its documentation for more guidance)
///
/// After some period of time, lints with this variant can be turned into
/// hard errors (and the lint removed). Preferably when there is some

View file

@ -38,6 +38,7 @@ pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
#[repr(transparent)]
pub struct TransparentUnit<U>(f32, PhantomData<U>);
#[repr(transparent)]
#[allow(repr_transparent_non_zst_fields)]
pub struct TransparentCustomZst(i32, ZeroSize);
#[repr(C)]

View file

@ -1,5 +1,5 @@
error: `extern` block uses type `Foo`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:47:28
--> $DIR/lint-ctypes.rs:48:28
|
LL | pub fn ptr_type1(size: *const Foo);
| ^^^^^^^^^^ not FFI-safe
@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^
error: `extern` block uses type `Foo`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:48:28
--> $DIR/lint-ctypes.rs:49:28
|
LL | pub fn ptr_type2(size: *const Foo);
| ^^^^^^^^^^ not FFI-safe
@ -32,7 +32,7 @@ LL | pub struct Foo;
| ^^^^^^^^^^^^^^
error: `extern` block uses type `((),)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:50:25
--> $DIR/lint-ctypes.rs:51:25
|
LL | pub fn ptr_tuple(p: *const ((),));
| ^^^^^^^^^^^^ not FFI-safe
@ -41,7 +41,7 @@ LL | pub fn ptr_tuple(p: *const ((),));
= note: tuples have unspecified layout
error: `extern` block uses type `[u32]`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:51:26
--> $DIR/lint-ctypes.rs:52:26
|
LL | pub fn slice_type(p: &[u32]);
| ^^^^^^ not FFI-safe
@ -50,7 +50,7 @@ LL | pub fn slice_type(p: &[u32]);
= note: slices have no C equivalent
error: `extern` block uses type `str`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:52:24
--> $DIR/lint-ctypes.rs:53:24
|
LL | pub fn str_type(p: &str);
| ^^^^ not FFI-safe
@ -59,7 +59,7 @@ LL | pub fn str_type(p: &str);
= note: string slices have no C equivalent
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:53:24
--> $DIR/lint-ctypes.rs:54:24
|
LL | pub fn box_type(p: Box<u32>);
| ^^^^^^^^ not FFI-safe
@ -68,7 +68,7 @@ LL | pub fn box_type(p: Box<u32>);
= note: this struct has unspecified layout
error: `extern` block uses type `char`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:55:25
--> $DIR/lint-ctypes.rs:56:25
|
LL | pub fn char_type(p: char);
| ^^^^ not FFI-safe
@ -77,7 +77,7 @@ LL | pub fn char_type(p: char);
= note: the `char` type has no C equivalent
error: `extern` block uses type `dyn Bar`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:56:26
--> $DIR/lint-ctypes.rs:57:26
|
LL | pub fn trait_type(p: &dyn Bar);
| ^^^^^^^^ not FFI-safe
@ -85,7 +85,7 @@ LL | pub fn trait_type(p: &dyn Bar);
= note: trait objects have no C equivalent
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:57:26
--> $DIR/lint-ctypes.rs:58:26
|
LL | pub fn tuple_type(p: (i32, i32));
| ^^^^^^^^^^ not FFI-safe
@ -94,7 +94,7 @@ LL | pub fn tuple_type(p: (i32, i32));
= note: tuples have unspecified layout
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:58:27
--> $DIR/lint-ctypes.rs:59:27
|
LL | pub fn tuple_type2(p: I32Pair);
| ^^^^^^^ not FFI-safe
@ -103,7 +103,7 @@ LL | pub fn tuple_type2(p: I32Pair);
= note: tuples have unspecified layout
error: `extern` block uses type `ZeroSize`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:59:25
--> $DIR/lint-ctypes.rs:60:25
|
LL | pub fn zero_size(p: ZeroSize);
| ^^^^^^^^ not FFI-safe
@ -117,20 +117,20 @@ LL | pub struct ZeroSize;
| ^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:60:33
--> $DIR/lint-ctypes.rs:61:33
|
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: composed only of `PhantomData`
note: the type is defined here
--> $DIR/lint-ctypes.rs:44:1
--> $DIR/lint-ctypes.rs:45:1
|
LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:63:12
--> $DIR/lint-ctypes.rs:64:12
|
LL | -> ::std::marker::PhantomData<bool>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -138,7 +138,7 @@ LL | -> ::std::marker::PhantomData<bool>;
= note: composed only of `PhantomData`
error: `extern` block uses type `fn()`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:64:23
--> $DIR/lint-ctypes.rs:65:23
|
LL | pub fn fn_type(p: RustFn);
| ^^^^^^ not FFI-safe
@ -147,7 +147,7 @@ LL | pub fn fn_type(p: RustFn);
= note: this function pointer has Rust-specific calling convention
error: `extern` block uses type `fn()`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:65:24
--> $DIR/lint-ctypes.rs:66:24
|
LL | pub fn fn_type2(p: fn());
| ^^^^ not FFI-safe
@ -156,7 +156,7 @@ LL | pub fn fn_type2(p: fn());
= note: this function pointer has Rust-specific calling convention
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:66:28
--> $DIR/lint-ctypes.rs:67:28
|
LL | pub fn fn_contained(p: RustBadRet);
| ^^^^^^^^^^ not FFI-safe
@ -165,7 +165,7 @@ LL | pub fn fn_contained(p: RustBadRet);
= note: this struct has unspecified layout
error: `extern` block uses type `str`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:67:31
--> $DIR/lint-ctypes.rs:68:31
|
LL | pub fn transparent_str(p: TransparentStr);
| ^^^^^^^^^^^^^^ not FFI-safe
@ -174,7 +174,7 @@ LL | pub fn transparent_str(p: TransparentStr);
= note: string slices have no C equivalent
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:68:30
--> $DIR/lint-ctypes.rs:69:30
|
LL | pub fn transparent_fn(p: TransparentBadFn);
| ^^^^^^^^^^^^^^^^ not FFI-safe
@ -183,7 +183,7 @@ LL | pub fn transparent_fn(p: TransparentBadFn);
= note: this struct has unspecified layout
error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:69:27
--> $DIR/lint-ctypes.rs:70:27
|
LL | pub fn raw_array(arr: [u8; 8]);
| ^^^^^^^ not FFI-safe
@ -192,7 +192,7 @@ LL | pub fn raw_array(arr: [u8; 8]);
= note: passing raw arrays by value is not FFI-safe
error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:71:26
--> $DIR/lint-ctypes.rs:72:26
|
LL | pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -201,7 +201,7 @@ LL | pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>);
= note: enum has no representation hint
error: `extern` block uses type `Option<UnsafeCell<&i32>>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:73:26
--> $DIR/lint-ctypes.rs:74:26
|
LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -211,3 +211,14 @@ LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
error: aborting due to 21 previous errors
Future incompatibility report: Future breakage diagnostic:
warning: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/lint-ctypes.rs:42:38
|
LL | pub struct TransparentCustomZst(i32, ZeroSize);
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ZeroSize`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.

View file

@ -54,6 +54,7 @@ pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
pub struct TransparentUnit<U>(f32, PhantomData<U>);
#[repr(transparent)]
#[allow(repr_transparent_non_zst_fields)]
pub struct TransparentCustomZst(i32, ZeroSize);
#[repr(C)]

View file

@ -1,5 +1,5 @@
error: `extern` fn uses type `[u32]`, which is not FFI-safe
--> $DIR/lint-fn.rs:70:33
--> $DIR/lint-fn.rs:71:33
|
LL | pub extern "C" fn slice_type(p: &[u32]) { }
| ^^^^^^ not FFI-safe
@ -13,7 +13,7 @@ LL | #![deny(improper_ctypes_definitions)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `str`, which is not FFI-safe
--> $DIR/lint-fn.rs:73:31
--> $DIR/lint-fn.rs:74:31
|
LL | pub extern "C" fn str_type(p: &str) { }
| ^^^^ not FFI-safe
@ -22,7 +22,7 @@ LL | pub extern "C" fn str_type(p: &str) { }
= note: string slices have no C equivalent
error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
--> $DIR/lint-fn.rs:80:34
--> $DIR/lint-fn.rs:81:34
|
LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
| ^^^^^^^^^ not FFI-safe
@ -30,7 +30,7 @@ LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
= note: box cannot be represented as a single pointer
error: `extern` fn uses type `Box<str>`, which is not FFI-safe
--> $DIR/lint-fn.rs:83:35
--> $DIR/lint-fn.rs:84:35
|
LL | pub extern "C" fn boxed_string(p: Box<str>) { }
| ^^^^^^^^ not FFI-safe
@ -38,7 +38,7 @@ LL | pub extern "C" fn boxed_string(p: Box<str>) { }
= note: box cannot be represented as a single pointer
error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
--> $DIR/lint-fn.rs:86:34
--> $DIR/lint-fn.rs:87:34
|
LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
| ^^^^^^^^^^^^^^ not FFI-safe
@ -46,7 +46,7 @@ LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
= note: box cannot be represented as a single pointer
error: `extern` fn uses type `char`, which is not FFI-safe
--> $DIR/lint-fn.rs:89:32
--> $DIR/lint-fn.rs:90:32
|
LL | pub extern "C" fn char_type(p: char) { }
| ^^^^ not FFI-safe
@ -55,7 +55,7 @@ LL | pub extern "C" fn char_type(p: char) { }
= note: the `char` type has no C equivalent
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-fn.rs:92:33
--> $DIR/lint-fn.rs:93:33
|
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
| ^^^^^^^^^^ not FFI-safe
@ -64,7 +64,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
= note: tuples have unspecified layout
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-fn.rs:95:34
--> $DIR/lint-fn.rs:96:34
|
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
| ^^^^^^^ not FFI-safe
@ -73,7 +73,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
= note: tuples have unspecified layout
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
--> $DIR/lint-fn.rs:98:32
--> $DIR/lint-fn.rs:99:32
|
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
| ^^^^^^^^ not FFI-safe
@ -87,20 +87,20 @@ LL | pub struct ZeroSize;
| ^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
--> $DIR/lint-fn.rs:101:40
--> $DIR/lint-fn.rs:102:40
|
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: composed only of `PhantomData`
note: the type is defined here
--> $DIR/lint-fn.rs:60:1
--> $DIR/lint-fn.rs:61:1
|
LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-fn.rs:104:51
--> $DIR/lint-fn.rs:105:51
|
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
| ^^^^^^^^^^^^^^^^^ not FFI-safe
@ -108,7 +108,7 @@ LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
= note: composed only of `PhantomData`
error: `extern` fn uses type `fn()`, which is not FFI-safe
--> $DIR/lint-fn.rs:109:30
--> $DIR/lint-fn.rs:110:30
|
LL | pub extern "C" fn fn_type(p: RustFn) { }
| ^^^^^^ not FFI-safe
@ -117,7 +117,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
= note: this function pointer has Rust-specific calling convention
error: `extern` fn uses type `fn()`, which is not FFI-safe
--> $DIR/lint-fn.rs:112:31
--> $DIR/lint-fn.rs:113:31
|
LL | pub extern "C" fn fn_type2(p: fn()) { }
| ^^^^ not FFI-safe
@ -126,7 +126,7 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
= note: this function pointer has Rust-specific calling convention
error: `extern` fn uses type `str`, which is not FFI-safe
--> $DIR/lint-fn.rs:117:38
--> $DIR/lint-fn.rs:118:38
|
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
| ^^^^^^^^^^^^^^ not FFI-safe
@ -135,7 +135,7 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
= note: string slices have no C equivalent
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-fn.rs:169:43
--> $DIR/lint-fn.rs:170:43
|
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
| ^^^^^^^^^^^^^^^^^ not FFI-safe
@ -143,7 +143,7 @@ LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
= note: composed only of `PhantomData`
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
--> $DIR/lint-fn.rs:182:39
--> $DIR/lint-fn.rs:183:39
|
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
| ^^^^^^ not FFI-safe
@ -152,7 +152,7 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
= note: this struct has unspecified layout
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
--> $DIR/lint-fn.rs:185:41
--> $DIR/lint-fn.rs:186:41
|
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
| ^^^^^^ not FFI-safe
@ -162,3 +162,14 @@ LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
error: aborting due to 17 previous errors
Future incompatibility report: Future breakage diagnostic:
warning: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/lint-fn.rs:58:38
|
LL | pub struct TransparentCustomZst(i32, ZeroSize);
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ZeroSize`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.

View file

@ -2,7 +2,7 @@
#![feature(sync_unsafe_cell)]
#![allow(unused)]
#![deny(repr_transparent_external_private_fields)]
#![deny(repr_transparent_non_zst_fields)]
// https://github.com/rust-lang/rust/issues/129470

View file

@ -1,4 +1,4 @@
#![deny(repr_transparent_external_private_fields)]
#![deny(repr_transparent_non_zst_fields)]
//@ aux-build: repr-transparent-non-exhaustive.rs
extern crate repr_transparent_non_exhaustive;
@ -42,7 +42,7 @@ pub struct T4(Sized, ExternalIndirection<(InternalPrivate, InternalNonExhaustive
#[repr(transparent)]
pub struct T5(Sized, Private);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external types with private fields
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]
@ -67,7 +67,7 @@ pub struct T8(Sized, NonExhaustiveVariant);
#[repr(transparent)]
pub struct T9(Sized, InternalIndirection<Private>);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external types with private fields
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]
@ -87,7 +87,7 @@ pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
#[repr(transparent)]
pub struct T13(Sized, ExternalIndirection<Private>);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external types with private fields
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]
@ -117,7 +117,7 @@ pub struct T18(NonExhaustive, NonExhaustive);
#[repr(transparent)]
pub struct T19(NonExhaustive, Private);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external types with private fields
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]

View file

@ -1,4 +1,4 @@
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:44:22
|
LL | pub struct T5(Sized, Private);
@ -6,12 +6,12 @@ LL | pub struct T5(Sized, Private);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_external_private_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:49:22
@ -21,7 +21,7 @@ LL | pub struct T6(Sized, NonExhaustive);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:54:23
@ -31,7 +31,7 @@ LL | pub struct T6a(Sized, <i32 as Trait>::Assoc); // normalizes to `NonExhausti
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:59:22
@ -41,7 +41,7 @@ LL | pub struct T7(Sized, NonExhaustiveEnum);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:64:22
@ -51,9 +51,9 @@ LL | pub struct T8(Sized, NonExhaustiveVariant);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:69:22
|
LL | pub struct T9(Sized, InternalIndirection<Private>);
@ -61,7 +61,7 @@ LL | pub struct T9(Sized, InternalIndirection<Private>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:74:23
@ -71,7 +71,7 @@ LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:79:23
@ -81,7 +81,7 @@ LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:84:23
@ -91,9 +91,9 @@ LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:89:23
|
LL | pub struct T13(Sized, ExternalIndirection<Private>);
@ -101,7 +101,7 @@ LL | pub struct T13(Sized, ExternalIndirection<Private>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:94:23
@ -111,7 +111,7 @@ LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:99:23
@ -121,7 +121,7 @@ LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:104:23
@ -131,7 +131,7 @@ LL | pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:109:16
@ -141,7 +141,7 @@ LL | pub struct T17(NonExhaustive, Sized);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:114:31
@ -151,9 +151,9 @@ LL | pub struct T18(NonExhaustive, NonExhaustive);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:119:31
|
LL | pub struct T19(NonExhaustive, Private);
@ -161,7 +161,7 @@ LL | pub struct T19(NonExhaustive, Private);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:124:32
@ -171,7 +171,279 @@ LL | pub struct T19Flipped(Private, NonExhaustive);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
error: aborting due to 17 previous errors
Future incompatibility report: Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:44:22
|
LL | pub struct T5(Sized, Private);
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:49:22
|
LL | pub struct T6(Sized, NonExhaustive);
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:54:23
|
LL | pub struct T6a(Sized, <i32 as Trait>::Assoc); // normalizes to `NonExhaustive`
| ^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:59:22
|
LL | pub struct T7(Sized, NonExhaustiveEnum);
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:64:22
|
LL | pub struct T8(Sized, NonExhaustiveVariant);
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:69:22
|
LL | pub struct T9(Sized, InternalIndirection<Private>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:74:23
|
LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:79:23
|
LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:84:23
|
LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:89:23
|
LL | pub struct T13(Sized, ExternalIndirection<Private>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:94:23
|
LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:99:23
|
LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:104:23
|
LL | pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:109:16
|
LL | pub struct T17(NonExhaustive, Sized);
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:114:31
|
LL | pub struct T18(NonExhaustive, NonExhaustive);
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external types with private fields
--> $DIR/repr-transparent-non-exhaustive.rs:119:31
|
LL | pub struct T19(NonExhaustive, Private);
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `Private`, which contains private fields, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
--> $DIR/repr-transparent-non-exhaustive.rs:124:32
|
LL | pub struct T19Flipped(Private, NonExhaustive);
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
note: the lint level is defined here
--> $DIR/repr-transparent-non-exhaustive.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -0,0 +1,32 @@
#![deny(repr_transparent_non_zst_fields)]
#[repr(C)]
pub struct ReprC1Zst {
pub _f: (),
}
pub type Sized = i32;
#[repr(transparent)]
pub struct T1(ReprC1Zst);
#[repr(transparent)]
pub struct T2((), ReprC1Zst);
#[repr(transparent)]
pub struct T3(ReprC1Zst, ());
#[repr(transparent)]
pub struct T5(Sized, ReprC1Zst);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]
pub struct T6(ReprC1Zst, Sized);
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
//~| WARN this was previously accepted by the compiler
#[repr(transparent)]
pub struct T7(T1, Sized); // still wrong, even when the repr(C) is hidden inside another type
//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
//~| WARN this was previously accepted by the compiler
fn main() {}

View file

@ -0,0 +1,85 @@
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:18:22
|
LL | pub struct T5(Sized, ReprC1Zst);
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
note: the lint level is defined here
--> $DIR/repr-transparent-repr-c.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:23:15
|
LL | pub struct T6(ReprC1Zst, Sized);
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:28:15
|
LL | pub struct T7(T1, Sized); // still wrong, even when the repr(C) is hidden inside another type
| ^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
error: aborting due to 3 previous errors
Future incompatibility report: Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:18:22
|
LL | pub struct T5(Sized, ReprC1Zst);
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
note: the lint level is defined here
--> $DIR/repr-transparent-repr-c.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:23:15
|
LL | pub struct T6(ReprC1Zst, Sized);
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
note: the lint level is defined here
--> $DIR/repr-transparent-repr-c.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: zero-sized fields in `repr(transparent)` cannot contain `repr(C)` types
--> $DIR/repr-transparent-repr-c.rs:28:15
|
LL | pub struct T7(T1, Sized); // still wrong, even when the repr(C) is hidden inside another type
| ^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this field contains `ReprC1Zst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
note: the lint level is defined here
--> $DIR/repr-transparent-repr-c.rs:1:9
|
LL | #![deny(repr_transparent_non_zst_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^