Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5eae716
docs(unstable-book): Document const generics features
popzxc Apr 20, 2026
6315e17
Update unstable feature descriptions (min_generic_const_args, generic…
popzxc Apr 20, 2026
73e44e8
Change generic_const_args feature from unstable to incomplete
popzxc Apr 20, 2026
c4eb1bf
Do not use `const { }` blocks for GCI
popzxc Apr 23, 2026
2aeb041
Revert documentation changes from 08bd077
bushrat011899 Apr 26, 2026
69cc5fa
Remove unnecessary `get_unchecked`
ChrisDenton Apr 27, 2026
a1c5893
Added std library support for WALI command-line arguments.
arjunr2 May 1, 2026
b9499e0
move associated type tests out of issues
danieljofficial May 2, 2026
4cca528
add issue links and bless
danieljofficial May 2, 2026
a34cb76
Only include `crate_hash` in `Linker` if incremental compilation is e…
susitsm May 2, 2026
5313fb1
rename `needs_crate_hash` to `needs_hir_hash`.
susitsm May 2, 2026
ecf527f
Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`
aobatact May 3, 2026
1e649f1
.mailmap: prefer matching just based on commit emails
DanielEScherzer May 4, 2026
8e0ebb9
c-variadic: gate `va_arg` on `c_variadic_experimental_arch`
folkertdev May 1, 2026
f4e1b2f
Use `into_bytes` directly
arjunr2 May 4, 2026
f19d04f
Rollup merge of #155848 - bushrat011899:revert_08bd077, r=Mark-Simula…
JonathanBrouwer May 4, 2026
ebd42bb
Rollup merge of #155855 - ChrisDenton:remove-unsafe-get, r=Mark-Simul…
JonathanBrouwer May 4, 2026
0824adf
Rollup merge of #156062 - arjunr2:wali-support-clargs, r=nia-e
JonathanBrouwer May 4, 2026
47f7f7b
Rollup merge of #155543 - popzxc:document-generic-const-features, r=B…
JonathanBrouwer May 4, 2026
47b5379
Rollup merge of #156043 - folkertdev:c-variadic-avr-assembly-test, r=…
JonathanBrouwer May 4, 2026
c4fa0d5
Rollup merge of #156082 - danieljofficial:move-tests-associated-types…
JonathanBrouwer May 4, 2026
7ca04b6
Rollup merge of #156092 - susitsm:needs-hir-hash, r=petrochenkov
JonathanBrouwer May 4, 2026
43346f4
Rollup merge of #156104 - aobatact:try-as-dyn-unsized, r=oli-obk
JonathanBrouwer May 4, 2026
746d095
Rollup merge of #156128 - DanielEScherzer:gg-mailmap, r=GuillaumeGomez
JonathanBrouwer May 4, 2026
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
8 changes: 3 additions & 5 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,9 @@ Gregor Peach <gregorpeach@gmail.com>
Grzegorz Bartoszek <grzegorz.bartoszek@thaumatec.com>
Guanqun Lu <guanqun.lu@gmail.com>
Guillaume Gomez <contact@guillaume-gomez.fr>
Guillaume Gomez <contact@guillaume-gomez.fr> Guillaume Gomez <guillaume1.gomez@gmail.com>
Guillaume Gomez <contact@guillaume-gomez.fr> ggomez <guillaume1.gomez@gmail.com>
Guillaume Gomez <contact@guillaume-gomez.fr> ggomez <ggomez@ggo.ifr.lan>
Guillaume Gomez <contact@guillaume-gomez.fr> Guillaume Gomez <ggomez@ggo.ifr.lan>
Guillaume Gomez <contact@guillaume-gomez.fr> Guillaume Gomez <guillaume.gomez@huawei.com>
Guillaume Gomez <contact@guillaume-gomez.fr> <guillaume1.gomez@gmail.com>
Guillaume Gomez <contact@guillaume-gomez.fr> <ggomez@ggo.ifr.lan>
Guillaume Gomez <contact@guillaume-gomez.fr> <guillaume.gomez@huawei.com>
gnzlbg <gonzalobg88@gmail.com> <gnzlbg@users.noreply.github.com>
hamidreza kalbasi <hamidrezakalbasi@protonmail.com>
Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com>
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {

// Don't hash unless necessary, because it's expensive.
let opt_hir_hash =
if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };

let delayed_resolver = Steal::new((resolver, krate));
mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash)
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::ffi::c_uint;
use std::{assert_matches, iter, ptr};

use rustc_abi::{
AddressSpace, Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive,
Size, WrappingRange,
AddressSpace, Align, BackendRepr, CVariadicStatus, Float, HasDataLayout, Integer,
NumScalableVectors, Primitive, Size, WrappingRange,
};
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
Expand All @@ -23,6 +23,7 @@ use rustc_middle::ty::{
};
use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC;
use rustc_span::{Span, Symbol, sym};
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
Expand Down Expand Up @@ -288,6 +289,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]),
sym::va_arg => {
let target = &self.cx.tcx.sess.target;
let stability = target.supports_c_variadic_definitions();
if let CVariadicStatus::Unstable { feature } = stability
&& !self.tcx.features().enabled(feature)
{
let msg =
format!("C-variadic function definitions on this target are unstable");
feature_err(&*self.sess(), feature, span, msg).emit();
}

let BackendRepr::Scalar(scalar) = result.layout.backend_repr else {
bug!("the va_arg intrinsic does not support non-scalar types")
};
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,9 @@ declare_features! (
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Allows using generics in more complex const expressions, based on definitional equality.
(unstable, generic_const_args, "1.95.0", Some(151972)),
/// Allows non-trivial generic constants which have to have wfness manually propagated to callers
(incomplete, generic_const_args, "1.95.0", Some(151972)),
/// Allows non-trivial generic constants which have to be shown to successfully evaluate
/// to a value by being part of an item signature.
(incomplete, generic_const_exprs, "1.56.0", Some(76560)),
/// Allows generic parameters and where-clauses on free & associated const items.
(incomplete, generic_const_items, "1.73.0", Some(113521)),
Expand Down Expand Up @@ -626,7 +627,8 @@ declare_features! (
/// Allows additional const parameter types, such as [u8; 10] or user defined types.
/// User defined types must not have fields more private than the type itself.
(unstable, min_adt_const_params, "1.96.0", Some(154042)),
/// Enables the generic const args MVP (only bare paths, not arbitrary computation).
/// Enables the generic const args MVP (paths to type const items and constructors
/// for ADTs and primitives).
(incomplete, min_generic_const_args, "1.84.0", Some(132980)),
/// A minimal, sound subset of specialization intended to be used by the
/// standard library until the soundness issues with specialization
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Linker {
Linker {
dep_graph: tcx.dep_graph.clone(),
output_filenames: Arc::clone(tcx.output_filenames(())),
crate_hash: if tcx.needs_crate_hash() {
crate_hash: if tcx.sess.opts.incremental.is_some() {
Some(tcx.crate_hash(LOCAL_CRATE))
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> {
attrs: &SortedMap<ItemLocalId, &[Attribute]>,
define_opaque: Option<&[(Span, LocalDefId)]>,
) -> Hashes {
if !self.needs_crate_hash() {
if !self.needs_hir_hash() {
return Hashes { opt_hash_including_bodies: None, attrs_hash: None };
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,12 +1127,12 @@ impl<'tcx> TyCtxt<'tcx> {
})
}

pub fn needs_crate_hash(self) -> bool {
// Why is the crate hash needed for these configurations?
pub fn needs_hir_hash(self) -> bool {
// Why is the hir hash needed for these configurations?
// - debug_assertions: for the "fingerprint the result" check in
// `rustc_query_impl::execution::execute_job`.
// - incremental: for query lookups.
// - needs_metadata: for putting into crate metadata.
// - needs_metadata: it is included in the crate metadata through the crate_hash query
// - instrument_coverage: for putting into coverage data (see
// `hash_mir_source`).
// - metrics_dir: metrics use the strict version hash in the filenames
Expand Down
18 changes: 14 additions & 4 deletions library/core/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,18 +1007,23 @@ pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
#[must_use]
#[unstable(feature = "try_as_dyn", issue = "144361")]
pub const fn try_as_dyn<
T: Any + 'static,
T: Any + ?Sized + 'static,
U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized + 'static,
>(
t: &T,
) -> Option<&U> {
// For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is
// only supported for sized types). The function therefore unconditionally
// returns `None` in that case.
let vtable: Option<ptr::DynMetadata<U>> =
const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
match vtable {
Some(dyn_metadata) => {
let pointer = ptr::from_raw_parts(t, dyn_metadata);
let pointer = ptr::from_raw_parts(t as *const T as *const (), dyn_metadata);
// SAFETY: `t` is a reference to a type, so we know it is valid.
// `dyn_metadata` is a vtable for T, implementing the trait of `U`.
// `T` is sized here because `trait_info_of` only returns `Some` for sized types,
// so the thin data pointer fully describes the value.
Some(unsafe { &*pointer })
}
None => None,
Expand Down Expand Up @@ -1061,18 +1066,23 @@ pub const fn try_as_dyn<
#[must_use]
#[unstable(feature = "try_as_dyn", issue = "144361")]
pub const fn try_as_dyn_mut<
T: Any + 'static,
T: Any + ?Sized + 'static,
U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized + 'static,
>(
t: &mut T,
) -> Option<&mut U> {
// For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is
// only supported for sized types). The function therefore unconditionally
// returns `None` in that case.
let vtable: Option<ptr::DynMetadata<U>> =
const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
match vtable {
Some(dyn_metadata) => {
let pointer = ptr::from_raw_parts_mut(t, dyn_metadata);
let pointer = ptr::from_raw_parts_mut(t as *mut T as *mut (), dyn_metadata);
// SAFETY: `t` is a reference to a type, so we know it is valid.
// `dyn_metadata` is a vtable for T, implementing the trait of `U`.
// `T` is sized here because `trait_info_of` only returns `Some` for sized types,
// so the thin data pointer fully describes the value.
Some(unsafe { &mut *pointer })
}
None => None,
Expand Down
21 changes: 18 additions & 3 deletions library/core/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub type RawOsError = cfg_select! {
/// This list is intended to grow over time and it is not recommended to
/// exhaustively match against it.
///
/// It is used with the [`io::Error`][error] type.
///
/// [error]: ../../std/io/struct.Error.html
///
/// # Handling errors and matching on `ErrorKind`
///
/// In application code, use `match` for the `ErrorKind` values you are
Expand Down Expand Up @@ -135,12 +139,13 @@ pub enum ErrorKind {
#[stable(feature = "rust1", since = "1.0.0")]
TimedOut,
/// An error returned when an operation could not be completed because a
/// call to an underlying writer returned [`Ok(0)`].
/// call to [`write`][write] returned [`Ok(0)`].
///
/// This typically means that an operation could only succeed if it wrote a
/// particular number of bytes but only a smaller number of bytes could be
/// written.
///
/// [write]: ../../std/io/trait.Write.html#tymethod.write
/// [`Ok(0)`]: Ok
#[stable(feature = "rust1", since = "1.0.0")]
WriteZero,
Expand Down Expand Up @@ -239,14 +244,16 @@ pub enum ErrorKind {
//
/// A custom error that does not fall under any other I/O error kind.
///
/// This can be used to construct your own errors that do not match any
/// This can be used to construct your own [`Error`][error]s that do not match any
/// [`ErrorKind`].
///
/// This [`ErrorKind`] is not used by the standard library.
///
/// Errors from the standard library that do not fall under any of the I/O
/// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
/// New [`ErrorKind`]s might be added in the future for some of those.
///
/// [error]: ../../std/io/struct.Error.html
#[stable(feature = "rust1", since = "1.0.0")]
Other,

Expand Down Expand Up @@ -379,7 +386,15 @@ impl ErrorKind {

#[stable(feature = "io_errorkind_display", since = "1.60.0")]
impl fmt::Display for ErrorKind {
/// Shows a human-readable description of the `ErrorKind`.
/// Shows a human-readable description of the [`ErrorKind`].
///
/// This is similar to `impl Display for Error`, but doesn't require first converting to Error.
///
/// # Examples
/// ```
/// use core::io::ErrorKind;
/// assert_eq!("entity not found", ErrorKind::NotFound.to_string());
/// ```
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.write_str(self.as_str())
}
Expand Down
7 changes: 1 addition & 6 deletions library/core/src/str/lossy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,7 @@ impl<'a> Iterator for Utf8Chunks<'a> {

let mut i = 0;
let mut valid_up_to = 0;
while i < self.source.len() {
// SAFETY: `i < self.source.len()` per previous line.
// For some reason the following are both significantly slower:
// while let Some(&byte) = self.source.get(i) {
// while let Some(byte) = self.source.get(i).copied() {
let byte = unsafe { *self.source.get_unchecked(i) };
while let Some(byte) = self.source.get(i).copied() {
i += 1;

if byte < 128 {
Expand Down
5 changes: 3 additions & 2 deletions library/std/src/os/linux/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t};
target_arch = "powerpc",
target_arch = "sparc",
target_arch = "arm",
target_arch = "wasm32"
))]
mod arch {
use crate::os::raw::{c_long, c_short, c_uint};
Expand Down Expand Up @@ -311,7 +310,9 @@ mod arch {
}
}

#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))]
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
// `wasm32-wali-linux-musl` uses ABI similar to x86_64
target_arch = "wasm32"))]
mod arch {
use crate::os::raw::{c_int, c_long};

Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod common;

cfg_select! {
any(
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),
all(target_family = "unix", not(any(target_family = "wasm", target_os = "espidf", target_os = "vita"))),
target_os = "hermit",
) => {
mod unix;
Expand Down Expand Up @@ -45,6 +45,10 @@ cfg_select! {
mod wasi;
pub use wasi::*;
}
all(target_family = "wasm", target_os = "linux") => {
mod wali;
pub use wali::*;
}
target_os = "xous" => {
mod xous;
pub use xous::*;
Expand Down
54 changes: 54 additions & 0 deletions library/std/src/sys/args/wali.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
pub use super::common::Args;

/// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) {
unsafe { imp::init(argc, argv) }
}

/// Returns the command line arguments
pub fn args() -> Args {
imp::args()
}

mod imp {
use super::Args;
use crate::ffi::{CString, OsString};
use crate::os::raw::{c_uint as WaliArgIdx, c_uint};
use crate::os::unix::prelude::*;
use crate::sync::OnceLock;

#[link(wasm_import_module = "wali")]
unsafe extern "C" {
pub fn __cl_get_argc() -> WaliArgIdx;
pub fn __cl_get_argv_len(offset: WaliArgIdx) -> c_uint;
pub fn __cl_copy_argv(buf: *mut i8, offset: WaliArgIdx) -> c_uint;
}

static ARGS: OnceLock<Vec<OsString>> = OnceLock::new();

pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
// Uses the WALI arguments API
ARGS.set(argc_argv()).ok();
}

unsafe fn load_arg(idx: c_uint) -> OsString {
let arg_len = unsafe { __cl_get_argv_len(idx) };
let arg_buf = CString::new(vec![b'x'; arg_len as usize]).unwrap();
let ptr = arg_buf.into_raw();
let arg_buf = unsafe {
__cl_copy_argv(ptr, idx);
CString::from_raw(ptr)
};
OsStringExt::from_vec(arg_buf.into_bytes())
}

fn argc_argv() -> Vec<OsString> {
let argc = unsafe { __cl_get_argc() };
(0..argc).map(|x| unsafe { load_arg(x) }).collect()
}

pub fn args() -> Args {
let cached = ARGS.get().cloned().unwrap_or_default();
Args::new(cached)
}
}
37 changes: 37 additions & 0 deletions src/doc/unstable-book/src/language-features/generic-const-args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# generic_const_args

Allows using generics in more complex const expressions, based on definitional equality.

The tracking issue for this feature is: [#151972]

[#151972]: https://github.com/rust-lang/rust/issues/151972

------------------------

Warning: This feature is incomplete; its design and syntax may change.

This feature enables many of the same use cases supported by [generic_const_exprs],
but based on the machinery developed for [min_generic_const_args]. In a way, it is
meant to be an interim successor for GCE (though it might not currently support all
the valid cases that supported by GCE).

See also: [generic_const_items]

[min_generic_const_args]: min-generic-const-args.md
[generic_const_exprs]: generic-const-exprs.md
[generic_const_items]: generic-const-items.md

## Examples

```rust
#![feature(generic_const_items)]
#![feature(min_generic_const_args)]
#![feature(generic_const_args)]
#![expect(incomplete_features)]

type const ADD1<const N: usize>: usize = const { N + 1 };

type const INC<const N: usize>: usize = ADD1::<N>;

const ARR: [(); ADD1::<0>] = [(); INC::<0>];
```
Loading
Loading