Repository navigation
Allow --verify-function more than once - #68
Open
kiranandcode wants to merge 8 commits into
Open
kiranandcode wants to merge 8 commits into
kiranandcode wants to merge 8 commits into
Conversation
Each pattern selects functions as before, with its own no-match and ambiguity errors; the run verifies the union. A single flag behaves as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every pattern is resolved before failing; the no-match and ambiguity messages of all bad patterns go into one error, each worded as before. --verify-function now accepts several --verify-only-module (and --verify-root alongside them). Each pattern is matched across all of them; a pattern that matches in two modules is an error unless it is qualified by its module (foo::bar::f, or crate::f for the root). Qualifiers are only recognised with more than one module, so a single module behaves exactly as before. UserFilter::Function is now (Vec<ModuleId>, HashSet<Fun>), without the unused pattern list, and each module's function names are built once. The help text names the value PATTERN and describes the union. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A pattern is first matched as written; only if that fails is a leading module name (`m::`, `crate::m::`, or `crate::` for the root) taken as a qualifier, longest first. This works with one selected module too, so a caller can always qualify. Inputs that work on main are unchanged. - An unqualified name such as `T::f` (a method of `T` in another module) is no longer read as `f` in a selected module `T`. - Wildcard matches in several modules are unioned; only an exact name that matches in two modules is an error. The "consider *pat*" hints now work. - Share module-name formatting with `verifier::module_name`. - Tests run through `run_verus_raw` (binary suffix, solver paths) and compare the joined error without depending on rustc's indentation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A qualified pattern was matched as written first, and read as qualified only if that failed. So `a::f` could select `Data::f` (a unique substring match) over `f` in module `a`, and an ambiguity across modules could be resolved silently by the qualified reading. - With several modules, each function is matched by the pattern as written and by the pattern without its own module qualifier, in the same step: exact (or wildcard) matches first, then unique substring matches. An exact name that matches in two modules, by any reading, is an error; its hint names `crate::m::f` when `m::f` is the pattern itself. - With one module, the pattern is first matched only as written, exactly as on main, so every pattern that works on main selects the same functions with byte-identical output; qualified readings apply only when that fails. - Qualifiers come from the module's friendly name (the one names are made relative to), with the crate name written `crate`; a name that is not relative to its module is shown and matched as is, not prefixed. - Wildcard hints list one wildcard per reading that matched. - The four error listings share one helper. - The help text no longer stops mid-sentence. - The two-module ambiguity test compares lines without rustc's indentation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With one module, every pattern selects what it selects on main. Otherwise (several modules, or a pattern with `::` that main cannot resolve), a pattern with `::` is also matched against each function's path from the crate root, with or without `crate::`, and a pattern without `*` at its ends must select exactly one function, whether or not the matches share a module. The ambiguity hint suggests a name that the same rule resolves to one function, and the wildcard hints match by the same names, so they select what is listed. A function named by a path outside its module (`impl crate::second::Item` inside `first`) can now be named `crate::second::Item::moved`. A pattern is exact when it has no `*` at either end, as on main. A repeated pattern is resolved (and reported) once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every pattern goes through one rule. A pattern is matched against each function's name relative to its module, and, with `::`, also against its path from the crate root and its module's path followed by its relative name, each with or without `crate::`. Exact or wildcard matches come first, then a unique substring. Exact matches in one module are all selected; exact matches in several modules are ambiguous. - Methods of impls of one type in two modules can be told apart by module (`ta::S::f`). - The ambiguity hint names one function, or else the functions of one module, and no longer suggests a wildcard that selects more. - Listings with several modules show where same-named functions are defined. - Comments and tests describe the rule rather than main. - Function names are derived from the full name once, with each module's prefixes computed once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An exact pattern is matched against relative names first, then against the qualified names (path from the crate root, module path), then by unique substring. So `line::f` with module `line` selects the method `line::line::f`, as on main, rather than also `f` in `line`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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.
--verify-functioncan now be given more than once, and used with several modules.Semantics
*wildcards at the ends. The run verifies the union of the selections, and each function is checked once.--verify-functionstill needs--verify-only-moduleor--verify-root, and still rejects--verify-module.--verify-only-modulecan be repeated, and--verify-rootcan be added alongside. A repeated module counts once.One rule
Every pattern goes through one matcher, whether one module or several are selected.
Names: every pattern is matched against each function's name relative to its module (as before). A pattern with
::is also matched against:crate::(first::shared,crate::first::shared,crate::betafor the root);crate::. Forimpl crate::S<u8> { fn f }written in moduleta, that ista::S::f. So methods of impls of one type in two modules can be told apart.Wildcards: a pattern with
*at either end selects every function with a name it matches, by any of these names.Exact patterns (no
*at either end) go through one precedence step, the same with one module or several:All matches at the first step that finds any are selected if they are in one module (e.g.
G::gselects bothG<u8>::gandG<u16>::g, and so doesninth::G::g). Matches in more than one module are an ambiguity error. Soline::fwith modulelineis the methodfofline::line(its relative name), as onmain, and not alsofin moduleline(its path).crate::line::fandline::line::feach select one.Hints follow the same rule:
eleventh::ninth::G::gwhenninthandeleventheach have two methodsninth::G::g.{pattern}*is gone, since it also selected other functions starting with the pattern. If no name selects even one module's matches, the error says so and gives no hint.*pat*and the "could not find" hint*clean*match by the same names, so they select exactly the functions listed.Listings with several modules show each function's path from the crate root (
crate::plus the name for the root). When several listed functions share a name, each gets its location:- S::f (at src/lib.rs:98:31). With one module, listings are unchanged.Methods of impls for a type of another crate (e.g.
impl Tw for Seq<int>in moduletwelfth) have no path from the crate root, because their name is the other crate's path (vstd::seq::Seq::tw). They can still be qualified: by the module's path followed by that name,twelfth::vstd::seq::Seq::tw(orcrate::twelfth::vstd::seq::Seq::tw). That spelling is not a real Rust path, but it is unique to the module.Compared with
mainPatterns without
::, with one module: byte-identical tomain, since they match only the relative name, and with one module there is no ambiguity error and no location in listings.Patterns with
::that work onmainand change, from the comparison below (20 of 318 working inputs). Exact patterns thatmainmatches exactly by relative name are unchanged.:mainresolved as an accidental unique substring:a::fin modulea:mainselectsData::f(its name containsa::f); now selectsf, whose path isa::f.::infirst,aandline, and::finaandline:mainselects the one relative name containing::(e.g.Data::f). Every path contains::, so these are now "more than one match" errors.*a::f,*a::f*,*a::*,*a::**,*::f,*::f*ina;*::*infirst,aandline;*::f,*::f*,*line::f,line::f*,*line::f*inline.Changes
config.rs: help text forPATTERN. The "at most one--verify-only-moduleor--verify-root" check is gone.user_filter.rs:UserFilter::Function(Vec<ModuleId>, HashSet<Fun>).FunNameholds the module, the relative name, the qualified names, the listed name and the location. The relative name and the path are cut from the function's full name. Each module's prefixes are computed once, so the friendly-name map's lock is taken once per function (plus once per module).resolveis the single rule. It returns aResolution, andmessagewords the error.driver.rs:is_verifying_entire_cratechecksis_empty().is_verifying_entire_crateignores--verify-only-module(already so onmain), so a run with only--verify-only-moduleprints no "(partial verification …)" note.Testing
rust_verify_test/tests/verify_function.rshas 29 tests, all passing. They run throughcommon::run_verus_rawand compare error messages line by line. They cover:*shar*hints that work;first::shared,first::only_*,crate::beta,crate::alphhinting*crate::alph*, which verifies 2);a::fselectsfwithaalone and withaandfirst, and so doescrate::a::f;a::Data::fselectsData::f;cell::facrosscell,fifthandsixthis the relative name of the methods infifthandsixth, so it is ambiguous between those two and hintsfifth::cell::f;crate::cell::fselectsfincell;line::fselects only the methodline::line::f(its relative name wins over the path off), withlinealone and withlineandfirst;crate::line::fandline::line::feach select one;first,secondandeighth(structfirstwith methodshared),sharedhintscrate::first::shared, notfirst::shared;G::g,ninth::G::gandcrate::ninth::G::geach verify both methods, withninthalone and withninthandfirst;crate::Sintaandtb:S::fis ambiguous, hintsta::S::f, and lists both with their locations;ta::S::fandcrate::ta::S::fselect one;ninth::G::gwithninthandeleventh(two methods each): the hint names one module's functions (eleventh::ninth::G::g), which verifies 2;twelfth::vstd::seq::Seq::twnames a method of an impl forvstd'sSeq;moved(infirst, ofsecond::Item) is listed assecond::Item::movedand matched bycrate::second::Item::moved,second::Item::moved, its full name andfirst::second::Item::moved, with one or two modules.Also:
module_order(1),report_json(11) andresident(70) pass withVERUS_CVC5_PATHset to an absolute path.vargo fmt -- --checkis clean. I did not run the fullrust_verify_testsuite.main: a release binary built fromorigin/main(3fa79fdb) against this branch, on 4720 single-module, single-pattern invocations of the test fixture: 16 module selections × 295 patterns (exact, substring, ambiguous, no-match, each with*at either or both ends, module- andcrate::-qualified, type-qualified, interior*,::,*). Compared stdout, stderr and the exit code.main: 298 are byte-identical, and the 20 that differ are the::patterns listed above.main, 266 now give different output, and every one of them contains::.Earlier real check (first commit, one module)
On verified-nrkernel
impl_u::os_refinement(pristine), with the os-bench flags (-V cvc5 --rlimit 10 --num-threads 4 --multiple-errors 50):step_MapEnd_refineslemma_map_soundness_equalitylemma_protect_soundness_equalitystep_MapEnd_refines+lemma_protect_soundness_equalitymainbinary, both flagsOption 'verify-function' given more than once, exit 255The saving per extra function is one front end. The box was shared, so the timings are only indicative. I have not re-run nrkernel with several modules.
Why: the os-bench
veruswrapper re-runs fork verus on the changed functions that fail, for--expand-errors. With this change it can do that in one process, even when the functions are in different modules, and it can always pass qualified names.🤖 Generated with Claude Code