Expand description
Datafrog-based NLL borrow solver.
Implements Non-Lexical Lifetimes using Datafrog’s monotone fixed-point engine. This is the core of Shape’s borrow checking — it determines which borrows are alive at each program point and detects conflicts.
Single source of truth: This solver produces BorrowAnalysis, which is
consumed by the compiler, LSP, and diagnostic engine. No consumer re-derives results.
§The Datafrog pattern
Datafrog is a lightweight Datalog engine that computes fixed points over monotone relations. The pattern used here is:
- Define input relations — static facts extracted from MIR that never
change during iteration (e.g.
cfg_edge,invalidates). - Define derived variables — monotonically-growing sets computed by
Datafrog’s iteration engine (e.g.
loan_live_at). - Seed the derived variable with initial facts (each loan is live at its issuance point).
- Express rules as
from_leapjoincalls inside awhile iteration.changed()loop. Each rule joins a derived variable against input relations and produces new tuples. Datafrog deduplicates and tracks whether any new tuples were added (thechanged()check). - Convergence: Because all relations are sets of tuples and rules only add (never remove), the iteration terminates when no new tuples are produced — the monotone fixed point.
- Post-processing: After convergence, the derived relation is
.complete()-d into a frozenRelationand scanned for error conditions.
§Input relations (populated from MIR)
loan_issued_at(Loan, Point)— a borrow was createdcfg_edge(Point, Point)— control flow between pointsinvalidates(Point, Loan)— an action invalidates a loanuse_of_loan(Loan, Point)— a loan is used (the ref is read/used)
§Derived relations (Datafrog fixpoint)
loan_live_at(Loan, Point)— a loan is still activeerror(Point, Loan, Loan)— two conflicting loans are simultaneously active
§Additional analyses
- Post-solve relaxation:
solve()skipsReferenceStoredIn*errors when the container slot’sEscapeStatusisLocal(never escapes). - Interprocedural summaries:
extract_borrow_summary()derives per-function conflict pairs for call-site alias checking. - Task-boundary sendability: Detects closures with mutable captures crossing detached task boundaries (B0014).
Structs§
- Borrow
Facts - Input facts extracted from MIR for the Datafrog solver.
- Solver
Result - Raw solver output (before combining with liveness for full BorrowAnalysis).
Functions§
- analyze
- extract_
borrow_ summary - Run the complete borrow analysis pipeline for a MIR function. This is the main entry point — produces the single BorrowAnalysis consumed by compiler, LSP, and diagnostics. Extract a borrow summary for a function — describes which parameters are borrowed and which parameter pairs must not alias at call sites.
- extract_
facts - Populate borrow facts from a MIR function and its CFG.
- solve
- Run the Datafrog solver to compute loan liveness and detect errors.
Type Aliases§
- Callee
Summaries - Callee return-reference summaries, keyed by function name.