FA-44316 / Borrow checking / Open access
Index lowering reorders index-side mutation before the base borrow · case 01
Index lowering reorders index-side mutation before the base borrow.
ROOT CAUSE
The static analyzer mishandles index evaluation order: index lowering reorders index-side mutation before the base borrow.
VERIFIED REPAIR
Apply the specified transfer or inference rule at this site: if d['base_point']>d['index_point']: errors.append('index-evaluation-order').
Unsuccessful approach: The partial repair uses if d['base_point']>d['index_point']+1: errors.append('index-evaluation-order'), which still violates the stipulated analysis contract.
Case contract
Validate borrow-sensitive desugaring proof facts. For-loop iterator temporary covers loop; question-mark error exit drops body loans; short-circuit right operand is conditionally evaluated; method autoref targets receiver after autoderef; compound assignment evaluates destination once; indexing evaluates base before index; await suspension preserves the borrowed future owner; let-else failure cannot access successful bindings; destructuring assignment stages RHS borrows before writing destinations; return expression lifetime is checked before local cleanup. Input is a fully explicit descriptor of the stated toy IR. Return rule identifiers in declaration order; absent optional obligations use the provided neutral defaults. No rule is an assertion about a production language.
Why this case matters
A finite offline static-analysis model of ownership and borrowing; it does not execute the analyzed program.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
errors=[]
if d['iterator_end']<d['loop_end']: errors.append('for-owner-duration')
if d['error_exit'] and bool(d['body_loans_live']): errors.append('question-error-cleanup')
if d['rhs_evaluated'] and not d['rhs_enabled']: errors.append('short-circuit-conditional')
if d['autoderef_place']!=d['autoref_place']: errors.append('autoref-after-autoderef')
if d['compound_assignment'] and d['destination_evaluations']!=1: errors.append('compound-destination-once')
if False: errors.append('index-evaluation-order')
if d['future_owner_end']<d['await_resume']: errors.append('await-future-owner')
if d['else_branch'] and bool(set(d['success_bindings'])&set(d['else_uses'])): errors.append('let-else-binding-scope')
if d['first_write']<d['rhs_end']: errors.append('destructure-stage-rhs')
if d['return_check']>d['cleanup_point']: errors.append('return-before-cleanup')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'iterator_end': 0, 'loop_end': 0, 'error_exit': False, 'body_loans_live': [], 'rhs_evaluated': False, 'rhs_enabled': True, 'autoderef_place': [], 'autoref_place': [], 'destination_evaluations': 0, 'compound_assignment': False, 'base_point': 0, 'index_point': 0, 'future_owner_end': 0, 'await_resume': 0, 'else_branch': False, 'success_bindings': [], 'else_uses': [], 'rhs_end': 0, 'first_write': 0, 'return_check': 0, 'cleanup_point': 0}
check('well formed empty obligations',solve(base),[])
check('for-owner-duration regression 0', solve(dict(base, **({'iterator_end':N,'loop_end':N+1}))), ['for-owner-duration'])
check('for-owner-duration regression 1', solve(dict(base, **({'iterator_end':N+1,'loop_end':N+2}))), ['for-owner-duration'])
check('question-error-cleanup regression 0', solve(dict(base, **({'error_exit':True,'body_loans_live':['r']}))), ['question-error-cleanup'])
check('question-error-cleanup regression 1', solve(dict(base, **({'error_exit':True,'body_loans_live':[N]}))), ['question-error-cleanup'])
check('short-circuit-conditional regression 0', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False}))), ['short-circuit-conditional'])
check('short-circuit-conditional regression 1', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False,'loop_end':N,'iterator_end':N}))), ['short-circuit-conditional'])
check('autoref-after-autoderef regression 0', solve(dict(base, **({'autoderef_place':['r','*'],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('autoref-after-autoderef regression 1', solve(dict(base, **({'autoderef_place':['r','*',N],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('compound-destination-once regression 0', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':2}))), ['compound-destination-once'])
check('compound-destination-once regression 1', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':N+2}))), ['compound-destination-once'])
check('index-evaluation-order regression 0', solve(dict(base, **({'base_point':N+1,'index_point':N}))), ['index-evaluation-order'])
check('index-evaluation-order regression 1', solve(dict(base, **({'base_point':N+2,'index_point':N+1}))), ['index-evaluation-order'])
check('await-future-owner regression 0', solve(dict(base, **({'future_owner_end':N,'await_resume':N+1}))), ['await-future-owner'])
check('await-future-owner regression 1', solve(dict(base, **({'future_owner_end':N+1,'await_resume':N+2}))), ['await-future-owner'])
check('let-else-binding-scope regression 0', solve(dict(base, **({'else_branch':True,'success_bindings':['x'],'else_uses':['x']}))), ['let-else-binding-scope'])
check('let-else-binding-scope regression 1', solve(dict(base, **({'else_branch':True,'success_bindings':[N],'else_uses':[N]}))), ['let-else-binding-scope'])
check('destructure-stage-rhs regression 0', solve(dict(base, **({'first_write':N,'rhs_end':N+1}))), ['destructure-stage-rhs'])
check('destructure-stage-rhs regression 1', solve(dict(base, **({'first_write':N+1,'rhs_end':N+2}))), ['destructure-stage-rhs'])
check('return-before-cleanup regression 0', solve(dict(base, **({'return_check':N+1,'cleanup_point':N}))), ['return-before-cleanup'])
check('return-before-cleanup regression 1', solve(dict(base, **({'return_check':N+2,'cleanup_point':N+1}))), ['return-before-cleanup'])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| well formed empty obligations | [] | [] | Passed |
| for-owner-duration regression 0 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| for-owner-duration regression 1 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| question-error-cleanup regression 0 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| question-error-cleanup regression 1 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| short-circuit-conditional regression 0 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| short-circuit-conditional regression 1 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| autoref-after-autoderef regression 0 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| autoref-after-autoderef regression 1 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| compound-destination-once regression 0 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| compound-destination-once regression 1 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| index-evaluation-order regression 0 | [] | ['index-evaluation-order'] | Failed |
| index-evaluation-order regression 1 | [] | ['index-evaluation-order'] | Failed |
| await-future-owner regression 0 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| await-future-owner regression 1 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| let-else-binding-scope regression 0 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| let-else-binding-scope regression 1 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| destructure-stage-rhs regression 0 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| destructure-stage-rhs regression 1 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| return-before-cleanup regression 0 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
| return-before-cleanup regression 1 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
SHA-256 / 97701397df1f9cf1653f7771bde9c12f659a9803953f978865c073490b295d8c
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
errors=[]
if d['iterator_end']<d['loop_end']: errors.append('for-owner-duration')
if d['error_exit'] and bool(d['body_loans_live']): errors.append('question-error-cleanup')
if d['rhs_evaluated'] and not d['rhs_enabled']: errors.append('short-circuit-conditional')
if d['autoderef_place']!=d['autoref_place']: errors.append('autoref-after-autoderef')
if d['compound_assignment'] and d['destination_evaluations']!=1: errors.append('compound-destination-once')
if d['base_point']>d['index_point']+1: errors.append('index-evaluation-order')
if d['future_owner_end']<d['await_resume']: errors.append('await-future-owner')
if d['else_branch'] and bool(set(d['success_bindings'])&set(d['else_uses'])): errors.append('let-else-binding-scope')
if d['first_write']<d['rhs_end']: errors.append('destructure-stage-rhs')
if d['return_check']>d['cleanup_point']: errors.append('return-before-cleanup')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'iterator_end': 0, 'loop_end': 0, 'error_exit': False, 'body_loans_live': [], 'rhs_evaluated': False, 'rhs_enabled': True, 'autoderef_place': [], 'autoref_place': [], 'destination_evaluations': 0, 'compound_assignment': False, 'base_point': 0, 'index_point': 0, 'future_owner_end': 0, 'await_resume': 0, 'else_branch': False, 'success_bindings': [], 'else_uses': [], 'rhs_end': 0, 'first_write': 0, 'return_check': 0, 'cleanup_point': 0}
check('well formed empty obligations',solve(base),[])
check('for-owner-duration regression 0', solve(dict(base, **({'iterator_end':N,'loop_end':N+1}))), ['for-owner-duration'])
check('for-owner-duration regression 1', solve(dict(base, **({'iterator_end':N+1,'loop_end':N+2}))), ['for-owner-duration'])
check('question-error-cleanup regression 0', solve(dict(base, **({'error_exit':True,'body_loans_live':['r']}))), ['question-error-cleanup'])
check('question-error-cleanup regression 1', solve(dict(base, **({'error_exit':True,'body_loans_live':[N]}))), ['question-error-cleanup'])
check('short-circuit-conditional regression 0', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False}))), ['short-circuit-conditional'])
check('short-circuit-conditional regression 1', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False,'loop_end':N,'iterator_end':N}))), ['short-circuit-conditional'])
check('autoref-after-autoderef regression 0', solve(dict(base, **({'autoderef_place':['r','*'],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('autoref-after-autoderef regression 1', solve(dict(base, **({'autoderef_place':['r','*',N],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('compound-destination-once regression 0', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':2}))), ['compound-destination-once'])
check('compound-destination-once regression 1', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':N+2}))), ['compound-destination-once'])
check('index-evaluation-order regression 0', solve(dict(base, **({'base_point':N+1,'index_point':N}))), ['index-evaluation-order'])
check('index-evaluation-order regression 1', solve(dict(base, **({'base_point':N+2,'index_point':N+1}))), ['index-evaluation-order'])
check('await-future-owner regression 0', solve(dict(base, **({'future_owner_end':N,'await_resume':N+1}))), ['await-future-owner'])
check('await-future-owner regression 1', solve(dict(base, **({'future_owner_end':N+1,'await_resume':N+2}))), ['await-future-owner'])
check('let-else-binding-scope regression 0', solve(dict(base, **({'else_branch':True,'success_bindings':['x'],'else_uses':['x']}))), ['let-else-binding-scope'])
check('let-else-binding-scope regression 1', solve(dict(base, **({'else_branch':True,'success_bindings':[N],'else_uses':[N]}))), ['let-else-binding-scope'])
check('destructure-stage-rhs regression 0', solve(dict(base, **({'first_write':N,'rhs_end':N+1}))), ['destructure-stage-rhs'])
check('destructure-stage-rhs regression 1', solve(dict(base, **({'first_write':N+1,'rhs_end':N+2}))), ['destructure-stage-rhs'])
check('return-before-cleanup regression 0', solve(dict(base, **({'return_check':N+1,'cleanup_point':N}))), ['return-before-cleanup'])
check('return-before-cleanup regression 1', solve(dict(base, **({'return_check':N+2,'cleanup_point':N+1}))), ['return-before-cleanup'])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| well formed empty obligations | [] | [] | Passed |
| for-owner-duration regression 0 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| for-owner-duration regression 1 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| question-error-cleanup regression 0 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| question-error-cleanup regression 1 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| short-circuit-conditional regression 0 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| short-circuit-conditional regression 1 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| autoref-after-autoderef regression 0 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| autoref-after-autoderef regression 1 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| compound-destination-once regression 0 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| compound-destination-once regression 1 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| index-evaluation-order regression 0 | [] | ['index-evaluation-order'] | Failed |
| index-evaluation-order regression 1 | [] | ['index-evaluation-order'] | Failed |
| await-future-owner regression 0 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| await-future-owner regression 1 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| let-else-binding-scope regression 0 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| let-else-binding-scope regression 1 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| destructure-stage-rhs regression 0 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| destructure-stage-rhs regression 1 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| return-before-cleanup regression 0 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
| return-before-cleanup regression 1 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
SHA-256 / eb275cf2509c370d4a037b411f927084a1b440d8797b75281292668f8f16896e
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
errors=[]
if d['iterator_end']<d['loop_end']: errors.append('for-owner-duration')
if d['error_exit'] and bool(d['body_loans_live']): errors.append('question-error-cleanup')
if d['rhs_evaluated'] and not d['rhs_enabled']: errors.append('short-circuit-conditional')
if d['autoderef_place']!=d['autoref_place']: errors.append('autoref-after-autoderef')
if d['compound_assignment'] and d['destination_evaluations']!=1: errors.append('compound-destination-once')
if d['base_point']>d['index_point']: errors.append('index-evaluation-order')
if d['future_owner_end']<d['await_resume']: errors.append('await-future-owner')
if d['else_branch'] and bool(set(d['success_bindings'])&set(d['else_uses'])): errors.append('let-else-binding-scope')
if d['first_write']<d['rhs_end']: errors.append('destructure-stage-rhs')
if d['return_check']>d['cleanup_point']: errors.append('return-before-cleanup')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'iterator_end': 0, 'loop_end': 0, 'error_exit': False, 'body_loans_live': [], 'rhs_evaluated': False, 'rhs_enabled': True, 'autoderef_place': [], 'autoref_place': [], 'destination_evaluations': 0, 'compound_assignment': False, 'base_point': 0, 'index_point': 0, 'future_owner_end': 0, 'await_resume': 0, 'else_branch': False, 'success_bindings': [], 'else_uses': [], 'rhs_end': 0, 'first_write': 0, 'return_check': 0, 'cleanup_point': 0}
check('well formed empty obligations',solve(base),[])
check('for-owner-duration regression 0', solve(dict(base, **({'iterator_end':N,'loop_end':N+1}))), ['for-owner-duration'])
check('for-owner-duration regression 1', solve(dict(base, **({'iterator_end':N+1,'loop_end':N+2}))), ['for-owner-duration'])
check('question-error-cleanup regression 0', solve(dict(base, **({'error_exit':True,'body_loans_live':['r']}))), ['question-error-cleanup'])
check('question-error-cleanup regression 1', solve(dict(base, **({'error_exit':True,'body_loans_live':[N]}))), ['question-error-cleanup'])
check('short-circuit-conditional regression 0', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False}))), ['short-circuit-conditional'])
check('short-circuit-conditional regression 1', solve(dict(base, **({'rhs_evaluated':True,'rhs_enabled':False,'loop_end':N,'iterator_end':N}))), ['short-circuit-conditional'])
check('autoref-after-autoderef regression 0', solve(dict(base, **({'autoderef_place':['r','*'],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('autoref-after-autoderef regression 1', solve(dict(base, **({'autoderef_place':['r','*',N],'autoref_place':['r']}))), ['autoref-after-autoderef'])
check('compound-destination-once regression 0', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':2}))), ['compound-destination-once'])
check('compound-destination-once regression 1', solve(dict(base, **({'compound_assignment':True,'destination_evaluations':N+2}))), ['compound-destination-once'])
check('index-evaluation-order regression 0', solve(dict(base, **({'base_point':N+1,'index_point':N}))), ['index-evaluation-order'])
check('index-evaluation-order regression 1', solve(dict(base, **({'base_point':N+2,'index_point':N+1}))), ['index-evaluation-order'])
check('await-future-owner regression 0', solve(dict(base, **({'future_owner_end':N,'await_resume':N+1}))), ['await-future-owner'])
check('await-future-owner regression 1', solve(dict(base, **({'future_owner_end':N+1,'await_resume':N+2}))), ['await-future-owner'])
check('let-else-binding-scope regression 0', solve(dict(base, **({'else_branch':True,'success_bindings':['x'],'else_uses':['x']}))), ['let-else-binding-scope'])
check('let-else-binding-scope regression 1', solve(dict(base, **({'else_branch':True,'success_bindings':[N],'else_uses':[N]}))), ['let-else-binding-scope'])
check('destructure-stage-rhs regression 0', solve(dict(base, **({'first_write':N,'rhs_end':N+1}))), ['destructure-stage-rhs'])
check('destructure-stage-rhs regression 1', solve(dict(base, **({'first_write':N+1,'rhs_end':N+2}))), ['destructure-stage-rhs'])
check('return-before-cleanup regression 0', solve(dict(base, **({'return_check':N+1,'cleanup_point':N}))), ['return-before-cleanup'])
check('return-before-cleanup regression 1', solve(dict(base, **({'return_check':N+2,'cleanup_point':N+1}))), ['return-before-cleanup'])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| well formed empty obligations | [] | [] | Passed |
| for-owner-duration regression 0 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| for-owner-duration regression 1 | ['for-owner-duration'] | ['for-owner-duration'] | Passed |
| question-error-cleanup regression 0 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| question-error-cleanup regression 1 | ['question-error-cleanup'] | ['question-error-cleanup'] | Passed |
| short-circuit-conditional regression 0 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| short-circuit-conditional regression 1 | ['short-circuit-conditional'] | ['short-circuit-conditional'] | Passed |
| autoref-after-autoderef regression 0 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| autoref-after-autoderef regression 1 | ['autoref-after-autoderef'] | ['autoref-after-autoderef'] | Passed |
| compound-destination-once regression 0 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| compound-destination-once regression 1 | ['compound-destination-once'] | ['compound-destination-once'] | Passed |
| index-evaluation-order regression 0 | ['index-evaluation-order'] | ['index-evaluation-order'] | Passed |
| index-evaluation-order regression 1 | ['index-evaluation-order'] | ['index-evaluation-order'] | Passed |
| await-future-owner regression 0 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| await-future-owner regression 1 | ['await-future-owner'] | ['await-future-owner'] | Passed |
| let-else-binding-scope regression 0 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| let-else-binding-scope regression 1 | ['let-else-binding-scope'] | ['let-else-binding-scope'] | Passed |
| destructure-stage-rhs regression 0 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| destructure-stage-rhs regression 1 | ['destructure-stage-rhs'] | ['destructure-stage-rhs'] | Passed |
| return-before-cleanup regression 0 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
| return-before-cleanup regression 1 | ['return-before-cleanup'] | ['return-before-cleanup'] | Passed |
SHA-256 / 09dc5fdb4793dc667f959484cdda651ff06eed2eaa40c9d8161085b705f30929
Verification & scope
The explicitly stated toy language is the complete scope; this is not a production compiler or a claim about Rust semantics. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:44:11.073921+00:00.
Case digest / cf6f7a50c6f66b537ced550b1da14ad53bad2f56d07f04d914772a9c611b6f98