Expand description
Interprocedural call summaries derived from MIR for local wrapper functions.
When no hand-crafted summary exists, this module inspects a calleeโs own MIR
to approximate its effects: pointer-arithmetic wrappers, from_raw_parts
wrappers, argument-to-return dataflow, and index-disjointness validators.
Enumsยง
- Tuple
Field ๐Len - Length kind of a decoderโs returned tuple length field.
- Wrapper
Effect ๐Memo - Memo state for the transitive wrapper-effect walk:
Computingmarks a callee currently being resolved (a re-entry is a self/mutual-recursive cycle),Donecaches the finished result.
Functionsยง
- block_
dominates ๐ - Whether block
adominates blockb(every path from the entry tobpasses througha). Simple BFS:adominatesbiffbis not reachable from the entry whenais skipped. - body_
reads_ ๐slice_ len - Whether
bodycontains alencall whose receiver traces back to argument 0. - call_
result_ ๐reaches_ return - Return true when
call_destโs value flows (via Copy/Move/Cast) to the functionโs return place_0. - callee_
calls_ ๐other_ local - Return true if the callee body contains any Call terminator, meaning the callee is not self-contained (a nested call may have side effects that a shallow summary cannot capture).
- callee_
contains_ ๐pointer_ arithmetic - Check whether a callee body contains pointer arithmetic calls.
- context_
key ๐ - Canonical, sortable representation of a
CallContextโs concrete arguments, used as part of the memo key (FxHashMapis notHash). - copy_
root ๐ - Trace a local back through
x = copy y/x = move yassignments to its copy root (the original loop variable before MIR temporaries). - detect_
index_ ๐disjoint_ validator - Detect an โindex disjoint validatorโ: a function whose body loads elements
from an array argument, and returns early (
Err) both when an element is out of range against a scalar argument (>= len) and when two elements are equal (a duplicate). Returns(indices_arg, len_arg). - detect_
pre_ ๐dec_ end_ offset - Detect a
pre_dec_end(offset)call on the receiver (arg 0) and return its constant offset.next_back_uncheckedcallsself.pre_dec_end(1)before returning theend_or_lenfield, so the returned pointer must be adjusted byoffsetelements. - iter_
ctor_ ๐reads_ slice_ len - Whether the callee (following at most
depthsingle-call wrappers) reads the length of its slice argument โ a necessary condition for a slice iterator, whoseendfield isstart + len. - local_
must_ ๐write_ args - Return callee argument indices that are definitely written on every
reachable return path, pruning paths infeasible under
context. Works for any callee with available MIR, and follows wrapper calls (Vec::pushโpush_mut) with bounded depth. - local_
return_ ๐dependencies - Use the existing dataflow graph to approximate callee return deps.
Works for any callee with available MIR (local or cross-crate
#[inline]). - must_
write_ ๐args_ rec - named_
index_ ๐disjoint_ validator - Recognize the standard-library
get_disjoint_check_validhelper as a trusted index-disjoint validator by name. - nested_
call_ ๐context - Build the
CallContexta nested call sees, keyed by the nested calleeโs own argument indices. Each nested argument is concrete either because it is a literal at this call site, or because it passes an outer concrete value straight through (Copy/Moveof an argument). This keeps a callerโs literal at positionifrom being read as the nested calleeโs position-iargument. - operand_
is_ ๐ptr_ metadata - Whether
operand(through copy/move temps) isPtrMetadata(slice), including aslice.len()call (which is semanticallyPtrMetadata). - path_
ends_ ๐in_ return - path_
infeasible_ ๐under_ context - Return
trueifpathis provably infeasible undercontext, by folding aSwitchIntwhose discriminant is a direct copy of a concrete argument. Only prunes when the taken target is uniquely determined, so a feasible path is never removed. - pointer_
arith_ ๐wrapper_ probe - Single-effect recognizer for
resolve_wrapper_effect: doescalleedirectly wrap a pointer add/sub, or delegate to a nested callee that itself resolves to one? - resolve_
wrapper_ ๐effect - Resolve
calleeโs wrapper effect by walking nested wrapper calls, with cycle detection and memoization.probeinspectscalleeโs body and, for a nested call it follows, invokesrecurse, which routes back through this resolver so the memo applies uniformly. A callee re-entered while still being resolved is a cycle and resolves toNone(no finite wrapper chain). - single_
call_ ๐wrapper_ target - The callee delegated to by a thin wrapper whose body is a single call
returning directly into
_0(e.g.slice::iterโIter::new). - switch_
discriminant_ ๐concrete - Trace a
SwitchIntdiscriminant back to a concrete argument value, following only directCopy/Moveassignments (no casts or pointer arithmetic) so the recovered value is identical to the argumentโs. - trace_
to_ ๐callee_ arg - Trace backward from an operand (inner call arg) through Copy/Move/Cast/
Ref/RawPtr assignments to the outer calleeโs argument local, returning its
index.
Ref/RawPtrare treated as data-flow too, which is an approximation (taking a reference is not a pure copy) but is adequate for wrapper recognition. - try_
branch_ ๐effect - Detect
<Option<T> as Try>::branch:Option<T>->ControlFlow<Option<!>, T>. TheContinuepayload (field 0) equals theSomepayload (field 0), so a?-operatorif let Some(..) = expr?unwrap keeps the payloadโs provenance. - try_
decode_ ๐length_ return_ effect - Detect a UTF-8-decoder shape: the function returns
Option<(.., usize, ..)>whose length field is a constant on eachSomereturn, and eachSome((.., len))return is guarded by aslice.get(len - 1)?(solen <= slice.len()). Summarizes the tupleโs length field asfield <= arg.len()so a caller can re-provefinger <= finger_backafterfinger += len. - try_
field_ ๐load_ effect - Detect a field-getter callee from its MIR: a function whose body is
(essentially)
(*self).fieldโ a singleDeref+Fieldload returned as the functionโs result. Produces aReturnFieldOfArgeffect so the materialized field is returned, without any name- or length-specific knowledge. - try_
from_ ๐raw_ parts_ wrapper_ effect - Detect when a local callee wraps
from_raw_parts(ptr, len)and produce aReturnFreshAllocationeffect with the correct element size. - try_
iter_ ๐constructor_ effect - Detect a slice-iterator constructor structurally: a callee whose argument
is a
&[T]/&mut [T]and whose return type is a struct whose first two fields are pointers intoT(field 0 = startNonNull<T>, field 1 = end*const T/*mut T). This matchesslice::Iter/IterMutand same-shaped local re-implementations by structure rather than by the typeโs name. - try_
pointer_ ๐arith_ wrapper_ effect - Probe whether
calleeis a pointer-arithmetic (add/sub) wrapper, following nested wrapper calls transitively.effect_summaryruns this on every local callee; it returnsNonefor anything that is not โ transitively โ a pointer add/sub wrapper. - try_
ptr_ ๐field_ return_ effect - Detect a function that returns a raw-pointer field of its receiver
(
(*self).end_or_len-shaped), even when the body also contains a ZST/non-ZST branch and a preceding mutation call (e.g. an iteratorโsnext_back_unchecked). Produces aReturnFieldOfArgeffect so the returned pointer keeps the fieldโs provenance across the interprocedural boundary. - try_
slice_ ๐bounded_ return_ effect - Detect a
memchr-style search function: it returnsOption<usize>whoseSome(i)payload is an index guarded by a loop conditioni < arg.len()(whereargis a slice argument). The summary lets a caller re-prove a numeric invariant likefinger <= finger_backafterfinger += i + 1. - tuple_
field_ ๐len_ kind - Classify the length field of a
(.., len, ..)tuple, tracing through copy/move temps and a_tmp = (..)tuple aggregate assignment. - write_
args_ ๐on_ path
Type Aliasesยง
- Must
Write ๐Memo - Cached must-write summaries, keyed by
(callee, depth, context). Depth is part of the key because thedepth > 4cutoff makes a summary computed deeper in the wrapper chain less complete than one computed higher up, and the DFS reaches the deep ones first. The context is part of the key because one query can reach the same callee with different concrete arguments, which prune different paths.