FAILURE MAP
← Case archive

FA-44331 / Borrow checking / Open access

Destructuring assignment overwrites an owner before RHS borrow evaluation completes · case 01

Destructuring assignment overwrites an owner before RHS borrow evaluation completes.

Verified by executionVariant 1 · 21 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The static analyzer mishandles destructure stage rhs: destructuring assignment overwrites an owner before rhs borrow evaluation completes.

VERIFIED REPAIR

Apply the specified transfer or inference rule at this site: if d['first_write']<d['rhs_end']: errors.append('destructure-stage-rhs').

Unsuccessful approach: The partial repair uses if d['first_write']+1<d['rhs_end']: errors.append('destructure-stage-rhs'), 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 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 False: 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 fixtureActualExpectedOutcome
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']Failed
destructure-stage-rhs regression 1[]['destructure-stage-rhs']Failed
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 / 4ca401c82bf25646d700d60ab1a3dcaf5512eac04ed3c41b5f04b0ec98570f95

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']: 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']+1<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 fixtureActualExpectedOutcome
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']Failed
destructure-stage-rhs regression 1[]['destructure-stage-rhs']Failed
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 / 0ea2bac7226c44fa110e5b471671d4e9af2d8d15aeb72ee710f7ea33e4f9f246

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 fixtureActualExpectedOutcome
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.158011+00:00.

Case digest / b82141f96e486cd4e6597e07946af9796f2a180af60da9b9aa28f7ef64e60d35