diff --git a/RELEASES.md b/RELEASES.md index 35cd912291f83..5558086f1f5b2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,12 @@ +Version 1.99.1 (2026-10-15) +=========================== + + + +* [library: fix missing symbol `wcslen` on UEFI and embedded targets](https://github.com/rust-lang/rust/issues/163614) +* [rustc: fix miscompilation of FFI `bool` return values on x86_64](https://github.com/rust-lang/rust/issues/163911) +* [rust-lld: add the rpath for `libLLVM` on macOS](https://github.com/rust-lang/rust/issues/163947) + Version 1.99.0 (2026-10-01) ========================== @@ -29,7 +38,7 @@ Language Compiler -------- - [Convert `-Ctarget-cpu` into a target-modifier for AVR, AMDGCN and NVPTX](https://github.com/rust-lang/rust/pull/150732) -- [Enable `static_position_independent_executables` on all gnu and musl targets](https://github.com/rust-lang/rust/pull/158510) +- [Enable `static_position_independent_executables` on all gnu targets](https://github.com/rust-lang/rust/pull/158510) - When providing a suggestion about a missing method, rustc now prefers an exactly matching name from a [doc alias attribute](https://doc.rust-lang.org/rustdoc/advanced-features.html#add-aliases-for-an-item-in-documentation-search) over a similarity search from other method names. If your new users sometimes expect a method under a different name, adding a doc alias will now help them find it via rustc suggestions, in addition to helping them find it via rustdoc search: [When suggesting method names, prefer *exact* doc aliases over similar names](https://github.com/rust-lang/rust/pull/160369) @@ -85,7 +94,6 @@ Cargo ----- - Add a new built-in profile `debug`. This is a preparation for transitioning the `dev` profile away from debugging to give a saner default for faster development iterations. Currently there is no difference between `dev` and `debug` profiles. [docs](https://doc.rust-lang.org/nightly/cargo/reference/profiles.html#debug-1) [#17214](https://github.com/rust-lang/cargo/pull/17214) - Workspace members on edition 2024 or later can now override an inherited workspace dependency's `default-features` field. For example, `serde = { workspace = true, default-features = false }` now turns off default features even when the workspace definition enables them. On earlier editions, `default-features = false` is ignored with a warning. ([RFC 3945](https://github.com/rust-lang/rfcs/pull/3945)) [#17126](https://github.com/rust-lang/cargo/pull/17126) -- Incremental compilation is now disabled by default when running in CI. CI is detected via the CI environment variable. [#17220](https://github.com/rust-lang/cargo/pull/17220) See also the [full Cargo changelog](https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-199-2026-10-01) @@ -116,6 +124,8 @@ Compatibility Notes - Macros that expand to a semicolon now produce a warning lint (`semicolon_in_expressions_from_non_local_macros`) even when the macro comes from another crate. Previously, such warnings only appeared for macros from the same crate, to avoid showing warnings that can't be fixed locally; however, this masked problems, as integration tests from the crate providing the macro get compiled as a separate crate, so tests often wouldn't reveal this issue. If you encounter a lint like this, please make sure to report it to the crate providing the macro so they can fix it; don't just silence it in your own crate. - [`semicolon_in_expressions_from_macros`: Lint on non-local macros too](https://github.com/rust-lang/rust/pull/159222) - [Split non-local `semicolon_in_expressions_from_macros` into a separate lint](https://github.com/rust-lang/rust/pull/159700) +- In Cargo, incremental compilation is now disabled by default when running in CI. CI is detected via the `CI` environment variable. [#17220](https://github.com/rust-lang/cargo/pull/17220) +- [The Rust Reference no longer recommends using a single pattern to match a union alongside another value, such as in a manually-written tagged union](https://github.com/rust-lang/reference/pull/2303). This was because it was found that such code would, in some circumstances, result in the compiler reading the contents of the union before checking if the rest of the scrutinee matches the rest of the pattern. This can cause undefined behavior in code similar to what the reference previously recommended. @@ -1536,7 +1546,7 @@ for more information on Rust's tiered platform support. Libraries --------- - [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154) -- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375) +- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375) - [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080) - [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933) - Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717) @@ -1610,7 +1620,7 @@ These previously stable APIs are now stable in const contexts: - [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) - [`char::is_whitespace`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_whitespace) - [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened) -- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut) +- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut) - [`String::into_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes) - [`String::as_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str) - [`String::capacity`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index a06a6a0a69e12..2a10921f99578 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -495,7 +495,9 @@ impl<'a, Ty> ArgAbi<'a, Ty> { // Only integers have signedness if let BackendRepr::Scalar(scalar) = self.layout.backend_repr && let Primitive::Int(i, signed) = scalar.primitive() - && i.size().bits() < bits + // bools are i1 but their primitive is i8. Unlike other types, + // bools can be extended to their primitive size. + && (i.size().bits() < bits || self.layout.backend_repr.is_bool()) && let PassMode::Direct(ref mut attrs) = self.mode { if signed { diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 5ab2834807d67..378989a07246f 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -248,6 +248,11 @@ where } else if is_arg || cx.target_spec().is_like_darwin { arg.extend_integer_width_to(32); } + // The x86_64 psABI requires bools to be zero-extended to 8-bits, with high bits unspecified. + // zeroext i1 has this behavior in the LLVM X86 backend. + if !is_arg && arg.layout.backend_repr.is_bool() { + arg.extend_integer_width_to(8); + } } } }; diff --git a/library/compiler-builtins/builtins-test/tests/mem.rs b/library/compiler-builtins/builtins-test/tests/mem.rs index 3c01a6179502f..87a83063681e3 100644 --- a/library/compiler-builtins/builtins-test/tests/mem.rs +++ b/library/compiler-builtins/builtins-test/tests/mem.rs @@ -1,5 +1,5 @@ extern crate compiler_builtins; -use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; +use compiler_builtins::mem::{memcmp, memcpy, memmove, memset, wchar_t}; const WORD_SIZE: usize = core::mem::size_of::(); @@ -285,6 +285,30 @@ fn memset_backward_aligned() { } } +/// Wrapper that prevents inlining the wcslen implementation into the test. +/// +/// Inlining causes LLVM to pick up the wcslen pattern and generate a call to +/// wcslen. That causes a linker error for tests on platforms without wcslen +/// (such as wasm). +/// +/// `no_mangle` is needed because LLVM knows not to apply the wcslen +/// optimization to a function with this name: +/// https://github.com/llvm/llvm-project/pull/132572 +#[inline(never)] +#[unsafe(no_mangle)] +unsafe fn wcslen(p: *const wchar_t) -> usize { + unsafe { compiler_builtins::mem::wcslen(p) } +} + +#[test] +fn wide_string_length() { + let s = [0]; + assert_eq!(unsafe { wcslen(s.as_ptr()) }, 0); + + let s = [97, 98, 99, 0]; + assert_eq!(unsafe { wcslen(s.as_ptr()) }, 3); +} + #[cfg(all( target_arch = "arm", not(any(target_vendor = "apple", target_env = "msvc")) diff --git a/library/compiler-builtins/compiler-builtins/src/mem/mod.rs b/library/compiler-builtins/compiler-builtins/src/mem/mod.rs index ef0f4da228e96..0fbb34c05cb37 100644 --- a/library/compiler-builtins/compiler-builtins/src/mem/mod.rs +++ b/library/compiler-builtins/compiler-builtins/src/mem/mod.rs @@ -7,6 +7,13 @@ #[cfg_attr(all(feature = "arch", target_arch = "x86_64"), path = "x86_64.rs")] mod impls; +#[cfg(any(windows, target_os = "uefi"))] +#[expect(non_camel_case_types)] +pub type wchar_t = u16; +#[cfg(not(any(windows, target_os = "uefi")))] +#[expect(non_camel_case_types)] +pub type wchar_t = i32; + intrinsics! { #[mem_builtin] pub unsafe extern "C" fn memcpy( @@ -67,4 +74,15 @@ intrinsics! { pub unsafe extern "C" fn strlen(s: *const core::ffi::c_char) -> usize { impls::c_string_length(s) } + + #[mem_builtin] + pub unsafe extern "C" fn wcslen(s: *const crate::mem::wchar_t) -> usize { + let mut s = s; + let mut n = 0; + while *s != 0 { + n += 1; + s = s.add(1); + } + n + } } diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index 2ebc3066f1fac..58691539edfa3 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/160100 +Last change is for: https://github.com/rust-lang/rust/pull/163954 diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 739f0d6c1cf02..6b9a6f8530d26 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1504,7 +1504,6 @@ impl CommandLineStep for Lld { if builder.config.rpath_enabled(target) && helpers::use_host_linker(target) && builder.config.llvm_link_shared() - && target.contains("linux") { // So we inform LLD where it can find LLVM's libraries by adding an rpath entry to the // expected parent `lib` directory. @@ -1512,7 +1511,12 @@ impl CommandLineStep for Lld { // Be careful when changing this path, we need to ensure it's quoted or escaped: // `$ORIGIN` would otherwise be expanded when the `LdFlags` are passed verbatim to // cmake. - ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'"); + if target.contains("linux") { + ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'"); + } + if target.contains("apple-darwin") { + ldflags.push_all("-Wl,-rpath,'@loader_path/../../../'"); + } } configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]); diff --git a/src/version b/src/version index 9eb2e1ff9c224..3bd6c5685c9ba 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.99.0 +1.99.1 diff --git a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs index fdaf0dc58f106..79be3bd5f57b4 100644 --- a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs @@ -1,10 +1,12 @@ //@ add-minicore //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 -//@ revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv +//@ revisions:x86_64-linux x86_64-uefi i686 aarch64-apple aarch64-windows aarch64-linux arm riscv -//@[x86_64] compile-flags: --target x86_64-unknown-uefi -//@[x86_64] needs-llvm-components: x86 +//@[x86_64-uefi] compile-flags: --target x86_64-unknown-uefi +//@[x86_64-uefi] needs-llvm-components: x86 +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-linux] needs-llvm-components: x86 //@[i686] compile-flags: --target i686-unknown-linux-musl //@[i686] needs-llvm-components: x86 //@[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc @@ -33,7 +35,8 @@ use minicore::*; // // ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING // ============================== ======================= -// x86_64: void @c_arg_bool(i1 zeroext %_a) +// x86_64-linux: void @c_arg_bool(i1 zeroext %_a) +// x86_64-uefi: void @c_arg_bool(i1 zeroext %_a) // i686: void @c_arg_bool(i1 zeroext %_a) // aarch64-apple: void @c_arg_bool(i1 zeroext %_a) // aarch64-windows: void @c_arg_bool(i1 %_a) @@ -43,7 +46,8 @@ use minicore::*; #[no_mangle] pub extern "C" fn c_arg_bool(_a: bool) {} -// x86_64: void @c_arg_u8(i8 zeroext %_a) +// x86_64-linux: void @c_arg_u8(i8 zeroext %_a) +// x86_64-uefi: void @c_arg_u8(i8 zeroext %_a) // i686: void @c_arg_u8(i8 zeroext %_a) // aarch64-apple: void @c_arg_u8(i8 zeroext %_a) // aarch64-windows: void @c_arg_u8(i8 %_a) @@ -53,7 +57,8 @@ pub extern "C" fn c_arg_bool(_a: bool) {} #[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) {} -// x86_64: void @c_arg_u16(i16 zeroext %_a) +// x86_64-linux: void @c_arg_u16(i16 zeroext %_a) +// x86_64-uefi: void @c_arg_u16(i16 zeroext %_a) // i686: void @c_arg_u16(i16 zeroext %_a) // aarch64-apple: void @c_arg_u16(i16 zeroext %_a) // aarch64-windows: void @c_arg_u16(i16 %_a) @@ -63,7 +68,8 @@ pub extern "C" fn c_arg_u8(_a: u8) {} #[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) {} -// x86_64: void @c_arg_u32(i32 %_a) +// x86_64-linux: void @c_arg_u32(i32 %_a) +// x86_64-uefi: void @c_arg_u32(i32 %_a) // i686: void @c_arg_u32(i32 %_a) // aarch64-apple: void @c_arg_u32(i32 %_a) // aarch64-windows: void @c_arg_u32(i32 %_a) @@ -73,7 +79,8 @@ pub extern "C" fn c_arg_u16(_a: u16) {} #[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) {} -// x86_64: void @c_arg_u64(i64 %_a) +// x86_64-linux: void @c_arg_u64(i64 %_a) +// x86_64-uefi: void @c_arg_u64(i64 %_a) // i686: void @c_arg_u64(i64 %_a) // aarch64-apple: void @c_arg_u64(i64 %_a) // aarch64-windows: void @c_arg_u64(i64 %_a) @@ -83,7 +90,8 @@ pub extern "C" fn c_arg_u32(_a: u32) {} #[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) {} -// x86_64: void @c_arg_i8(i8 signext %_a) +// x86_64-linux: void @c_arg_i8(i8 signext %_a) +// x86_64-uefi: void @c_arg_i8(i8 signext %_a) // i686: void @c_arg_i8(i8 signext %_a) // aarch64-apple: void @c_arg_i8(i8 signext %_a) // aarch64-windows: void @c_arg_i8(i8 %_a) @@ -93,7 +101,8 @@ pub extern "C" fn c_arg_u64(_a: u64) {} #[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) {} -// x86_64: void @c_arg_i16(i16 signext %_a) +// x86_64-linux: void @c_arg_i16(i16 signext %_a) +// x86_64-uefi: void @c_arg_i16(i16 signext %_a) // i686: void @c_arg_i16(i16 signext %_a) // aarch64-apple: void @c_arg_i16(i16 signext %_a) // aarch64-windows: void @c_arg_i16(i16 %_a) @@ -103,7 +112,8 @@ pub extern "C" fn c_arg_i8(_a: i8) {} #[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) {} -// x86_64: void @c_arg_i32(i32 %_a) +// x86_64-linux: void @c_arg_i32(i32 %_a) +// x86_64-uefi: void @c_arg_i32(i32 %_a) // i686: void @c_arg_i32(i32 %_a) // aarch64-apple: void @c_arg_i32(i32 %_a) // aarch64-windows: void @c_arg_i32(i32 %_a) @@ -113,7 +123,8 @@ pub extern "C" fn c_arg_i16(_a: i16) {} #[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) {} -// x86_64: void @c_arg_i64(i64 %_a) +// x86_64-linux: void @c_arg_i64(i64 %_a) +// x86_64-uefi: void @c_arg_i64(i64 %_a) // i686: void @c_arg_i64(i64 %_a) // aarch64-apple: void @c_arg_i64(i64 %_a) // aarch64-windows: void @c_arg_i64(i64 %_a) @@ -123,7 +134,8 @@ pub extern "C" fn c_arg_i32(_a: i32) {} #[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) {} -// x86_64: zeroext i1 @c_ret_bool() +// x86_64-linux: zeroext i1 @c_ret_bool() +// x86_64-uefi: zeroext i1 @c_ret_bool() // i686: zeroext i1 @c_ret_bool() // aarch64-apple: zeroext i1 @c_ret_bool() // aarch64-windows: i1 @c_ret_bool() @@ -135,7 +147,8 @@ pub extern "C" fn c_ret_bool() -> bool { false } -// x86_64: zeroext i8 @c_ret_u8() +// x86_64-linux: i8 @c_ret_u8() +// x86_64-uefi: zeroext i8 @c_ret_u8() // i686: zeroext i8 @c_ret_u8() // aarch64-apple: zeroext i8 @c_ret_u8() // aarch64-windows: i8 @c_ret_u8() @@ -147,7 +160,8 @@ pub extern "C" fn c_ret_u8() -> u8 { 0 } -// x86_64: zeroext i16 @c_ret_u16() +// x86_64-linux: i16 @c_ret_u16() +// x86_64-uefi: zeroext i16 @c_ret_u16() // i686: zeroext i16 @c_ret_u16() // aarch64-apple: zeroext i16 @c_ret_u16() // aarch64-windows: i16 @c_ret_u16() @@ -159,7 +173,8 @@ pub extern "C" fn c_ret_u16() -> u16 { 0 } -// x86_64: i32 @c_ret_u32() +// x86_64-linux: i32 @c_ret_u32() +// x86_64-uefi: i32 @c_ret_u32() // i686: i32 @c_ret_u32() // aarch64-apple: i32 @c_ret_u32() // aarch64-windows: i32 @c_ret_u32() @@ -171,7 +186,8 @@ pub extern "C" fn c_ret_u32() -> u32 { 0 } -// x86_64: i64 @c_ret_u64() +// x86_64-linux: i64 @c_ret_u64() +// x86_64-uefi: i64 @c_ret_u64() // i686: i64 @c_ret_u64() // aarch64-apple: i64 @c_ret_u64() // aarch64-windows: i64 @c_ret_u64() @@ -183,7 +199,8 @@ pub extern "C" fn c_ret_u64() -> u64 { 0 } -// x86_64: signext i8 @c_ret_i8() +// x86_64-linux: i8 @c_ret_i8() +// x86_64-uefi: signext i8 @c_ret_i8() // i686: signext i8 @c_ret_i8() // aarch64-apple: signext i8 @c_ret_i8() // aarch64-windows: i8 @c_ret_i8() @@ -195,7 +212,8 @@ pub extern "C" fn c_ret_i8() -> i8 { 0 } -// x86_64: signext i16 @c_ret_i16() +// x86_64-linux: i16 @c_ret_i16() +// x86_64-uefi: signext i16 @c_ret_i16() // i686: signext i16 @c_ret_i16() // aarch64-apple: signext i16 @c_ret_i16() // aarch64-windows: i16 @c_ret_i16() @@ -207,7 +225,8 @@ pub extern "C" fn c_ret_i16() -> i16 { 0 } -// x86_64: i32 @c_ret_i32() +// x86_64-linux: i32 @c_ret_i32() +// x86_64-uefi: i32 @c_ret_i32() // i686: i32 @c_ret_i32() // aarch64-apple: i32 @c_ret_i32() // aarch64-windows: i32 @c_ret_i32() @@ -219,7 +238,8 @@ pub extern "C" fn c_ret_i32() -> i32 { 0 } -// x86_64: i64 @c_ret_i64() +// x86_64-linux: i64 @c_ret_i64() +// x86_64-uefi: i64 @c_ret_i64() // i686: i64 @c_ret_i64() // aarch64-apple: i64 @c_ret_i64() // aarch64-windows: i64 @c_ret_i64()