Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 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
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
06412ff
Rollup merge of #155543 - popzxc:document-generic-const-features, r=B…
jhpratt May 4, 2026
6ab3339
Rollup merge of #156043 - folkertdev:c-variadic-avr-assembly-test, r=…
jhpratt May 4, 2026
d2cd0b7
Rollup merge of #156082 - danieljofficial:move-tests-associated-types…
jhpratt May 4, 2026
31e13b6
Rollup merge of #156092 - susitsm:needs-hir-hash, r=petrochenkov
jhpratt May 4, 2026
44cd989
Rollup merge of #156104 - aobatact:try-as-dyn-unsized, r=oli-obk
jhpratt May 4, 2026
561cac7
Rollup merge of #156128 - DanielEScherzer:gg-mailmap, r=GuillaumeGomez
jhpratt 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
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>];
```
73 changes: 73 additions & 0 deletions src/doc/unstable-book/src/language-features/generic-const-exprs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# generic_const_exprs

Allows non-trivial generic constants which have to be shown to successfully evaluate
to a value by being part of an item signature.

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


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

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

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

See also: [min_generic_const_args], [generic_const_args]

[min_generic_const_args]: min-generic-const-args.md
[generic_const_args]: generic-const-args.md

## Examples

```rust
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

// Use parameters that depend on a generic argument.
struct Foo<const N: usize>
where
[(); N + 1]:,
{
array: [usize; N + 1],
}

// Use generic parameters in const operations.
trait Bar {
const X: usize;
const Y: usize;
}

// Note `B::X * B::Y`.
const fn baz<B: Bar>(x: [usize; B::X], y: [usize; B::Y]) -> [usize; B::X * B::Y] {
let mut out = [0; B::X * B::Y];
let mut i = 0;
while i < B::Y {
let mut j = 0;
while j < B::X {
out[i * B::X + j] = y[i].saturating_mul(x[j]);
j += 1;
}
i += 1;
}
out
}


// Create a new type based on a generic argument.
pub struct Grow<const N: usize> {
arr: [usize; N],
}

impl<const N: usize> Grow<N> {
pub const fn grow(self, val: usize) -> Grow<{ N + 1 }> {
let mut new_arr = [0; { N + 1 }];
let mut idx = 0;
while idx < N {
new_arr[idx] = self.arr[idx];
idx += 1;
}
new_arr[N] = val;
Grow { arr: new_arr }
}
}
```
53 changes: 53 additions & 0 deletions src/doc/unstable-book/src/language-features/generic-const-items.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# generic_const_items

Allows generic parameters and where-clauses on free & associated const items.

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

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

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

Warning: This feature is an [experiment] and lacks an RFC.
There are no guarantees that it will ever be stabilized.

See also: [generic_const_exprs], [min_generic_const_args].

[experiment]: https://lang-team.rust-lang.org/how_to/experiment.html
[generic_const_exprs]: generic-const-exprs.md
[min_generic_const_args]: min-generic-const-args.md

## Examples

### Generic constant values

```rust
#![allow(incomplete_features)]
#![feature(generic_const_items)]

const GENERIC_VAL<const ARG: usize>: usize = ARG + 1;

#[test]
fn generic_const_arg() {
assert_eq!(GENERIC_VAL::<1>, 2);
assert_eq!(GENERIC_VAL::<2>, 3);
}
```

### Conditional constants

```rust
#![allow(incomplete_features)]
#![feature(generic_const_items)]

// `GENERIC_VAL::<0>` will fail to compile
const GENERIC_VAL<const ARG: usize>: usize = if ARG > 0 { ARG + 1 } else { panic!("0 value") };

// Will fail to compile if the `Copy` derive is removed.
const COPY_MARKER<C: Copy>: () = ();

#[derive(Clone, Copy)]
struct Foo;

const FOO_IS_COPY: () = COPY_MARKER::<Foo>;
```
Loading
Loading