Auto merge of #148202 - Zalathar:rollup-2eriuc3, r=Zalathar

Rollup of 14 pull requests

Successful merges:

 - rust-lang/rust#144936 (CFI: Fix types that implement Fn, FnMut, or FnOnce)
 - rust-lang/rust#147185 (repr(transparent): do not consider repr(C) types to be 1-ZST)
 - rust-lang/rust#147840 (Rework unsizing coercions in the new solver)
 - rust-lang/rust#147915 (Update target maintainers android.md)
 - rust-lang/rust#148013 (1.91.0 release notes)
 - rust-lang/rust#148044 (compiletest: show output in debug logging)
 - rust-lang/rust#148057 (tests/ui/sanitizer/hwaddress.rs: Run on aarch64 and remove cgu hack)
 - rust-lang/rust#148139 (Add `coverage` scope for controlling paths in code coverage)
 - rust-lang/rust#148154 (Add a mailmap entry)
 - rust-lang/rust#148158 (ci: loongarch64: use medium code model to avoid relocation overflows)
 - rust-lang/rust#148166 (Re-enable macro-stepping test for AArch64)
 - rust-lang/rust#148172 (rustc-dev-guide subtree update)
 - rust-lang/rust#148175 (Fix typos: duplicate words in comments)
 - rust-lang/rust#148186 (rustdoc-search: add an integration test for CCI)

Failed merges:

 - rust-lang/rust#147935 (Add LLVM realtime sanitizer)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-10-28 09:55:34 +00:00
67 changed files with 1370 additions and 203 deletions

View File

@@ -680,6 +680,7 @@ Valerii Lashmanov <vflashm@gmail.com>
Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
Vitaly Shukela <vi0oss@gmail.com>
Waffle Lapkin <waffle.lapkin@gmail.com>
Waffle Lapkin <waffle.lapkin@gmail.com> <Waffle Lapkin>
Waffle Lapkin <waffle.lapkin@gmail.com> <waffle.lapkin@tasking.com>
Weihang Lo <me@weihanglo.tw>
Weihang Lo <me@weihanglo.tw> <weihanglo@users.noreply.github.com>

View File

@@ -1,3 +1,214 @@
Version 1.91.0 (2025-10-30)
==========================
<a id="1.91.0-Language"></a>
Language
--------
- [Lower pattern bindings in the order they're written and base drop order on primary bindings' order](https://github.com/rust-lang/rust/pull/143764)
- [Stabilize declaration of C-style variadic functions for `sysv64`, `win64`, `efiapi`, and `aapcs` ABIs](https://github.com/rust-lang/rust/pull/144066).
This brings these ABIs in line with the C ABI: variadic functions can be declared in extern blocks but not defined.
- [Add `dangling_pointers_from_locals` lint to warn against dangling pointers from local variables](https://github.com/rust-lang/rust/pull/144322)
- [Upgrade `semicolon_in_expressions_from_macros` from warn to deny](https://github.com/rust-lang/rust/pull/144369)
- [Stabilize LoongArch32 inline assembly](https://github.com/rust-lang/rust/pull/144402)
- [Add warn-by-default `integer_to_ptr_transmutes` lint against integer-to-pointer transmutes](https://github.com/rust-lang/rust/pull/144531)
- [Stabilize `sse4a` and `tbm` target features](https://github.com/rust-lang/rust/pull/144542)
- [Add `target_env = "macabi"` and `target_env = "sim"` cfgs](https://github.com/rust-lang/rust/pull/139451) as replacements for the `target_abi` cfgs with the same values.
<a id="1.91.0-Compiler"></a>
Compiler
--------
- [Don't warn on never-to-any `as` casts as unreachable](https://github.com/rust-lang/rust/pull/144804)
<a id="1.91.0-Platform-Support"></a>
Platform Support
----------------
- [Promote `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/143031)
Note: llvm-tools and MSI installers are missing but will be added in future releases.
- [Promote `aarch64-pc-windows-msvc` to Tier 1](https://github.com/rust-lang/rust/pull/145682)
Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.
[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
<a id="1.91.0-Libraries"></a>
Libraries
---------
- [Print thread ID in panic message](https://github.com/rust-lang/rust/pull/115746)
- [Fix overly restrictive lifetime in `core::panic::Location::file` return type](https://github.com/rust-lang/rust/pull/132087)
- [Guarantee parameter order for `_by()` variants of `min` / `max`/ `minmax` in `std::cmp`](https://github.com/rust-lang/rust/pull/139357)
- [Document assumptions about `Clone` and `Eq` traits](https://github.com/rust-lang/rust/pull/144330/)
- [`std::thread`: Return error if setting thread stack size fails](https://github.com/rust-lang/rust/pull/144210)
This used to panic within the standard library.
<a id="1.91.0-Stabilized-APIs"></a>
Stabilized APIs
---------------
- [`Path::file_prefix`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.file_prefix)
- [`AtomicPtr::fetch_ptr_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_add)
- [`AtomicPtr::fetch_ptr_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_sub)
- [`AtomicPtr::fetch_byte_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_add)
- [`AtomicPtr::fetch_byte_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_sub)
- [`AtomicPtr::fetch_or`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_or)
- [`AtomicPtr::fetch_and`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and)
- [`AtomicPtr::fetch_xor`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_xor)
- [`{integer}::strict_add`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add)
- [`{integer}::strict_sub`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub)
- [`{integer}::strict_mul`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_mul)
- [`{integer}::strict_div`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div)
- [`{integer}::strict_div_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div_euclid)
- [`{integer}::strict_rem`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem)
- [`{integer}::strict_rem_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem_euclid)
- [`{integer}::strict_neg`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_neg)
- [`{integer}::strict_shl`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shl)
- [`{integer}::strict_shr`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shr)
- [`{integer}::strict_pow`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_pow)
- [`i{N}::strict_add_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_add_unsigned)
- [`i{N}::strict_sub_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_sub_unsigned)
- [`i{N}::strict_abs`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_abs)
- [`u{N}::strict_add_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add_signed)
- [`u{N}::strict_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub_signed)
- [`PanicHookInfo::payload_as_str`](https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload_as_str)
- [`core::iter::chain`](https://doc.rust-lang.org/stable/core/iter/fn.chain.html)
- [`u{N}::checked_signed_diff`](https://doc.rust-lang.org/stable/std/primitive.u16.html#method.checked_signed_diff)
- [`core::array::repeat`](https://doc.rust-lang.org/stable/core/array/fn.repeat.html)
- [`PathBuf::add_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.add_extension)
- [`PathBuf::with_added_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.with_added_extension)
- [`Duration::from_mins`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_mins)
- [`Duration::from_hours`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_hours)
- [`impl PartialEq<str> for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3Cstr%3E-for-PathBuf)
- [`impl PartialEq<String> for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf)
- [`impl PartialEq<str> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path)
- [`impl PartialEq<String> for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path)
- [`impl PartialEq<PathBuf> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String)
- [`impl PartialEq<Path> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String)
- [`impl PartialEq<PathBuf> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str)
- [`impl PartialEq<Path> for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPath%3E-for-str)
- [`Ipv4Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.from_octets)
- [`Ipv6Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_octets)
- [`Ipv6Addr::from_segments`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_segments)
- [`impl<T> Default for Pin<Box<T>> where Box<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CBox%3CT%3E%3E)
- [`impl<T> Default for Pin<Rc<T>> where Rc<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CRc%3CT%3E%3E)
- [`impl<T> Default for Pin<Arc<T>> where Arc<T>: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CArc%3CT%3E%3E)
- [`Cell::as_array_of_cells`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.as_array_of_cells)
- [`u{N}::carrying_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_add)
- [`u{N}::borrowing_sub`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.borrowing_sub)
- [`u{N}::carrying_mul`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul)
- [`u{N}::carrying_mul_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul_add)
- [`BTreeMap::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.extract_if)
- [`BTreeSet::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.extract_if)
- [`impl Debug for windows::ffi::EncodeWide<'_>`](https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-Debug-for-EncodeWide%3C'_%3E)
- [`str::ceil_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.ceil_char_boundary)
- [`str::floor_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.floor_char_boundary)
- [`impl Sum for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum-for-Saturating%3Cu32%3E)
- [`impl Sum<&Self> for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E)
- [`impl Product for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product-for-Saturating%3Cu32%3E)
- [`impl Product<&Self> for Saturating<u{N}>`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E)
These previously stable APIs are now stable in const contexts:
- [`<[T; N]>::each_ref`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_ref)
- [`<[T; N]>::each_mut`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut)
- [`OsString::new`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.new)
- [`PathBuf::new`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.new)
- [`TypeId::of`](https://doc.rust-lang.org/stable/std/any/struct.TypeId.html#method.of)
- [`ptr::with_exposed_provenance`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance.html)
- [`ptr::with_exposed_provenance_mut`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance_mut.html)
<a id="1.91.0-Cargo"></a>
Cargo
-----
- 🎉 Stabilize `build.build-dir`.
This config sets the directory where intermediate build artifacts are stored.
These artifacts are produced by Cargo and rustc during the build process.
End users usually won't need to interact with them, and the layout inside
`build-dir` is an implementation detail that may change without notice.
([config doc](https://doc.rust-lang.org/stable/cargo/reference/config.html#buildbuild-dir))
([build cache doc](https://doc.rust-lang.org/stable/cargo/reference/build-cache.html))
[#15833](https://github.com/rust-lang/cargo/pull/15833)
[#15840](https://github.com/rust-lang/cargo/pull/15840)
- The `--target` flag and the `build.target` configuration can now take literal
`"host-tuple"` string, which will internally be substituted by the host
machine's target triple.
[#15838](https://github.com/rust-lang/cargo/pull/15838)
[#16003](https://github.com/rust-lang/cargo/pull/16003)
[#16032](https://github.com/rust-lang/cargo/pull/16032)
<a id="1.91.0-Rustdoc"></a>
Rustdoc
-----
- [In search results, rank doc aliases lower than non-alias items with the same name](https://github.com/rust-lang/rust/pull/145100)
- [Raw pointers now work in type-based search like references](https://github.com/rust-lang/rust/pull/145731). This means you can now search for things like `*const u8 ->`, and additionally functions that take or return raw pointers will now display their signature properly in search results.
<a id="1.91.0-Compatibility-Notes"></a>
Compatibility Notes
-------------------
- [Always require coroutine captures to be drop-live](https://github.com/rust-lang/rust/pull/144156)
- [Apple: Always pass SDK root when linking with `cc`, and pass it via `SDKROOT` env var](https://github.com/rust-lang/rust/pull/131477). This should fix linking issues with `rustc` running inside Xcode. Libraries in `/usr/local/lib` may no longer be linked automatically, if you develop or use a crate that relies on this, you should explicitly set `cargo::rustc-link-search=/usr/local/lib` in a `build.rs` script.
- [Relaxed bounds in associated type bound position like in `TraitRef<AssocTy: ?Sized>` are now correctly forbidden](https://github.com/rust-lang/rust/pull/135331)
- [Add unstable `#[sanitize(xyz = "on|off")]` built-in attribute that shadows procedural macros with the same name](https://github.com/rust-lang/rust/pull/142681)
- [Fix the drop checker being more permissive for bindings declared with let-else](https://github.com/rust-lang/rust/pull/143028)
- [Be more strict when parsing attributes, erroring on many invalid attributes](https://github.com/rust-lang/rust/pull/144689)
- [Error on invalid `#[should_panic]` attributes](https://github.com/rust-lang/rust/pull/143808)
- [Error on invalid `#[link]` attributes](https://github.com/rust-lang/rust/pull/143193)
- [Mark all deprecation lints in name resolution as deny-by-default and also report in dependencies](https://github.com/rust-lang/rust/pull/143929)
- The lint `semicolon_in_expressions_from_macros`, for `macro_rules!` macros in expression position that expand to end in a semicolon (`;`), is now deny-by-default. It was already warn-by-default, and a future compatibility warning (FCW) that warned even in dependencies. This lint will become a hard error in the future.
- [Trait impl modifiers (e.g., `unsafe`, `!`, `default`) in inherent impls are no longer syntactically valid](https://github.com/rust-lang/rust/pull/144386)
- [Start reporting future breakage for `ill_formed_attribute_input` in dependencies](https://github.com/rust-lang/rust/pull/144544)
- [Restrict the scope of temporaries created by the macros `pin!`, `format_args!`, `write!`, and `writeln!` in `if let` scrutinees in Rust Edition 2024.](https://github.com/rust-lang/rust/pull/145342) This applies [Rust Edition 2024's `if let` temporary scope rules](https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html) to these temporaries, which previously could live past the `if` expression regardless of Edition.
- [Invalid numeric literal suffixes in tuple indexing, tuple struct indexing, and struct field name positions are now correctly rejected](https://github.com/rust-lang/rust/pull/145463)
- [Closures marked with the keyword `static` are now syntactically invalid](https://github.com/rust-lang/rust/pull/145604)
- [Shebangs inside `--cfg` and `--check-cfg` arguments are no longer allowed](https://github.com/rust-lang/rust/pull/146211)
- [Add future incompatibility lint for temporary lifetime shortening in Rust 1.92](https://github.com/rust-lang/rust/pull/147056)
Cargo compatibility notes:
- `cargo publish` no longer keeps `.crate` tarballs as final build artifacts
when `build.build-dir` is set. These tarballs were previously included due to
an oversight and are now treated as intermediate artifacts.
To get `.crate` tarballs as final artifacts, use `cargo package`.
In a future version, this change will apply regardless of `build.build-dir`.
[#15910](https://github.com/rust-lang/cargo/pull/15910)
- Adjust Cargo messages to match rustc diagnostic style.
This changes some of the terminal colors used by Cargo messages.
[#15928](https://github.com/rust-lang/cargo/pull/15928)
- Tools and projects relying on the
[internal details of Cargo's `build-dir`](https://doc.rust-lang.org/cargo/reference/build-cache.html)
may not work for users changing their `build-dir` layout.
For those doing so, we'd recommend proactively testing these cases
particularly as we are considering changing the default location of the `build-dir` in the future
([cargo#16147](https://github.com/rust-lang/cargo/issues/16147)).
If you can't migrate off of Cargo's internal details,
we'd like to learn more about your use case as we prepare to change the layout of the `build-dir`
([cargo#15010](https://github.com/rust-lang/cargo/issues/15010)).
<a id="1.91.0-Internal-Changes"></a>
Internal Changes
----------------
These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
- [Update to LLVM 21](https://github.com/rust-lang/rust/pull/143684)
Version 1.90.0 (2025-09-18)
===========================

View File

@@ -298,7 +298,7 @@ impl Printer {
}
}
// This is is where `BoxMarker`s are produced.
// This is where `BoxMarker`s are produced.
fn scan_begin(&mut self, token: BeginToken) -> BoxMarker {
if self.scan_stack.is_empty() {
self.left_total = 1;
@@ -310,7 +310,7 @@ impl Printer {
BoxMarker
}
// This is is where `BoxMarker`s are consumed.
// This is where `BoxMarker`s are consumed.
fn scan_end(&mut self, b: BoxMarker) {
if self.scan_stack.is_empty() {
self.print_end();

View File

@@ -128,7 +128,7 @@ impl GlobalFileTable {
for file in all_files {
raw_file_table.entry(file.stable_id).or_insert_with(|| {
file.name
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
.to_string_lossy()
.into_owned()
});
@@ -147,7 +147,7 @@ impl GlobalFileTable {
.sess
.opts
.working_dir
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
.to_string_lossy();
table.push(base_dir.as_ref());

View File

@@ -121,7 +121,7 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {
/// ### `tracing_separate_thread` parameter
///
/// This macro was introduced to obtain better traces of Miri without impacting release performance.
/// Miri saves traces using the the `tracing_chrome` `tracing::Layer` so that they can be visualized
/// Miri saves traces using the `tracing_chrome` `tracing::Layer` so that they can be visualized
/// in <https://ui.perfetto.dev>. To instruct `tracing_chrome` to put some spans on a separate trace
/// thread/line than other spans when viewed in <https://ui.perfetto.dev>, you can pass
/// `tracing_separate_thread = tracing::field::Empty` to the tracing macros. This is useful to

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

@@ -35,13 +35,13 @@
//! // and are then unable to coerce `&7i32` to `&mut i32`.
//! ```
use std::ops::Deref;
use std::ops::{ControlFlow, Deref};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::attrs::InlineAttr;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, LangItem};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_infer::infer::relate::RelateResult;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, InferResult, RegionVariableOrigin};
@@ -56,6 +56,8 @@ use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
use rustc_trait_selection::solve::{Certainty, Goal, NoSolution};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{
self, ImplSource, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
@@ -639,11 +641,44 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
Adjust::Pointer(PointerCoercion::Unsize),
)?;
let mut selcx = traits::SelectionContext::new(self);
// Create an obligation for `Source: CoerceUnsized<Target>`.
let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target });
let pred = ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]);
let obligation = Obligation::new(self.tcx, cause, self.fcx.param_env, pred);
if self.next_trait_solver() {
coercion.obligations.push(obligation);
if self
.infcx
.visit_proof_tree(
Goal::new(self.tcx, self.param_env, pred),
&mut CoerceVisitor { fcx: self.fcx, span: self.cause.span },
)
.is_break()
{
return Err(TypeError::Mismatch);
}
} else {
self.coerce_unsized_old_solver(
obligation,
&mut coercion,
coerce_unsized_did,
unsize_did,
)?;
}
Ok(coercion)
}
fn coerce_unsized_old_solver(
&self,
obligation: Obligation<'tcx, ty::Predicate<'tcx>>,
coercion: &mut InferOk<'tcx, (Vec<Adjustment<'tcx>>, Ty<'tcx>)>,
coerce_unsized_did: DefId,
unsize_did: DefId,
) -> Result<(), TypeError<'tcx>> {
let mut selcx = traits::SelectionContext::new(self);
// Use a FIFO queue for this custom fulfillment procedure.
//
// A Vec (or SmallVec) is not a natural choice for a queue. However,
@@ -651,12 +686,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// and almost never more than 3. By using a SmallVec we avoid an
// allocation, at the (very small) cost of (occasionally) having to
// shift subsequent elements down when removing the front element.
let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new(
self.tcx,
cause,
self.fcx.param_env,
ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
)];
let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![obligation];
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@@ -749,7 +779,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// with the unsizing - the lack of a coercion should
// be silent, as it causes a type mismatch later.
}
Ok(Some(ImplSource::UserDefined(impl_source))) => {
queue.extend(impl_source.nested);
// Certain incoherent `CoerceUnsized` implementations may cause ICEs,
@@ -767,7 +796,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
}
}
Ok(coercion)
Ok(())
}
/// Applies reborrowing for `Pin`
@@ -2005,3 +2034,69 @@ impl AsCoercionSite for hir::Arm<'_> {
self.body
}
}
/// Recursively visit goals to decide whether an unsizing is possible.
/// `Break`s when it isn't, and an error should be raised.
/// `Continue`s when an unsizing ok based on an implementation of the `Unsize` trait / lang item.
struct CoerceVisitor<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
span: Span,
}
impl<'tcx> ProofTreeVisitor<'tcx> for CoerceVisitor<'_, 'tcx> {
type Result = ControlFlow<()>;
fn span(&self) -> Span {
self.span
}
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
let Some(pred) = goal.goal().predicate.as_trait_clause() else {
return ControlFlow::Continue(());
};
// Make sure this predicate is referring to either an `Unsize` or `CoerceUnsized` trait,
// Otherwise there's nothing to do.
if !self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::Unsize)
&& !self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::CoerceUnsized)
{
return ControlFlow::Continue(());
}
match goal.result() {
// If we prove the `Unsize` or `CoerceUnsized` goal, continue recursing.
Ok(Certainty::Yes) => ControlFlow::Continue(()),
Err(NoSolution) => {
// Even if we find no solution, continue recursing if we find a single candidate
// for which we're shallowly certain it holds to get the right error source.
if let [only_candidate] = &goal.candidates()[..]
&& only_candidate.shallow_certainty() == Certainty::Yes
{
only_candidate.visit_nested_no_probe(self)
} else {
ControlFlow::Break(())
}
}
Ok(Certainty::Maybe { .. }) => {
// FIXME: structurally normalize?
if self.fcx.tcx.is_lang_item(pred.def_id(), LangItem::Unsize)
&& let ty::Dynamic(..) = pred.skip_binder().trait_ref.args.type_at(1).kind()
&& let ty::Infer(ty::TyVar(vid)) = *pred.self_ty().skip_binder().kind()
&& self.fcx.type_var_is_sized(vid)
{
// We get here when trying to unsize a type variable to a `dyn Trait`,
// knowing that that variable is sized. Unsizing definitely has to happen in that case.
// If the variable weren't sized, we may not need an unsizing coercion.
// In general, we don't want to add coercions too eagerly since it makes error messages much worse.
ControlFlow::Continue(())
} else if let Some(cand) = goal.unique_applicable_candidate()
&& cand.shallow_certainty() == Certainty::Yes
{
cand.visit_nested_no_probe(self)
} else {
ControlFlow::Break(())
}
}
}
}
}

View File

@@ -5,7 +5,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_span::Span;
use rustc_trait_selection::solve::Certainty;
use rustc_trait_selection::solve::inspect::{
InspectConfig, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor,
InferCtxtProofTreeExt, InspectConfig, InspectGoal, ProofTreeVisitor,
};
use tracing::{debug, instrument, trace};

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

@@ -10,9 +10,8 @@ use rustc_hir as hir;
use rustc_hir::LangItem;
use rustc_middle::bug;
use rustc_middle::ty::{
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, InstanceKind, IntTy,
List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
UintTy,
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef,
Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy,
};
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, sym};
@@ -459,6 +458,30 @@ pub(crate) fn transform_instance<'tcx>(
instance
}
fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option<DefId> {
match instance.def {
ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => {
tcx.opt_associated_item(def_id).map(|item| item.def_id)
}
_ => None,
}
}
/// Determines if an instance represents a trait method implementation and returns the necessary
/// information for type erasure.
///
/// This function handles two main cases:
///
/// * **Implementation in an `impl` block**: When the instance represents a concrete implementation
/// of a trait method in an `impl` block, it extracts the trait reference, method ID, and trait
/// ID from the implementation. The method ID is obtained from the `trait_item_def_id` field of
/// the associated item, which points to the original trait method definition.
///
/// * **Provided method in a `trait` block or synthetic `shim`**: When the instance represents a
/// default implementation provided in the trait definition itself or a synthetic shim, it uses
/// the instance's own `def_id` as the method ID and determines the trait ID from the associated
/// item.
///
fn implemented_method<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
@@ -476,10 +499,11 @@ fn implemented_method<'tcx>(
trait_id = trait_ref.skip_binder().def_id;
impl_id
} else if let AssocContainer::Trait = assoc.container
&& let InstanceKind::Item(def_id) = instance.def
&& let Some(trait_method_def_id) = default_or_shim(tcx, instance)
{
// Provided method in a `trait` block or a synthetic `shim`
trait_method = assoc;
method_id = def_id;
method_id = trait_method_def_id;
trait_id = tcx.parent(method_id);
trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc(tcx, trait_id, instance.args));
trait_id

View File

@@ -1386,10 +1386,12 @@ bitflags::bitflags! {
const DIAGNOSTICS = 1 << 1;
/// Apply remappings to debug information
const DEBUGINFO = 1 << 3;
/// Apply remappings to coverage information
const COVERAGE = 1 << 4;
/// An alias for `macro` and `debuginfo`. This ensures all paths in compiled
/// executables or libraries are remapped but not elsewhere.
const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits();
/// An alias for `macro`, `debuginfo` and `coverage`. This ensures all paths in compiled
/// executables, libraries and objects are remapped but not elsewhere.
const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits() | Self::COVERAGE.bits();
}
}

View File

@@ -869,8 +869,7 @@ mod desc {
pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)";
pub(crate) const parse_proc_macro_execution_strategy: &str =
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
pub(crate) const parse_remap_path_scope: &str =
"comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`";
pub(crate) const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`";
pub(crate) const parse_inlining_threshold: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
@@ -1705,6 +1704,7 @@ pub mod parse {
"macro" => RemapPathScopeComponents::MACRO,
"diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
"debuginfo" => RemapPathScopeComponents::DEBUGINFO,
"coverage" => RemapPathScopeComponents::COVERAGE,
"object" => RemapPathScopeComponents::OBJECT,
"all" => RemapPathScopeComponents::all(),
_ => return false,

View File

@@ -24,7 +24,7 @@ use tracing::instrument;
use self::derive_errors::*;
use super::Certainty;
use super::delegate::SolverDelegate;
use super::inspect::{self, ProofTreeInferCtxtExt};
use super::inspect::{self, InferCtxtProofTreeExt};
use crate::traits::{FulfillmentError, ScrubbedTraitError};
mod derive_errors;

View File

@@ -15,7 +15,7 @@ use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _}
use tracing::{instrument, trace};
use crate::solve::delegate::SolverDelegate;
use crate::solve::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
use crate::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
use crate::solve::{Certainty, deeply_normalize_for_diagnostics};
use crate::traits::{FulfillmentError, FulfillmentErrorCode, wf};

View File

@@ -463,7 +463,7 @@ pub trait ProofTreeVisitor<'tcx> {
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result;
}
#[extension(pub trait ProofTreeInferCtxtExt<'tcx>)]
#[extension(pub trait InferCtxtProofTreeExt<'tcx>)]
impl<'tcx> InferCtxt<'tcx> {
fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
&self,

View File

@@ -12,7 +12,7 @@ use rustc_middle::{bug, span_bug};
use rustc_span::Span;
use thin_vec::thin_vec;
use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
use crate::solve::inspect::{self, InferCtxtProofTreeExt};
#[extension(pub trait InferCtxtSelectExt<'tcx>)]
impl<'tcx> InferCtxt<'tcx> {

View File

@@ -29,7 +29,7 @@ use tracing::{debug, instrument, warn};
use super::ObligationCtxt;
use crate::error_reporting::traits::suggest_new_overflow_limit;
use crate::infer::InferOk;
use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
use crate::solve::inspect::{InferCtxtProofTreeExt, InspectGoal, ProofTreeVisitor};
use crate::solve::{SolverDelegate, deeply_normalize_for_diagnostics, inspect};
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::select::IntercrateAmbiguityCause;

View File

@@ -21,7 +21,9 @@ ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-gnu/bin
ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \
AR_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-ar \
CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++
CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++ \
CFLAGS_loongarch64_unknown_linux_gnu="-mcmodel=medium" \
CXXFLAGS_loongarch64_unknown_linux_gnu="-mcmodel=medium"
# We re-use the Linux toolchain for bare-metal, because upstream bare-metal
# target support for LoongArch is only available from GCC 14+.

View File

@@ -21,7 +21,9 @@ ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-musl/bin
ENV CC_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-gcc \
AR_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-ar \
CXX_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-g++
CXX_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-g++ \
CFLAGS_loongarch64_unknown_linux_musl="-mcmodel=medium" \
CXXFLAGS_loongarch64_unknown_linux_musl="-mcmodel=medium"
ENV HOSTS=loongarch64-unknown-linux-musl

View File

@@ -1 +1 @@
4fa824bb78318a3cba8c7339d5754b4909922547
b1b464d6f61ec8c4e609c1328106378c066a9729

View File

@@ -235,12 +235,6 @@ What this command does is:
- Build `library` (the standard libraries) with the stage1 compiler that was just built.
- Assemble a working stage1 sysroot, containing the stage1 compiler and stage1 standard libraries.
To build `rustc` with the in-tree `std`, use this command instead:
```console
./x build library --stage 2
```
This final product (stage1 compiler + libs built using that compiler)
is what you need to build other Rust programs (unless you use `#![no_std]` or
`#![no_core]`).

View File

@@ -52,9 +52,9 @@ channels: stable, beta, and nightly.
- **Stable**: this is the latest stable release for general usage.
- **Beta**: this is the next release (will be stable within 6 weeks).
- **Nightly**: follows the `master` branch of the repo. This is the only
channel where unstable, incomplete, or experimental features are usable with
feature gates.
- **Nightly**: follows the `master` branch of the repo.
This is the only channel where unstable features are intended to be used,
which happens via opt-in feature gates.
See [this chapter on implementing new features](./implementing_new_features.md) for more
information.

View File

@@ -56,6 +56,13 @@ fn main() {
unsafe extern "C" {
pub fn kernel_1(array_b: *mut [f64; 256]);
}
#[cfg(not(target_os = "linux"))]
#[unsafe(no_mangle)]
#[inline(never)]
pub extern "gpu-kernel" fn kernel_1(x: *mut [f64; 256]) {
unsafe { (*x)[0] = 21.0 };
}
```
## Compile instructions

View File

@@ -521,4 +521,25 @@ const EXPECTED = [
returned: [],
},
]
```
```
If the [`//@ revisions`] directive is used, the JS file will
have access to a variable called `REVISION`.
```js
const EXPECTED = [
// This first test targets name-based search.
{
query: "constructor",
others: REVISION === "has_constructor" ?
[
{ path: "constructor_search", name: "constructor" },
] :
[],
in_args: [],
returned: [],
},
];
```
[`//@ revisions`]: ../tests/compiletest.md#revisions

View File

@@ -9,8 +9,9 @@
## Target maintainers
[@chriswailes](https://github.com/chriswailes)
[@jfgoog](https://github.com/jfgoog)
[@maurer](https://github.com/maurer)
[@mgeisler](https://github.com/mgeisler)
[@pirama-arumuga-nainar](https://github.com/pirama-arumuga-nainar)
## Requirements

View File

@@ -10,7 +10,8 @@ This flag accepts a comma-separated list of values and may be specified multiple
- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from
- `diagnostics` - apply remappings to printed compiler diagnostics
- `debuginfo` - apply remappings to debug informations
- `debuginfo` - apply remappings to debug information
- `coverage` - apply remappings to coverage information
- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,debuginfo`.
- `all` - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`.

View File

@@ -3006,7 +3006,7 @@ impl<'test> TestCx<'test> {
self.delete_file(&examined_path);
}
// If we want them to be the same, but they are different, then error.
// We do this wether we bless or not
// We do this whether we bless or not
(_, true, false) => {
self.fatal_proc_rec(
&format!("`{}` should not have different output from base test!", kind),

View File

@@ -18,7 +18,9 @@ impl TestCx<'_> {
.arg("--crate-name")
.arg(file_stem.replace("-", "_"))
.arg("--test-file")
.arg(self.testpaths.file.with_extension("js")),
.arg(self.testpaths.file.with_extension("js"))
.arg("--revision")
.arg(self.revision.unwrap_or_default()),
);
if !res.status.success() {
self.fatal_proc_rec("rustdoc-js test failed!", &res);

View File

@@ -207,8 +207,12 @@ impl TestCx<'_> {
debug!(
"run_ui_test: explicit={:?} config.compare_mode={:?} \
proc_res.status={:?} props.error_patterns={:?}",
explicit, self.config.compare_mode, proc_res.status, self.props.error_patterns
proc_res.status={:?} props.error_patterns={:?} output_to_check={:?}",
explicit,
self.config.compare_mode,
proc_res.status,
self.props.error_patterns,
output_to_check,
);
// Compiler diagnostics (expected errors) are always tied to the compile-time ProcRes.

View File

@@ -364,10 +364,10 @@ function hasCheck(content, checkName) {
return content.startsWith(`const ${checkName}`) || content.includes(`\nconst ${checkName}`);
}
async function runChecks(testFile, doSearch, parseQuery) {
async function runChecks(testFile, doSearch, parseQuery, revision) {
let checkExpected = false;
let checkParsed = false;
let testFileContent = readFile(testFile);
let testFileContent = `const REVISION = "${revision}";\n${readFile(testFile)}`;
if (testFileContent.indexOf("FILTER_CRATE") !== -1) {
testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;";
@@ -548,6 +548,7 @@ function parseOptions(args) {
"doc_folder": "",
"test_folder": "",
"test_file": [],
"revision": "",
};
const correspondences = {
"--resource-suffix": "resource_suffix",
@@ -555,6 +556,7 @@ function parseOptions(args) {
"--test-folder": "test_folder",
"--test-file": "test_file",
"--crate-name": "crate_name",
"--revision": "revision",
};
for (let i = 0; i < args.length; ++i) {
@@ -611,7 +613,7 @@ async function main(argv) {
if (opts["test_file"].length !== 0) {
for (const file of opts["test_file"]) {
process.stdout.write(`Testing ${file} ... `);
errors += await runChecks(file, doSearch, parseAndSearch.parseQuery);
errors += await runChecks(file, doSearch, parseAndSearch.parseQuery, opts.revision);
}
} else if (opts["test_folder"].length !== 0) {
for (const file of fs.readdirSync(opts["test_folder"])) {
@@ -619,7 +621,7 @@ async function main(argv) {
continue;
}
process.stdout.write(`Testing ${file} ... `);
errors += await runChecks(path.join(opts["test_folder"], file), doSearch,
errors += await runChecks(path.join(opts["test_folder"], file, ""), doSearch,
parseAndSearch.parseQuery);
}
}

View File

@@ -0,0 +1,17 @@
// This test makes sure that the files used in the coverage are remapped by
// `--remap-path-prefix` and the `coverage` <- `object` scopes.
//
// We also test the `macro` scope to make sure it does not affect coverage.
// When coverage paths are remapped, the coverage-run mode can't find source files (because
// it doesn't know about the remapping), so it produces an empty coverage report. The empty
// report (i.e. no `.coverage` files) helps to demonstrate that remapping was indeed performed.
//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//
//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage
//@[with_object_scope] compile-flags: -Zremap-path-scope=object
//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro
fn main() {}

View File

@@ -0,0 +1,10 @@
Function name: remap_path_prefix::main
Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => remapped/remap-path-prefix.rs
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0

View File

@@ -0,0 +1,10 @@
Function name: remap_path_prefix::main
Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => $DIR/remap-path-prefix.rs
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0

View File

@@ -0,0 +1,18 @@
LL| |// This test makes sure that the files used in the coverage are remapped by
LL| |// `--remap-path-prefix` and the `coverage` <- `object` scopes.
LL| |//
LL| |// We also test the `macro` scope to make sure it does not affect coverage.
LL| |
LL| |// When coverage paths are remapped, the coverage-run mode can't find source files (because
LL| |// it doesn't know about the remapping), so it produces an empty coverage report. The empty
LL| |// report (i.e. no `.coverage` files) helps to demonstrate that remapping was indeed performed.
LL| |
LL| |//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope
LL| |//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
LL| |//
LL| |//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage
LL| |//@[with_object_scope] compile-flags: -Zremap-path-scope=object
LL| |//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro
LL| |
LL| 1|fn main() {}

View File

@@ -0,0 +1,10 @@
Function name: remap_path_prefix::main
Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => remapped/remap-path-prefix.rs
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0

View File

@@ -0,0 +1,10 @@
Function name: remap_path_prefix::main
Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
Number of files: 1
- file 0 => remapped/remap-path-prefix.rs
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
Highest counter ID seen: c0

View File

@@ -1,5 +1,4 @@
//@ ignore-android
//@ ignore-aarch64
//@ min-lldb-version: 1800
//@ min-gdb-version: 13.0

View File

@@ -0,0 +1,6 @@
//@ unique-doc-out-dir
//@ doc-flags:--merge=none
//@ doc-flags:--parts-out-dir=info/doc.parts/merged-dep
//@ doc-flags:-Zunstable-options
pub struct Dep;

View File

@@ -0,0 +1,15 @@
const EXPECTED = [
{
'query': 'merged_doc::Doc',
'others': [
{ 'path': 'merged_doc', 'name': 'Doc' },
],
},
{
'query': 'merged_dep::Dep',
'others': REVISION === "nomerge" ? [] :
[
{ 'path': 'merged_dep', 'name': 'Dep' },
],
},
];

View File

@@ -0,0 +1,10 @@
//@ revisions: merge nomerge
//@ aux-build:merged-dep.rs
//@ build-aux-docs
//@[merge] doc-flags:--merge=finalize
//@[merge] doc-flags:--include-parts-dir=info/doc.parts/merged-dep
//@[merge] doc-flags:-Zunstable-options
extern crate merged_dep;
pub struct Doc;

View File

@@ -1,5 +1,5 @@
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:8:23
--> $DIR/dst-object-from-unsized-type.rs:11:23
|
LL | fn test1<T: ?Sized + Foo>(t: &T) {
| - this type parameter needs to be `Sized`
@@ -14,7 +14,7 @@ LL + fn test1<T: Foo>(t: &T) {
|
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:13:23
--> $DIR/dst-object-from-unsized-type.rs:17:23
|
LL | fn test2<T: ?Sized + Foo>(t: &T) {
| - this type parameter needs to be `Sized`
@@ -29,7 +29,7 @@ LL + fn test2<T: Foo>(t: &T) {
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:18:28
--> $DIR/dst-object-from-unsized-type.rs:23:28
|
LL | let _: &[&dyn Foo] = &["hi"];
| ^^^^ doesn't have a size known at compile-time
@@ -38,7 +38,7 @@ LL | let _: &[&dyn Foo] = &["hi"];
= note: required for the cast from `&'static str` to `&dyn Foo`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/dst-object-from-unsized-type.rs:23:23
--> $DIR/dst-object-from-unsized-type.rs:29:23
|
LL | let _: &dyn Foo = x as &dyn Foo;
| ^ doesn't have a size known at compile-time

View File

@@ -0,0 +1,57 @@
error[E0277]: the trait bound `&T: CoerceUnsized<&dyn Foo>` is not satisfied in `T`
--> $DIR/dst-object-from-unsized-type.rs:11:23
|
LL | fn test1<T: ?Sized + Foo>(t: &T) {
| - this type parameter needs to be `Sized`
LL | let u: &dyn Foo = t;
| ^ within `T`, the trait `Sized` is not implemented for `T`
|
= note: required because it appears within the type `T`
= note: required for `&T` to implement `CoerceUnsized<&dyn Foo>`
= note: required for the cast from `&T` to `&dyn Foo`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn test1<T: ?Sized + Foo>(t: &T) {
LL + fn test1<T: Foo>(t: &T) {
|
error[E0277]: the trait bound `&T: CoerceUnsized<&dyn Foo>` is not satisfied in `T`
--> $DIR/dst-object-from-unsized-type.rs:17:23
|
LL | fn test2<T: ?Sized + Foo>(t: &T) {
| - this type parameter needs to be `Sized`
LL | let v: &dyn Foo = t as &dyn Foo;
| ^ within `T`, the trait `Sized` is not implemented for `T`
|
= note: required because it appears within the type `T`
= note: required for `&T` to implement `CoerceUnsized<&dyn Foo>`
= note: required for the cast from `&T` to `&dyn Foo`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn test2<T: ?Sized + Foo>(t: &T) {
LL + fn test2<T: Foo>(t: &T) {
|
error[E0277]: the trait bound `&str: CoerceUnsized<&dyn Foo>` is not satisfied in `str`
--> $DIR/dst-object-from-unsized-type.rs:23:28
|
LL | let _: &[&dyn Foo] = &["hi"];
| ^^^^ within `str`, the trait `Sized` is not implemented for `str`
|
= note: `str` is considered to contain a `[u8]` slice for auto trait purposes
= note: required for `&str` to implement `CoerceUnsized<&dyn Foo>`
= note: required for the cast from `&'static str` to `&dyn Foo`
error[E0277]: the trait bound `&[u8]: CoerceUnsized<&dyn Foo>` is not satisfied in `[u8]`
--> $DIR/dst-object-from-unsized-type.rs:29:23
|
LL | let _: &dyn Foo = x as &dyn Foo;
| ^ within `[u8]`, the trait `Sized` is not implemented for `[u8]`
|
= note: required because it appears within the type `[u8]`
= note: required for `&[u8]` to implement `CoerceUnsized<&dyn Foo>`
= note: required for the cast from `&[u8]` to `&dyn Foo`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@@ -1,4 +1,7 @@
// Test that we cannot create objects from unsized types.
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
trait Foo { fn foo(&self) {} }
impl Foo for str {}
@@ -6,22 +9,26 @@ impl Foo for [u8] {}
fn test1<T: ?Sized + Foo>(t: &T) {
let u: &dyn Foo = t;
//~^ ERROR the size for values of type
//[current]~^ ERROR the size for values of type
//[next]~^^ ERROR the trait bound `&T: CoerceUnsized<&dyn Foo>` is not satisfied in `T`
}
fn test2<T: ?Sized + Foo>(t: &T) {
let v: &dyn Foo = t as &dyn Foo;
//~^ ERROR the size for values of type
//[current]~^ ERROR the size for values of type
//[next]~^^ ERROR the trait bound `&T: CoerceUnsized<&dyn Foo>` is not satisfied in `T`
}
fn test3() {
let _: &[&dyn Foo] = &["hi"];
//~^ ERROR the size for values of type
//[current]~^ ERROR the size for values of type
//[next]~^^ ERROR the trait bound `&str: CoerceUnsized<&dyn Foo>` is not satisfied in `str`
}
fn test4(x: &[u8]) {
let _: &dyn Foo = x as &dyn Foo;
//~^ ERROR the size for values of type
//[current]~^ ERROR the size for values of type
//[next]~^^ ERROR the trait bound `&[u8]: CoerceUnsized<&dyn Foo>` is not satisfied in `[u8]`
}
fn main() { }

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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -0,0 +1,32 @@
// Verifies that types that implement the Fn, FnMut, or FnOnce traits can be
// called through their trait methods.
//
//@ needs-sanitizer-cfi
//@ only-linux
//@ ignore-backends: gcc
//@ compile-flags: -Ctarget-feature=-crt-static -Ccodegen-units=1 -Clto -Cprefer-dynamic=off -Copt-level=0 -Zsanitizer=cfi -Cunsafe-allow-abi-mismatch=sanitizer --test
//@ run-pass
#![feature(fn_traits)]
#![feature(unboxed_closures)]
fn foo(_a: u32) {}
#[test]
fn test_fn_trait() {
let f: Box<dyn Fn(u32)> = Box::new(foo);
Fn::call(&f, (0,));
}
#[test]
fn test_fnmut_trait() {
let mut a = 0;
let mut f: Box<dyn FnMut(u32)> = Box::new(|x| a += x);
FnMut::call_mut(&mut f, (1,));
}
#[test]
fn test_fnonce_trait() {
let f: Box<dyn FnOnce(u32)> = Box::new(foo);
FnOnce::call_once(f, (2,));
}

View File

@@ -1,11 +1,7 @@
//@ needs-sanitizer-support
//@ needs-sanitizer-hwaddress
//
// FIXME(#83706): this test triggers errors on aarch64-gnu
//@ ignore-aarch64-unknown-linux-gnu
//
// FIXME(#83989): codegen-units=1 triggers linker errors on aarch64-gnu
//@ compile-flags: -Z sanitizer=hwaddress -O -g -C codegen-units=16 -C unsafe-allow-abi-mismatch=sanitizer
//@ compile-flags: -Z sanitizer=hwaddress -O -g -C target-feature=+tagged-globals -C unsafe-allow-abi-mismatch=sanitizer
//
//@ run-fail
//@ error-pattern: HWAddressSanitizer: tag-mismatch
@@ -19,3 +15,5 @@ fn main() {
let code = unsafe { *xs.offset(4) };
std::process::exit(code);
}
//~? WARN unknown and unstable feature specified for `-Ctarget-feature`: `tagged-globals`

View File

@@ -0,0 +1,7 @@
warning: unknown and unstable feature specified for `-Ctarget-feature`: `tagged-globals`
|
= note: it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
= help: consider filing a feature request
warning: 1 warning emitted

View File

@@ -0,0 +1,32 @@
// Verifies that types that implement the Fn, FnMut, or FnOnce traits can be
// called through their trait methods.
//
//@ needs-sanitizer-kcfi
//@ only-linux
//@ ignore-backends: gcc
//@ compile-flags: -Ctarget-feature=-crt-static -Zpanic_abort_tests -Cpanic=abort -Cprefer-dynamic=off -Copt-level=0 -Zsanitizer=kcfi -Cunsafe-allow-abi-mismatch=sanitizer --test
//@ run-pass
#![feature(fn_traits)]
#![feature(unboxed_closures)]
fn foo(_a: u32) {}
#[test]
fn test_fn_trait() {
let f: Box<dyn Fn(u32)> = Box::new(foo);
Fn::call(&f, (0,));
}
#[test]
fn test_fnmut_trait() {
let mut a = 0;
let mut f: Box<dyn FnMut(u32)> = Box::new(|x| a += x);
FnMut::call_mut(&mut f, (1,));
}
#[test]
fn test_fnonce_trait() {
let f: Box<dyn FnOnce(u32)> = Box::new(foo);
FnOnce::call_once(f, (2,));
}

View File

@@ -0,0 +1,13 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
--> $DIR/unsize-goal-mismatch-2.rs:15:5
|
LL | x
| ^
|
= note: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
= note: required for `Box<dyn Trait<&()>>` to implement `CoerceUnsized<Box<dyn Super<&()>>>`
= note: required for the cast from `Box<(dyn Trait<&'a ()> + 'static)>` to `Box<(dyn Super<&'a ()> + 'static)>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@@ -0,0 +1,19 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@[current] check-pass
// Test from trait-system-refactor-initiative#241:
// Used to ICE in mir typeck because of ambiguity in the new solver.
// The wrong (first) trait bound was selected.
// This is fixed with new logic for unsizing coercions
// that's independent from that of the old solver, which this test verifies.
trait Super<T> {}
trait Trait<T>: Super<T> + for<'hr> Super<&'hr ()> {}
fn foo<'a>(x: Box<dyn Trait<&'a ()>>) -> Box<dyn Super<&'a ()>> {
x
//[next]~^ ERROR type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize<dyn Super<&()>>`
}
fn main() {}

View File

@@ -0,0 +1,17 @@
error[E0283]: type annotations needed: cannot satisfy `Self: Super<'a>`
--> $DIR/unsize-goal-mismatch.rs:11:18
|
LL | trait Trait<'a>: Super<'a> + for<'hr> Super<'hr> {}
| ^^^^^^^^^
|
note: multiple `impl`s or `where` clauses satisfying `Self: Super<'a>` found
--> $DIR/unsize-goal-mismatch.rs:10:1
|
LL | trait Super<'a> {}
| ^^^^^^^^^^^^^^^
LL | trait Trait<'a>: Super<'a> + for<'hr> Super<'hr> {}
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@@ -0,0 +1,13 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<'_>: Unsize<dyn Super<'_>>`
--> $DIR/unsize-goal-mismatch.rs:15:5
|
LL | x
| ^
|
= note: cannot satisfy `dyn Trait<'_>: Unsize<dyn Super<'_>>`
= note: required for `Box<dyn Trait<'_>>` to implement `CoerceUnsized<Box<dyn Super<'_>>>`
= note: required for the cast from `Box<(dyn Trait<'a> + 'static)>` to `Box<(dyn Super<'a> + 'static)>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@@ -0,0 +1,19 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Test from trait-system-refactor-initiative#241:
// Used to ICE in mir typeck because of ambiguity in the new solver.
// The wrong (first) trait bound was selected.
// This is fixed with new logic for unsizing coercions
// that's independent from that of the old solver, which this test verifies.
trait Super<'a> {}
trait Trait<'a>: Super<'a> + for<'hr> Super<'hr> {}
//[current]~^ ERROR type annotations needed: cannot satisfy `Self: Super<'a>`
fn foo<'a>(x: Box<dyn Trait<'a>>) -> Box<dyn Super<'a>> {
x
//[next]~^ ERROR type annotations needed: cannot satisfy `dyn Trait<'_>: Unsize<dyn Super<'_>>
}
fn main() {}

View File

@@ -0,0 +1,7 @@
//@ compile-flags: -Znext-solver
#![recursion_limit = "8"]
fn main() {
let _: Box<dyn Send> = Box::new(&&&&&&&1);
//~^ ERROR overflow evaluating the requirement `Box<&&&&&&&i32>: CoerceUnsized<Box<dyn Send>>
}

View File

@@ -0,0 +1,12 @@
error[E0275]: overflow evaluating the requirement `Box<&&&&&&&i32>: CoerceUnsized<Box<dyn Send>>`
--> $DIR/unsize-overflow.rs:5:28
|
LL | let _: Box<dyn Send> = Box::new(&&&&&&&1);
| ^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`unsize_overflow`)
= note: required for the cast from `Box<&&&&&&&i32>` to `Box<dyn Send>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.

View File

@@ -1,14 +1,13 @@
error[E0308]: mismatched types
error[E0277]: the trait bound `&dyn for<'a> Subtrait<'a, 'a>: CoerceUnsized<&dyn for<'a, 'b> Supertrait<'a, 'b>>` is not satisfied
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
| ----------------------------------- expected `&dyn for<'a, 'b> Supertrait<'a, 'b>` because of return type
LL | x
| ^ expected trait `Supertrait`, found trait `Subtrait`
| ^ the trait `Unsize<dyn for<'a, 'b> Supertrait<'a, 'b>>` is not implemented for `dyn for<'a> Subtrait<'a, 'a>`
|
= note: expected reference `&dyn for<'a, 'b> Supertrait<'a, 'b>`
found reference `&dyn for<'a> Subtrait<'a, 'a>`
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
= note: required for `&dyn for<'a> Subtrait<'a, 'a>` to implement `CoerceUnsized<&dyn for<'a, 'b> Supertrait<'a, 'b>>`
= note: required for the cast from `&dyn for<'a> Subtrait<'a, 'a>` to `&dyn for<'a, 'b> Supertrait<'a, 'b>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0277`.

View File

@@ -19,8 +19,10 @@ impl<'a> Supertrait<'a, 'a> for () {
}
impl<'a> Subtrait<'a, 'a> for () {}
fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
x //~ ERROR mismatched types
x
//[current]~^ ERROR mismatched types
//[current]~| ERROR mismatched types
//[next]~^^^ ERROR the trait bound `&dyn for<'a> Subtrait<'a, 'a>: CoerceUnsized<&dyn for<'a, 'b> Supertrait<'a, 'b>>` is not satisfied
}
fn transmute<'a, 'b>(x: &'a str) -> &'b str {