Fix three constructor-discovery ICEs from the crates.io sweep - #4725
Draft
tautschnig wants to merge 3 commits into
Draft
Fix three constructor-discovery ICEs from the crates.io sweep#4725tautschnig wants to merge 3 commits into
tautschnig wants to merge 3 commits into
Conversation
A layout niche (rustc_layout_scalar_valid_range, as used by std's NonZero and core::time::Duration's Nanoseconds field) is a language-level validity invariant: a value outside the niche is as invalid as a bool holding 3, and rustc packs enum variants into the invalid patterns. Nondeterministic-value generation for types without an Arbitrary implementation previously produced such values, which is unsound in the garbage-in sense and causes false alarms in every harness generating the type. After each generated value of a scalar-ABI type whose valid range is restricted, emit kani::assume(<raw bits> in valid_range), handling wrapping ranges (NonZero's 1..=0). Sound by construction: no flag or report marker needed. Verified on the time crate: fixes the InstantExt/SystemTimeExt signed_duration_since harnesses (std Duration receivers); the regression test's covers confirm no over-constraining. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The top-100 crates.io failure triage (model-checking#3832) showed the largest class of genuine false alarms is generated receivers violating private type invariants (e.g. time's Date packs a validated ordinal; raw field synthesis produces invalid dates, failing every method harness). Under the new opt-in --constructor-args flag, kani::any::<T> for private-field structs is synthesized as: generate nondeterministic constructor arguments, call one of T's public constructors, assume success (switching on the discriminant for Option<Self>/Result<Self, E> returns), and return the payload. Constructor search excludes non-public, doc-hidden (commonly _unchecked variants exported for macros that assert preconditions), unsafe, zero-argument (single-point coverage; Instant::now() reaches unsupported clock_gettime), and generic constructors; it prefers Self over Option<Self> over Result<Self, E> returns, then more arguments over fewer. The option is opt-in because it under-approximates (only constructor-reachable values are explored): harnesses are marked "(ctor)" via new is_ctor_based metadata, with an explanatory note in the summary. Measured on time-0.3.54: 341 -> 538 verified, 500 -> 315 failures. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Surfaced by a top-500 crates.io autoharness sweep (12 crates affected): 1. Items with their own early-bound lifetimes (AtomicU8::from_ptr<'a>) were resolved with the ADT args only, panicking on the arity mismatch (brotli, sharded-slab). 2. Lifetime-parameterized impls place lifetimes anywhere in the generics order (impl<'h> Searcher<'h> in regex-automata; also gimli, redox_syscall, arc-swap, clap_builder, event-listener, crypto-bigint), so appending erased lifetimes is not enough: build the argument list positionally against the item's full parent+own generics, rejecting the constructor when counts or kinds do not fit (rustc's instantiation panics on kind mismatches rather than returning Err). 3. Constructor arguments carrying escaping late-bound regions inside ADTs (BorrowedFd<'_> in async-io, js-sys, quinn-udp, wasm-bindgen) panicked the trait solver's dummy-binder wrap; such arguments are not generatable, so reject the candidate up front. The constructor regression test gains all three shapes. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #4717 (
--constructor-args); only the last commit is new. Marked draft until #4717 merges.A top-500 crates.io autoharness sweep (tracking #3832) ICEd in constructor discovery on 12 crates; three root causes:
AtomicU8::from_ptr<'a>-style constructors were resolved with the ADT args only — arity mismatch panic.impl<'h> Searcher<'h>places the lifetime first, so appending erased lifetimes is insufficient — the argument list is now built positionally against the item's full parent+own generics, rejecting shape mismatches up front (rustc's instantiation panics on kind mismatches rather than returningErr).BorrowedFd<'_>-style arguments read from a skipped fn-sig binder panicked the trait solver's dummy-binder wrap; such candidates are rejected as non-generatable.All 12 crates verified clean with this branch. The constructor regression test gains all three shapes.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.