Skip to content

Commit eda1edf

Browse files
committed
Prove cast validation and exact-size metadata inference
Specify metadata_for_exact_size and validate_cast_and_convert_metadata against independent layout calculations. Prove exact representability, greatest-fitting metadata, alignment-before-size error priority and the complete prefix or suffix result. Add Rust assertion harnesses comparing the full optional metadata and cast outcomes with remainder-based checked arithmetic. Keep address-addition bounds and the zero-stride panic exclusion visible in their domains. Outcome examples cover unattainable sizes and intentional panic separately from checks of the specification's meaning. Prove the concrete u32 slice KnownLayout initializer and every checked size_for_elems result through a Rust assertion harness. Admission traverses the actual local constant body, rather than assuming its descriptor. An initializer mutation challenges that connection. Retain reproducible native capability fixtures for generic KnownLayout, the production transmute macro, and raw pointers. Unsupported equalities, recursive declaration dependencies, and incomplete pointer carriers remain explicit blockers; no bounds or declarations are removed to admit them. gherrit-pr-id: Grerckvocdnwpdtef665ubpieo6wlwfdj Agent-authored-by: AI agent acting on joshlf's behalf
1 parent 7013978 commit eda1edf

40 files changed

Lines changed: 2555 additions & 12 deletions

‎verification/aeneas/DESIGN.md‎

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,92 @@ the library already models every part of Rust's abstract machine.
304304

305305
## Deferred decisions and reopening evidence
306306

307+
### Resource-free layout and storage work
308+
309+
The shared library supplies two independent foundations for layout and owned
310+
byte-cast proofs:
311+
312+
- `Rust.Pointer.Value` retains an address, opaque optional provenance, and
313+
metadata. Its casts and metadata operations preserve the exact provenance
314+
value. Pointer equality observes address and metadata; it does not compare
315+
provenance. Non-nullness supplies no alignment, liveness, or access permission.
316+
- `Rust.Storage.StorageDecoder` takes metadata explicitly, checks the requested
317+
byte width, and checks that a successful raw result carries that metadata.
318+
Fixed-width decoders adapt through unit metadata. Slice counts are inputs,
319+
including for zero-sized elements; byte length cannot recover those counts.
320+
321+
These are mathematical definitions and checked laws, not newly admitted Rust
322+
operations. The storage carrier still contains only initialized numeric bytes
323+
and uninitialized bytes. It does not encode pointers or decide where provenance
324+
lives in a pointer's representation. Pointer-bearing byte operations remain
325+
unsupported. Typed copies still require the treatment described in
326+
[the lowering audit](LOWERING_AUDIT.md), including
327+
[Aeneas issue #1405](https://github.com/AeneasVerif/aeneas/issues/1405).
328+
329+
Byte-cast reasoning uses the existing distinction between language validity and
330+
optional mathematical admission. The source's `IntoBytes` law ranges over all
331+
accepted language representations, regardless of mathematical admission. The
332+
destination's intended `FromBytes` law must accept every initialized storage of
333+
the correct width at both stages. The shared cast lemma composes these laws for
334+
arbitrary represented bytes. It supplies no encoder and does not claim that a
335+
particular Rust transmutation follows this interpretation.
336+
337+
The concrete `check_u32_slice_known_layout` Rust harness checks the actual
338+
`<[u32] as KnownLayout>::LAYOUT` initializer, its descriptor fields, and sizing
339+
for every element count, including checked-multiplication overflow. Admission
340+
visits the local constant's initializer body; no axiom supplies the descriptor.
341+
The visible guards expose the power-of-two and size-divisibility premises of
342+
the ABI reads. This checks that concrete numerical behavior, not the complete
343+
generic trait invariant. The proof also rejects an initializer changed from
344+
`for_slice` to `for_type`.
345+
346+
The native capability fixtures under `tests/capabilities/` preserve the next
347+
translation boundaries. With the current pins, the generic `KnownLayout`
348+
fixture retains an associated-type equality that Aeneas rejects. A second
349+
fixture without an explicit caller-side equality fails on the trait's own
350+
`MaybeUninit` metadata equality. The production
351+
`transmute!` fixture retains its compile-time trait-check helper and a loop that
352+
Aeneas rejects. The required `FromBytes` declaration dependencies additionally
353+
reach the unsupported recursive `Invariants`/`Alignment` group. These failures
354+
are not successful extraction or completed Rust proofs. Do not delete bounds,
355+
equalities, or required declarations to make those targets extract. Required
356+
recursive declaration support is deferred; dependent work must wait for tools
357+
that support it.
358+
359+
Native raw-pointer emission has a separate limitation. The pinned backend's
360+
carrier stores only `v : T`, and its scalar pointer cast returns `undef`.
361+
Emitted slice construction and `NonNull` operations remain external templates.
362+
The mathematical pointer model does not repair that carrier or grant admission
363+
to those operations. The existing checker continues to reject them. A faithful
364+
carrier and checked primitive interpretations are prerequisites for proving
365+
their address, metadata, or provenance behavior.
366+
367+
When those boundaries are supported, bind `KnownLayout::LAYOUT` to the original
368+
Rust type and its metadata-indexed geometry. Reuse the complete recursive
369+
layout semantics, which preserves an inner field's padding before outer
370+
rounding. Preserve physical tail offset, stride, alignment, and conservative
371+
padding flags. Keep mathematical extent, `usize` representability, and the
372+
`isize` object-size restriction separate. The `MaybeUninit` obligation also
373+
requires identical metadata and layout and acceptance of uninitialized storage
374+
in every position; a layout-only theorem must not be presented as the full
375+
trait invariant.
376+
377+
Concrete owned conversions use the actual standard transmute primitive for
378+
`u32` and four-byte arrays, plus a guarded `u8`-to-`bool` conversion. These types
379+
have no pointers, resources, destruction, or external-state invariants. Original
380+
Rust endpoint checks and a compiled canonical-provider audit restrict that
381+
interpretation to those cases; it does not admit the production macro or an
382+
arbitrary generic transmute. Invalid Boolean encodings take the forbidden path,
383+
even with postcondition `True`. Reference creation remains a later target because
384+
numerical geometry and provenance presence alone do not supply permissions or
385+
lifetimes. Derive
386+
proof requests are also deferred. Existing annotation discovery, native binding
387+
records, independent golden/live proofs, and dependency audits remain the sole
388+
route to reporting a Rust specification as checked; these foundations add no
389+
parallel coverage registry or automatic Rust ABI assumptions.
390+
391+
### Other deferred decisions
392+
307393
- **Canonical layout abstraction.** Retain structural `DstLayout` and existing
308394
`ModelViews` initially. Padding and trailing-size pilots already use those
309395
views. Use `extend`, sequence queries, and capacity contracts to compare total
@@ -325,8 +411,8 @@ the library already models every part of Rust's abstract machine.
325411
tactics, and the existing loop adapter. Introduce a larger lifting DSL,
326412
per-model tactics, or new loop abstraction only after concrete repeated
327413
failures show a net benefit over ordinary lemmas and a thin tactic.
328-
- **Broader carriers and effects.** Recursive nominal groups, indexed carriers,
329-
const generics, associated-type trait laws, higher-ranked bounds, bounded
414+
- **Broader carriers and effects.** Recursive nominal groups, general indexed
415+
carriers, const generics, associated-type trait laws, higher-ranked bounds, bounded
330416
nominal models, and escaping borrow reconstruction remain unsupported with
331417
explicit errors. The first trait-law bridge supports `Self`-only traits and
332418
simple generic bounds, with `Unaligned` and a total byte codec as checked
@@ -338,11 +424,12 @@ the library already models every part of Rust's abstract machine.
338424
execution, independently of ordinary library-model admission. A storage model
339425
must account for the translation's omissions as well as its primitives. The
340426
[pinned lowering audit](LOWERING_AUDIT.md) records known omissions and the
341-
additional admission checks needed before making memory-safety claims.
342-
[ADMISSION_DESIGN.md](ADMISSION_DESIGN.md) specifies the proposed closed
427+
admission checks needed before making memory-safety claims.
428+
[ADMISSION_DESIGN.md](ADMISSION_DESIGN.md) specifies the closed
343429
dependency traversal, controlled build origins using Charon's existing MIR
344-
preservation setup, primitive rules, and mandatory CI path. These additional
345-
checks are not implemented yet.
430+
preservation setup, primitive rules, and mandatory CI path. CI enforces
431+
these checks for the admitted fragment; extending that fragment requires
432+
corresponding operation semantics and coverage checks.
346433
<!-- FIXME: Typed transfers lose storage events; track support at
347434
https://github.com/AeneasVerif/aeneas/issues/1405. Until then, a typed storage
348435
abstraction must forget all padding contents and initialization facts. It

‎verification/aeneas/README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,10 @@ padding inside packed fields.
390390
A positive size-sequence comparison establishes equal sizes for every natural
391391
metadata value; a negative result does not assert that the sequences differ.
392392

393+
Cast validation and exact metadata inference establish error priority, exact
394+
splits and rejection of unattainable sizes. Intentional zero-stride panic is
395+
checked separately.
396+
393397
Plain arithmetic clauses use mathematical word values carrying machine bounds
394398
and, for NonZero, positivity. They coerce to `Nat` or `Int` without unwrapping
395399
raw fields. Binding `let N : Nat := n` makes addition and remainder ordinary

0 commit comments

Comments
 (0)