`Vec::push` in consts MVP
Example:
const X: &'static [u32] = {
let mut v = Vec::with_capacity(6);
let mut x = 1;
while x < 42 {
v.push(x);
x *= 2;
}
assert!(v.len() == 6);
v.const_make_global()
};
assert_eq!([1, 2, 4, 8, 16, 32], X);
Oh this is fun...
- We split out the implementation of
Globalsuch that it callsintrinsics::const_allocateandintrinsics::const_deallocateduring compile time. This is achieved usingconst_eval_select - This allows us to
impl const Allocator for Global - We then constify everything necessary for
Vec::with_capacityandVec::push. - Added
Vec::const_leakto leak the final value viaintrinsics::const_make_global. If we see any pointer in the final value of aconstthat did not callconst_make_global, we error as implemented in rust-lang/rust#143595. (should we name theVecmethod const_make_global as well?)
r? @rust-lang/wg-const-eval
To-do for me:
- [x] Assess the rustdoc impact of additional bounds in the method
- [ ] Increase test coverage
The job aarch64-gnu-llvm-20-1 failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
---- [mir-opt] tests/mir-opt/pre-codegen/drop_boxed_slice.rs stdout ----
25 }
26 }
27 scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
- let mut _9: *mut u8;
- scope 19 (inlined Layout::size) {
- }
- scope 20 (inlined NonNull::<u8>::as_ptr) {
- }
- scope 21 (inlined std::alloc::dealloc) {
- let mut _10: usize;
---
40 }
41 }
thread '[mir-opt] tests/mir-opt/pre-codegen/drop_boxed_slice.rs' panicked at src/tools/compiletest/src/runtest/mir_opt.rs:84:21:
Actual MIR output differs from expected MIR output /checkout/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
stack backtrace:
5: __rustc::rust_begin_unwind
at /rustc/bb624dcb4c8ab987e10c0808d92d76f3b84dd117/library/std/src/panicking.rs:698:5
6: core::panicking::panic_fmt
at /rustc/bb624dcb4c8ab987e10c0808d92d76f3b84dd117/library/core/src/panicking.rs:75:14
I think it'd make more sense for
Boxto go first since that is the most primitive type for heap allocations.
That will either require us doing a const_eval_select to do box_new in runtime and something else in compile time, or to constify box_new. I chose Vec because I thought it would be much more useful than Box.
The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
[TIMING:end] tool::ToolBuild { build_compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu, tool: "tidy", path: "src/tools/tidy", mode: ToolBootstrap, source_type: InTree, extra_features: [], allow_features: "", cargo_args: [], artifact_kind: Binary } -- 10.487
[TIMING:end] tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
Diff in /checkout/library/alloc/src/vec/mod.rs:855:
/// values of constants.
#[unstable(feature = "const_heap", issue = "79597")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
- pub const fn const_make_global(mut self) -> &'static [T] where T: Freeze {
+ pub const fn const_make_global(mut self) -> &'static [T]
+ where
+ T: Freeze,
+ {
unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) };
let me = ManuallyDrop::new(self);
unsafe { slice::from_raw_parts(me.as_ptr(), me.len) }
fmt: checked 6504 files
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Build completed unsuccessfully in 0:00:47
local time: Sun Oct 26 18:50:03 UTC 2025
network time: Sun, 26 Oct 2025 18:50:03 GMT
The job x86_64-gnu-gcc failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
test [codegen-units] tests/codegen-units/item-collection/non-generic-closures.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/static-init.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/statics-and-consts.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/overloaded-operators.rs ... ok
FATAL: !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())
test [codegen-units] tests/codegen-units/item-collection/opaque-return-impls.rs ... FAILED
test [codegen-units] tests/codegen-units/item-collection/trait-implementations.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/trait-method-default-impl.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/trait-method-as-argument.rs ... ok
test [codegen-units] tests/codegen-units/item-collection/transitive-drop-glue.rs ... ok
---
These items were contained but should not have been:
MONO_ITEM fn std::alloc::Global::alloc_impl_runtime @@ opaque_return_impls.a116a005f37f8ef5-cgu.0[Internal]
thread '[codegen-units] tests/codegen-units/item-collection/opaque-return-impls.rs' panicked at src/tools/compiletest/src/runtest/codegen_units.rs:111:13:
fatal error
For more information how to resolve CI failures of this job, visit this link.
@bors try @rust-timer queue This affects core pieces of vec and alloc, let's make sure everything gets optimized well
Awaiting bors try build completion.
@rustbot label: +S-waiting-on-perf
:hourglass: Trying commit aded02cb5b4e87368ad75fa038e088dcf0b701d7 with merge b3f7ade975cf0d5d02740da43e496064c977dfb4…
To cancel the try build, run the command @bors try cancel.
Workflow: https://github.com/rust-lang/rust/actions/runs/18823449504
:sunny: Try build successful (CI)
Build commit: b3f7ade975cf0d5d02740da43e496064c977dfb4 (b3f7ade975cf0d5d02740da43e496064c977dfb4, parent: f977dfc388ea39c9886b7f8c49abce26e6918df6)
Queued b3f7ade975cf0d5d02740da43e496064c977dfb4 with parent f977dfc388ea39c9886b7f8c49abce26e6918df6, future comparison URL. There is currently 1 preceding artifact in the queue. It will probably take at least ~1.1 hours until the benchmark run finishes.
Finished benchmarking commit (b3f7ade975cf0d5d02740da43e496064c977dfb4): comparison URL.
Overall result: ❌✅ regressions and improvements - please read the text below
Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.
Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.
@bors rollup=never @rustbot label: -S-waiting-on-perf +perf-regression
Instruction count
Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
| mean | range | count | |
|---|---|---|---|
| Regressions ❌ (primary) |
0.3% | [0.3%, 0.3%] | 1 |
| Regressions ❌ (secondary) |
0.2% | [0.1%, 0.2%] | 3 |
| Improvements ✅ (primary) |
-0.6% | [-0.6%, -0.6%] | 1 |
| Improvements ✅ (secondary) |
- | - | 0 |
| All ❌✅ (primary) | -0.2% | [-0.6%, 0.3%] | 2 |
Max RSS (memory usage)
Results (primary 0.4%, secondary -0.3%)
A less reliable metric. May be of interest, but not used to determine the overall result above.
| mean | range | count | |
|---|---|---|---|
| Regressions ❌ (primary) |
2.7% | [1.3%, 4.5%] | 5 |
| Regressions ❌ (secondary) |
3.7% | [3.7%, 3.7%] | 1 |
| Improvements ✅ (primary) |
-2.0% | [-3.3%, -0.4%] | 5 |
| Improvements ✅ (secondary) |
-2.3% | [-3.1%, -1.6%] | 2 |
| All ❌✅ (primary) | 0.4% | [-3.3%, 4.5%] | 10 |
Cycles
Results (primary 3.3%)
A less reliable metric. May be of interest, but not used to determine the overall result above.
| mean | range | count | |
|---|---|---|---|
| Regressions ❌ (primary) |
3.3% | [3.3%, 3.3%] | 1 |
| Regressions ❌ (secondary) |
- | - | 0 |
| Improvements ✅ (primary) |
- | - | 0 |
| Improvements ✅ (secondary) |
- | - | 0 |
| All ❌✅ (primary) | 3.3% | [3.3%, 3.3%] | 1 |
Binary size
Results (primary 0.3%, secondary 0.6%)
A less reliable metric. May be of interest, but not used to determine the overall result above.
| mean | range | count | |
|---|---|---|---|
| Regressions ❌ (primary) |
0.4% | [0.0%, 1.5%] | 33 |
| Regressions ❌ (secondary) |
0.6% | [0.0%, 1.0%] | 66 |
| Improvements ✅ (primary) |
-0.2% | [-0.5%, -0.0%] | 5 |
| Improvements ✅ (secondary) |
-0.1% | [-0.1%, -0.1%] | 1 |
| All ❌✅ (primary) | 0.3% | [-0.5%, 1.5%] | 38 |
Bootstrap: 473.751s -> 473.82s (0.01%) Artifact size: 390.43 MiB -> 390.55 MiB (0.03%)
Yeah, rustdoc output is non-ideal. It shows all the where A: Allocator bounds. #148434 could probably make this better?
:umbrella: The latest upstream changes (presumably #148573) made this pull request unmergeable. Please resolve the merge conflicts.
The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
fmt check
error: expected identifier, found keyword `impl`
##[error] --> /checkout/library/alloc/src/raw_vec/mod.rs:168:7
|
168 | const impl<T, A: [const] Allocator + [const] Destruct> RawVec<T, A> {
| ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `impl`
##[error] --> /checkout/library/alloc/src/vec/mod.rs:850:7
|
850 | const impl<T, A: [const] Allocator + [const] Destruct> Vec<T, A> {
| ^^^^ expected identifier, found keyword
fmt: checked 6563 files
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Build completed unsuccessfully in 0:00:47
The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
fmt check
error: expected identifier, found keyword `impl`
##[error] --> /checkout/library/alloc/src/raw_vec/mod.rs:169:7
|
169 | const impl<T, A: [const] Allocator + [const] Destruct> RawVec<T, A> {
| ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `impl`
##[error] --> /checkout/library/alloc/src/vec/mod.rs:851:7
|
851 | const impl<T, A: [const] Allocator + [const] Destruct> Vec<T, A> {
| ^^^^ expected identifier, found keyword
fmt: checked 6563 files
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Build completed unsuccessfully in 0:00:49
The doc issue is somewhat alleviated by splitting the constified impl into its own block. This seems fine for rustdoc to handle, and it just displays two impl blocks instead of displaying duplicated A: Allocator bounds.
tidy uses the beta rustfmt and not nightly, so we need to wait until the parser changes make their way into rustfmt, or find out someway for rustfmt to skip parsing a file entirely
:umbrella: The latest upstream changes (presumably #149979) made this pull request unmergeable. Please resolve the merge conflicts.