Skip to content

Upgrade Rust toolchain to nightly-2026-06-01 - #4760

Open
feliperodri wants to merge 1 commit into
model-checking:mainfrom
feliperodri:toolchain-2026-06-01
Open

Upgrade Rust toolchain to nightly-2026-06-01#4760
feliperodri wants to merge 1 commit into
model-checking:mainfrom
feliperodri:toolchain-2026-06-01

Conversation

@feliperodri

@feliperodri feliperodri commented Aug 25, 2026

Copy link
Copy Markdown
Member

Description

Bumps rust-toolchain.toml from nightly-2026-05-01 to nightly-2026-06-01. Four upstream changes drive most of this.

1. Retag moved onto Rvalue::Use

StatementKind::Retag and RetagKind are gone; Rvalue::Use now carries a WithRetag flag instead:

Use(Operand, WithRetag),

Kani never modelled retags (they are Stacked-Borrows/Miri only), so the statement arms are dropped, the flag is ignored when reading a Use, and synthesized Uses pass WithRetag::No. internal_mir's RetagKind conversion becomes a WithRetag one.

2. Variants::Multiple stores a VariantLayout, not a LayoutData

The new type carries only per-field offsets — no FieldsShape (so no field order) and no alignment. Variant layouts now come from Layout::for_variant, which is what rustc_codegen_ssa does and which restores the field order. A new variant_layout helper is used by both the type side (codegen_enum_cases) and the value side (codegen_aggregate), so the goto struct's components and the operands initializing them cannot disagree.

That change bit back: for_variant reports the enum's align for a variant (align: parent.align), which over-pads every variant and inflates the enum. check_vtable_size caught it as an ICE on tests/cargo-kani/iss2857 (48 vs 55 bytes). So codegen_struct_fields/codegen_alignment_padding now take the align explicitly, and a variant's own align is computed as the maximum of its fields' aligns — which is what the per-variant LayoutData used to carry.

3. rustc_layout_scalar_valid_range_start/_end were removed

Replaced by pattern types, the same move core::num::niche_types made. The tests that define ranged scalar newtypes are converted to std::pat::pattern_type!.

This narrows the layout-niche feature added in #4716: a pattern type is not an ADT and has no Arbitrary implementation, so can_derive_arbitrary cannot synthesize a struct that has one as a field, and locally-defined ranged types are now skipped rather than harnessed. The assumption still works end to end through std::time::Duration (the motivating case from the #3832 triage), and tests/script-based-pre/autoharness_niche pins both halves so the reduced reach is asserted by a test rather than silent. Tracked in #4758 with a concrete fix sketch.

4. New Rvalue::Reborrow

User-definable reborrowing of ADTs via CoerceShared. It is documented as a bitwise copy today, but the same docs anticipate it changing memory layout, so codegen reports it as an unsupported construct rather than silently modelling it as a copy. The points-to analysis treats it as pointing wherever its place does.

Assorted API changes

Change Site
CodegenBackend moved CrateInfo from codegen_crate to join_codegen both backends' compiler_interface.rs
rustc_data_structures::stable_hasher renamed to stable_hash; HashStable/hash_stable to StableHash/stable_hash reachability.rs
The normalize callback of ptr_metadata_ty{,_or_tail} now takes Unnormalized typ.rs
More FieldDef::ty and instantiate* sites need .skip_normalization() typ.rs, intrinsics.rs
TagEncoding::Niche's niche_variants is the lang RangeInclusive (public start/last fields, not methods) rvalue.rs, statement.rs
New useless_borrows_in_formatting clippy lint 11 sites across the workspace

Test change worth calling out

vtable_size_align_drop no longer asserts the exact identity of the vtable's drop pointer. Traced with Kani's debug logging: the drop-glue shim is now core::ptr::drop_glue::<T> rather than core::ptr::drop_in_place::<T>, and drop_glue is not nameable from source. It checks the slot is populated instead; the size and align fields the test is named for are unchanged. This weakens the test — it no longer checks the slot holds the drop glue for the right type — so it is tracked in #4759 with options for restoring that coverage.

Both of these failures were confirmed to be genuine nightly-2026-06-01 regressions rather than pre-existing fragility, by rebuilding the parent commit against nightly-2026-05-01, where both pass.

drop_in_place now takes a reference to reach the drop glue

Related to the same rename: core::ptr::drop_in_place used to be the drop lang item, with its body replaced wholesale by the compiler. It is now a wrapper that calls the new drop_glue lang item through &mut *to_drop, and creating that reference asserts the pointee is aligned and valid — so dropping through a raw pointer carries a precondition it did not before.

That surfaced in expected/loop-contract/loop_assigns_for_vec.rs, whose loop_modifies havocs the word holding v.len() while the invariant only constrains i; the drop after the loop then sees an unconstrained length. Strengthening the invariant with v.len() == i * 3 + 3 is rejected (Rust intrinsic assumption failed), so expressing what the drop needs looks like a loop-contracts limitation rather than something this PR can fix. The test is renamed loop_assigns_for_vec_fixme.rs with the analysis recorded in the file, tracked in #4761. Verified that Vec's internal layout is unchanged, so the test's hard-coded .add(2) offset for len is still correct.

Two contract tests that deliberately pin a total check count needed their numbers updated: capture_load_checks_elided 36 → 34 and capture_load_user_deref_pass 60 → 58 (two checks in read_answer's own body became unreachable). In both cases the assertion the test actually exists for still holds — no user-facing pointer_dereference group came back in the first, and the pinned {closure#3}::{closure#0}.pointer_dereference.1 - Status: SUCCESS is still present in the second — so the counts were updated with a note in each test explaining that the total is plumbing-sensitive and what it still guards against.

Testing

Local, macOS aarch64, CBMC 6.10.0 (cbmc-6.9.0-214-g45436eea34), all re-run after rebasing onto current main (which now includes #4717, whose new Rvalue::Use construction site also needed the WithRetag argument):

Suite Result
kani 607 passed, 0 failed, 23 ignored
cargo-kani 71 passed, 0 failed
script-based-pre 68 passed, 0 failed, 1 ignored
std-checks 5 passed, 0 failed
cargo-ui 30 passed, 0 failed
coverage 20 passed, 0 failed
ui 151 passed, 2 failed — both the cadical tests, see below
expected 474 passed, 0 failed, 16 fixme/ignored
prusti / smack / kani-docs / json-handler / cargo-coverage / firecracker 8 / 40 / 13 / 5 / 2 / 0 passed, 0 failed

Other gates, all clean:

  • cargo build-dev
  • cargo build-dev -- --features cprover --features llbc
  • cargo clippy --workspace --tests and RUSTFLAGS="--cfg=kani_sysroot" cargo clippy --workspace
  • ./scripts/kani-fmt.sh --check
  • RUSTFLAGS="-D warnings" cargo build --no-default-features --features cprover
  • Unit tests: cprover_bindings, kani-compiler, kani-driver, kani_metadata, kani --features concrete_playback, kani_macros

Environment caveat: this CBMC build has no cadical, so ui/solver-{attribute,option}/cadical fail locally on output text only ("The specified solver, 'cadical', is not available"), and expected/shadow/slices/slice_split is very slow under the MiniSat fallback. Both are expected to be clean on CI.

Towards #4758, #4759, #4761.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Four upstream changes drive most of this.

**Retag moved onto `Rvalue::Use`.** `StatementKind::Retag` and `RetagKind` are
gone; `Rvalue::Use` now carries a `WithRetag` flag instead. Kani never modelled
retags (they are Stacked-Borrows/Miri only), so the statement arms are dropped,
the flag is ignored when reading a `Use`, and synthesized `Use`s pass
`WithRetag::No`. `internal_mir`'s `RetagKind` conversion becomes a `WithRetag`
one.

**`Variants::Multiple` stores a `VariantLayout`, not a `LayoutData`.** The new
type carries only per-field offsets -- no `FieldsShape` (so no field order) and
no alignment. Variant layouts now come from `Layout::for_variant`, which is what
`rustc_codegen_ssa` does and restores the field order; a new `variant_layout`
helper is used by both the type side (`codegen_enum_cases`) and the value side
(`codegen_aggregate`) so the goto struct's components and the operands
initializing them cannot disagree.

`for_variant` reports the *enum's* align for a variant (`align: parent.align`),
which would over-pad every variant and inflate the enum -- caught by
`check_vtable_size` on `tests/cargo-kani/iss2857` (48 vs 55 bytes). So
`codegen_struct_fields`/`codegen_alignment_padding` now take the align
explicitly, and a variant's own align is computed as the maximum of its fields'
aligns, which is what the per-variant `LayoutData` used to carry.

**`rustc_layout_scalar_valid_range_start`/`_end` were removed** in favour of
pattern types, the same move `core::num::niche_types` made. The tests that
define ranged scalar newtypes are converted to `std::pat::pattern_type!`. Note
the consequence for autoharness: a pattern type is not an ADT and has no
`Arbitrary` implementation, so `can_derive_arbitrary` cannot synthesize a struct
that has one as a field, and locally-defined ranged types are now skipped rather
than harnessed. The niche assumption added in model-checking#4716 is still exercised end to end
through `std::time::Duration`; `tests/script-based-pre/autoharness_niche` pins
both halves so the reduced reach is asserted rather than silent.

**New `Rvalue::Reborrow`** (user-definable reborrowing of ADTs via
`CoerceShared`). It is documented as a bitwise copy today, but the same docs
anticipate it changing memory layout, so codegen reports it as an unsupported
construct rather than silently modelling it as a copy. The points-to analysis
treats it as pointing wherever its place does.

Also adapts to: the `CodegenBackend` trait moving `CrateInfo` from
`codegen_crate` to `join_codegen` (both backends), `rustc_data_structures::
stable_hasher` being renamed to `stable_hash` with `HashStable`/`hash_stable`
becoming `StableHash`/`stable_hash`, the `normalize` callback of
`ptr_metadata_ty{,_or_tail}` now taking `Unnormalized`, more `FieldDef::ty` and
`instantiate*` sites needing `.skip_normalization()`, `TagEncoding::Niche`'s
`niche_variants` becoming the lang `RangeInclusive` (public `start`/`last`
fields), and the new `useless_borrows_in_formatting` clippy lint.

The `vtable_size_align_drop` test no longer asserts the exact identity of the
vtable's drop pointer: the drop-glue shim is now `core::ptr::drop_glue::<T>`
rather than `core::ptr::drop_in_place::<T>`, and `drop_glue` is not nameable
from source. It checks the slot is populated instead; the size and align fields
that the test is named for are unchanged.
@feliperodri

Copy link
Copy Markdown
Member Author

The next upgrade, nightly-2026-07-01, is up as a draft in #4764 stacked on this one. It is much smaller (no verification behaviour changed and no test needed adjusting) and should be reviewed once this lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants