Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
Version 1.99.1 (2026-10-15)
===========================

<a id="1.99.1"></a>

* [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)
==========================

Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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.

<a id="1.99.0-Internal-Changes"></a>

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_target/src/callconv/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
};
Expand Down
26 changes: 25 additions & 1 deletion library/compiler-builtins/builtins-test/tests/mem.rs
Original file line number Diff line number Diff line change
@@ -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::<usize>();

Expand Down Expand Up @@ -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"))
Expand Down
18 changes: 18 additions & 0 deletions library/compiler-builtins/compiler-builtins/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
}
}
2 changes: 1 addition & 1 deletion src/bootstrap/download-ci-llvm-stamp
Original file line number Diff line number Diff line change
@@ -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
8 changes: 6 additions & 2 deletions src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1504,15 +1504,19 @@ 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.
//
// 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(), &[]);
Expand Down
2 changes: 1 addition & 1 deletion src/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.99.0
1.99.1
62 changes: 41 additions & 21 deletions tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand Down
Loading