diff --git a/.mailmap b/.mailmap index fc8e83d6493cd..6c168bbbcb554 100644 --- a/.mailmap +++ b/.mailmap @@ -680,6 +680,7 @@ Valerii Lashmanov Vitali Haravy Vitali Haravy Vitaly Shukela Waffle Lapkin +Waffle Lapkin Waffle Lapkin Weihang Lo Weihang Lo diff --git a/RELEASES.md b/RELEASES.md index aa5f37fffebff..74b0d4424c163 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,214 @@ +Version 1.91.0 (2025-10-30) +========================== + + + +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. + + + +Compiler +-------- + +- [Don't warn on never-to-any `as` casts as unreachable](https://github.com/rust-lang/rust/pull/144804) + + + +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 + + + +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. + + + +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 for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3Cstr%3E-for-PathBuf) +- [`impl PartialEq for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf) +- [`impl PartialEq for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path) +- [`impl PartialEq for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path) +- [`impl PartialEq for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String) +- [`impl PartialEq for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String) +- [`impl PartialEq for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str) +- [`impl PartialEq 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 Default for Pin> where Box: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CBox%3CT%3E%3E) +- [`impl Default for Pin> where Rc: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CRc%3CT%3E%3E) +- [`impl Default for Pin> where Arc: 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`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum-for-Saturating%3Cu32%3E) +- [`impl Sum<&Self> for Saturating`](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`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product-for-Saturating%3Cu32%3E) +- [`impl Product<&Self> for Saturating`](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) + + + +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) + + + +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. + + + +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` 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)). + + + +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) =========================== diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 8a0dbadf18cdf..4108671a3629e 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -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(); diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 7e873347c82b0..b3a11f8b12bfc 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -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()); diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index b5cf6c4c3723c..1e18a22be81c2 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -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 . To instruct `tracing_chrome` to put some spans on a separate trace /// thread/line than other spans when viewed in , you can pass /// `tracing_separate_thread = tracing::field::Empty` to the tracing macros. This is useful to diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 95b47c8aba671..25ab91ebc9cfa 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -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>, + } + 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> { // 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| { + 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( - "zero-sized fields in `repr(transparent)` cannot \ - contain external non-exhaustive types", + format!("zero-sized fields in `repr(transparent)` cannot contain {title}"), ); - let note = if non_exhaustive { - "is marked with `#[non_exhaustive]`" - } else { - "contains private fields" + 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; } } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 1e5fea1db9fcc..857e4f66489ab 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -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`. 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>, 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(()) + } + } + } + } +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 82a68c4d615a9..1ab7ac4c2e361 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -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}; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b4c18483a923b..faaeb7706e399 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -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 diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 1e965083d6699..8c474ed28240c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -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 - /// = 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 + /// = 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 ", + report_in_deps: true, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 40a818a3c9dc7..ec26c35ffdc9f 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -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 diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 021b206e1e2ef..28481f3dcdb3d 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -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 { + 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 diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8ff6d567422b9..60e301a5fd870 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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(); } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 6dd90546de1b0..b89aec7d22a91 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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 = ":::. 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, diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index ddd79e1dc9405..7b61a653ae31e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -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; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 598de27dfd3cb..8482c8a2972dc 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -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}; diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 488315054c6aa..cdbf2b0aeb834 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -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>( &self, diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index d7e7ffd5d28c6..1feaab2404153 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -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> { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index f0c006b5e3f6c..45357be563998 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -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; diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index e3f23149284e5..4b86ed32fd55f 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -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+. diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 2c33b5526eebc..763b29ae1c5e9 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -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 diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 47552aee08f74..f100e41166860 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -4fa824bb78318a3cba8c7339d5754b4909922547 +b1b464d6f61ec8c4e609c1328106378c066a9729 diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index ace834a55b71f..efb21726e3c6a 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -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]`). diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index b4c8f9e9a58c0..44d630080bbfa 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -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. diff --git a/src/doc/rustc-dev-guide/src/offload/usage.md b/src/doc/rustc-dev-guide/src/offload/usage.md index 9f519984d9bcc..7d1a5c9e2e0ed 100644 --- a/src/doc/rustc-dev-guide/src/offload/usage.md +++ b/src/doc/rustc-dev-guide/src/offload/usage.md @@ -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 diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index a54288f8f050e..dcf7659130a38 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -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 diff --git a/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md b/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md index 65219dc68e976..fb1c7d7a68789 100644 --- a/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md +++ b/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md @@ -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`. diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 16b604e9df821..b82a533271c17 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -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), diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index d683a325c8666..c0adb6302e9d0 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -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. diff --git a/tests/coverage/remap-path-prefix.rs b/tests/coverage/remap-path-prefix.rs new file mode 100644 index 0000000000000..29c5826989c44 --- /dev/null +++ b/tests/coverage/remap-path-prefix.rs @@ -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() {} diff --git a/tests/coverage/remap-path-prefix.with_coverage_scope.cov-map b/tests/coverage/remap-path-prefix.with_coverage_scope.cov-map new file mode 100644 index 0000000000000..35731d71116f7 --- /dev/null +++ b/tests/coverage/remap-path-prefix.with_coverage_scope.cov-map @@ -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 + diff --git a/tests/coverage/remap-path-prefix.with_macro_scope.cov-map b/tests/coverage/remap-path-prefix.with_macro_scope.cov-map new file mode 100644 index 0000000000000..551e286768854 --- /dev/null +++ b/tests/coverage/remap-path-prefix.with_macro_scope.cov-map @@ -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 + diff --git a/tests/coverage/remap-path-prefix.with_macro_scope.coverage b/tests/coverage/remap-path-prefix.with_macro_scope.coverage new file mode 100644 index 0000000000000..63979d8fe15a5 --- /dev/null +++ b/tests/coverage/remap-path-prefix.with_macro_scope.coverage @@ -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() {} + diff --git a/tests/coverage/remap-path-prefix.with_object_scope.cov-map b/tests/coverage/remap-path-prefix.with_object_scope.cov-map new file mode 100644 index 0000000000000..35731d71116f7 --- /dev/null +++ b/tests/coverage/remap-path-prefix.with_object_scope.cov-map @@ -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 + diff --git a/tests/coverage/remap-path-prefix.with_remap.cov-map b/tests/coverage/remap-path-prefix.with_remap.cov-map new file mode 100644 index 0000000000000..35731d71116f7 --- /dev/null +++ b/tests/coverage/remap-path-prefix.with_remap.cov-map @@ -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 + diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index 35bb6de4fef38..e58975764e533 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -1,5 +1,4 @@ //@ ignore-android -//@ ignore-aarch64 //@ min-lldb-version: 1800 //@ min-gdb-version: 13.0 diff --git a/tests/ui/dst/dst-object-from-unsized-type.stderr b/tests/ui/dst/dst-object-from-unsized-type.current.stderr similarity index 90% rename from tests/ui/dst/dst-object-from-unsized-type.stderr rename to tests/ui/dst/dst-object-from-unsized-type.current.stderr index cbb7dc5e9f421..be9966743d4ee 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.stderr +++ b/tests/ui/dst/dst-object-from-unsized-type.current.stderr @@ -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: &T) { | - this type parameter needs to be `Sized` @@ -14,7 +14,7 @@ LL + fn test1(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: &T) { | - this type parameter needs to be `Sized` @@ -29,7 +29,7 @@ LL + fn test2(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 diff --git a/tests/ui/dst/dst-object-from-unsized-type.next.stderr b/tests/ui/dst/dst-object-from-unsized-type.next.stderr new file mode 100644 index 0000000000000..032ba0cb14aeb --- /dev/null +++ b/tests/ui/dst/dst-object-from-unsized-type.next.stderr @@ -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: &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: &T) { +LL + fn test1(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: &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: &T) { +LL + fn test2(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`. diff --git a/tests/ui/dst/dst-object-from-unsized-type.rs b/tests/ui/dst/dst-object-from-unsized-type.rs index 3cd5b1ed6f462..1e6113b3fc6fb 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.rs +++ b/tests/ui/dst/dst-object-from-unsized-type.rs @@ -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: &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: &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() { } diff --git a/tests/ui/lint/improper-ctypes/lint-ctypes.rs b/tests/ui/lint/improper-ctypes/lint-ctypes.rs index 7dc06079fa32c..5d90e22e4b492 100644 --- a/tests/ui/lint/improper-ctypes/lint-ctypes.rs +++ b/tests/ui/lint/improper-ctypes/lint-ctypes.rs @@ -38,6 +38,7 @@ pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>); #[repr(transparent)] pub struct TransparentUnit(f32, PhantomData); #[repr(transparent)] +#[allow(repr_transparent_non_zst_fields)] pub struct TransparentCustomZst(i32, ZeroSize); #[repr(C)] diff --git a/tests/ui/lint/improper-ctypes/lint-ctypes.stderr b/tests/ui/lint/improper-ctypes/lint-ctypes.stderr index 6f8b951c53d70..ef23f3ca6c919 100644 --- a/tests/ui/lint/improper-ctypes/lint-ctypes.stderr +++ b/tests/ui/lint/improper-ctypes/lint-ctypes.stderr @@ -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`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:53:24 + --> $DIR/lint-ctypes.rs:54:24 | LL | pub fn box_type(p: Box); | ^^^^^^^^ not FFI-safe @@ -68,7 +68,7 @@ LL | pub fn box_type(p: Box); = 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); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `PhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:63:12 + --> $DIR/lint-ctypes.rs:64:12 | LL | -> ::std::marker::PhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -138,7 +138,7 @@ LL | -> ::std::marker::PhantomData; = 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`, 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`, 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>`, 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>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -201,7 +201,7 @@ LL | pub fn no_niche_a(a: Option>); = note: enum has no representation hint error: `extern` block uses type `Option>`, 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>); | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -211,3 +211,14 @@ LL | pub fn no_niche_b(b: Option>); 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 + = note: this field contains `ZeroSize`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets. + diff --git a/tests/ui/lint/improper-ctypes/lint-fn.rs b/tests/ui/lint/improper-ctypes/lint-fn.rs index 0b84098e39067..e71febb493dc4 100644 --- a/tests/ui/lint/improper-ctypes/lint-fn.rs +++ b/tests/ui/lint/improper-ctypes/lint-fn.rs @@ -54,6 +54,7 @@ pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>); pub struct TransparentUnit(f32, PhantomData); #[repr(transparent)] +#[allow(repr_transparent_non_zst_fields)] pub struct TransparentCustomZst(i32, ZeroSize); #[repr(C)] diff --git a/tests/ui/lint/improper-ctypes/lint-fn.stderr b/tests/ui/lint/improper-ctypes/lint-fn.stderr index 34e3bd021b92d..a0d1ab232c6ad 100644 --- a/tests/ui/lint/improper-ctypes/lint-fn.stderr +++ b/tests/ui/lint/improper-ctypes/lint-fn.stderr @@ -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`, 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) { } | ^^^^^^^^ not FFI-safe @@ -38,7 +38,7 @@ LL | pub extern "C" fn boxed_string(p: Box) { } = note: box cannot be represented as a single pointer error: `extern` fn uses type `Box`, 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) { } | ^^^^^^^^^^^^^^ not FFI-safe @@ -46,7 +46,7 @@ LL | pub extern "C" fn boxed_trait(p: Box) { } = 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); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` fn uses type `PhantomData`, 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 { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -108,7 +108,7 @@ LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData { = 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`, which is not FFI-safe - --> $DIR/lint-fn.rs:169:43 + --> $DIR/lint-fn.rs:170:43 | LL | pub extern "C" fn unused_generic2() -> PhantomData { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -143,7 +143,7 @@ LL | pub extern "C" fn unused_generic2() -> PhantomData { = note: composed only of `PhantomData` error: `extern` fn uses type `Vec`, which is not FFI-safe - --> $DIR/lint-fn.rs:182:39 + --> $DIR/lint-fn.rs:183:39 | LL | pub extern "C" fn used_generic4(x: Vec) { } | ^^^^^^ not FFI-safe @@ -152,7 +152,7 @@ LL | pub extern "C" fn used_generic4(x: Vec) { } = note: this struct has unspecified layout error: `extern` fn uses type `Vec`, which is not FFI-safe - --> $DIR/lint-fn.rs:185:41 + --> $DIR/lint-fn.rs:186:41 | LL | pub extern "C" fn used_generic5() -> Vec { | ^^^^^^ not FFI-safe @@ -162,3 +162,14 @@ LL | pub extern "C" fn used_generic5() -> Vec { 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 + = note: this field contains `ZeroSize`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets. + diff --git a/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs index 6ab34719f0664..8de25ab266290 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs +++ b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs @@ -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 diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.rs b/tests/ui/repr/repr-transparent-non-exhaustive.rs index 38bab0163b4c5..9188d6df3446f 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.rs +++ b/tests/ui/repr/repr-transparent-non-exhaustive.rs @@ -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); -//~^ 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); #[repr(transparent)] pub struct T13(Sized, ExternalIndirection); -//~^ 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)] diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.stderr b/tests/ui/repr/repr-transparent-non-exhaustive.stderr index 27ba6e82a539a..ac5493bf7e59c 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.stderr +++ b/tests/ui/repr/repr-transparent-non-exhaustive.stderr @@ -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 - = 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 - = 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, ::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 - = 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 - = 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 - = 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); @@ -61,7 +61,7 @@ LL | pub struct T9(Sized, InternalIndirection); | = 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 - = 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); | = 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 - = 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); | = 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 - = 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); | = 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 - = 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); @@ -101,7 +101,7 @@ LL | pub struct T13(Sized, ExternalIndirection); | = 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 - = 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); | = 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 - = 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); | = 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 - = 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); | = 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 - = 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 - = 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 - = 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 - = 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 - = 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 + = 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 + = 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, ::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 + = 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 + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 + = 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 + = 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 + = 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 + = 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 + = 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)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/repr/repr-transparent-repr-c.rs b/tests/ui/repr/repr-transparent-repr-c.rs new file mode 100644 index 0000000000000..c887c443f3fcd --- /dev/null +++ b/tests/ui/repr/repr-transparent-repr-c.rs @@ -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() {} diff --git a/tests/ui/repr/repr-transparent-repr-c.stderr b/tests/ui/repr/repr-transparent-repr-c.stderr new file mode 100644 index 0000000000000..5724845afdc1e --- /dev/null +++ b/tests/ui/repr/repr-transparent-repr-c.stderr @@ -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 + = 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 + = 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 + = 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 + = 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 + = 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 + = 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)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/sanitizer/cfi/fn-trait-objects.rs b/tests/ui/sanitizer/cfi/fn-trait-objects.rs new file mode 100644 index 0000000000000..977d4124fff0c --- /dev/null +++ b/tests/ui/sanitizer/cfi/fn-trait-objects.rs @@ -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 = Box::new(foo); + Fn::call(&f, (0,)); +} + +#[test] +fn test_fnmut_trait() { + let mut a = 0; + let mut f: Box = Box::new(|x| a += x); + FnMut::call_mut(&mut f, (1,)); +} + +#[test] +fn test_fnonce_trait() { + let f: Box = Box::new(foo); + FnOnce::call_once(f, (2,)); +} diff --git a/tests/ui/sanitizer/hwaddress.rs b/tests/ui/sanitizer/hwaddress.rs index 05fcab17506b9..8666e7de44924 100644 --- a/tests/ui/sanitizer/hwaddress.rs +++ b/tests/ui/sanitizer/hwaddress.rs @@ -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` diff --git a/tests/ui/sanitizer/hwaddress.stderr b/tests/ui/sanitizer/hwaddress.stderr new file mode 100644 index 0000000000000..37afe0bd779ec --- /dev/null +++ b/tests/ui/sanitizer/hwaddress.stderr @@ -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 + diff --git a/tests/ui/sanitizer/kcfi/fn-trait-objects.rs b/tests/ui/sanitizer/kcfi/fn-trait-objects.rs new file mode 100644 index 0000000000000..3f6b78545a0a1 --- /dev/null +++ b/tests/ui/sanitizer/kcfi/fn-trait-objects.rs @@ -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 = Box::new(foo); + Fn::call(&f, (0,)); +} + +#[test] +fn test_fnmut_trait() { + let mut a = 0; + let mut f: Box = Box::new(|x| a += x); + FnMut::call_mut(&mut f, (1,)); +} + +#[test] +fn test_fnonce_trait() { + let f: Box = Box::new(foo); + FnOnce::call_once(f, (2,)); +} diff --git a/tests/ui/traits/next-solver/unsize-goal-mismatch-2.next.stderr b/tests/ui/traits/next-solver/unsize-goal-mismatch-2.next.stderr new file mode 100644 index 0000000000000..b415db33addbf --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-goal-mismatch-2.next.stderr @@ -0,0 +1,13 @@ +error[E0283]: type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize>` + --> $DIR/unsize-goal-mismatch-2.rs:15:5 + | +LL | x + | ^ + | + = note: cannot satisfy `dyn Trait<&()>: Unsize>` + = note: required for `Box>` to implement `CoerceUnsized>>` + = 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`. diff --git a/tests/ui/traits/next-solver/unsize-goal-mismatch-2.rs b/tests/ui/traits/next-solver/unsize-goal-mismatch-2.rs new file mode 100644 index 0000000000000..2b174eac5c151 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-goal-mismatch-2.rs @@ -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 {} +trait Trait: Super + for<'hr> Super<&'hr ()> {} + +fn foo<'a>(x: Box>) -> Box> { + x + //[next]~^ ERROR type annotations needed: cannot satisfy `dyn Trait<&()>: Unsize>` +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/unsize-goal-mismatch.current.stderr b/tests/ui/traits/next-solver/unsize-goal-mismatch.current.stderr new file mode 100644 index 0000000000000..278a68e154714 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-goal-mismatch.current.stderr @@ -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`. diff --git a/tests/ui/traits/next-solver/unsize-goal-mismatch.next.stderr b/tests/ui/traits/next-solver/unsize-goal-mismatch.next.stderr new file mode 100644 index 0000000000000..cfb978240cbc6 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-goal-mismatch.next.stderr @@ -0,0 +1,13 @@ +error[E0283]: type annotations needed: cannot satisfy `dyn Trait<'_>: Unsize>` + --> $DIR/unsize-goal-mismatch.rs:15:5 + | +LL | x + | ^ + | + = note: cannot satisfy `dyn Trait<'_>: Unsize>` + = note: required for `Box>` to implement `CoerceUnsized>>` + = 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`. diff --git a/tests/ui/traits/next-solver/unsize-goal-mismatch.rs b/tests/ui/traits/next-solver/unsize-goal-mismatch.rs new file mode 100644 index 0000000000000..f57cceb4096a0 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-goal-mismatch.rs @@ -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>) -> Box> { + x + //[next]~^ ERROR type annotations needed: cannot satisfy `dyn Trait<'_>: Unsize> +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/unsize-overflow.rs b/tests/ui/traits/next-solver/unsize-overflow.rs new file mode 100644 index 0000000000000..036be02aaeae3 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-overflow.rs @@ -0,0 +1,7 @@ +//@ compile-flags: -Znext-solver +#![recursion_limit = "8"] + +fn main() { + let _: Box = Box::new(&&&&&&&1); + //~^ ERROR overflow evaluating the requirement `Box<&&&&&&&i32>: CoerceUnsized> +} diff --git a/tests/ui/traits/next-solver/unsize-overflow.stderr b/tests/ui/traits/next-solver/unsize-overflow.stderr new file mode 100644 index 0000000000000..ae0f2957243c7 --- /dev/null +++ b/tests/ui/traits/next-solver/unsize-overflow.stderr @@ -0,0 +1,12 @@ +error[E0275]: overflow evaluating the requirement `Box<&&&&&&&i32>: CoerceUnsized>` + --> $DIR/unsize-overflow.rs:5:28 + | +LL | let _: Box = 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` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr index b82f1eef42b5a..392680aa50643 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr @@ -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 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 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`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs index af2594b95f3d2..98ca30ca391f7 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs @@ -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 {