FA-43991 / Borrow checking / Open access
Reference freezing is treated as reversible to exclusive access · case 01
Reference freezing is treated as reversible to exclusive access.
ROOT CAUSE
The static analyzer mishandles freeze direction: reference freezing is treated as reversible to exclusive access.
VERIFIED REPAIR
Apply the specified transfer or inference rule at this site: if d['source_shared'] and d['target_unique']: errors.append('freeze-direction').
Unsuccessful approach: The partial repair uses if d['source_shared'] and d['target_unique'] and d['nested_mut']: errors.append('freeze-direction'), which still violates the stipulated analysis contract.
Case contract
Check reference coercion proof steps. Unique-to-shared freeze is one-way; unsizing preserves owner; trait unsizing retains metadata; array-to-slice length equals array extent; nested mutable references cannot shorten inner lifetime; shared outer references may shorten; deref coercion records every intermediate loan; implicit coercion cannot execute a moving deref; reification of a borrowed function pointer preserves captured lifetimes; never-type branch coercion contributes no invented loan. 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 False: errors.append('freeze-direction')
if d['source_owner']!=d['target_owner']: errors.append('unsize-owner')
if d['unsized'] and not d['metadata']: errors.append('unsize-metadata')
if d['array_coerce'] and d['array_size']!=d['slice_size']: errors.append('array-slice-extent')
if d['nested_mut'] and d['inner_before']!=d['inner_after']: errors.append('nested-mut-invariance')
if d['shared_outer'] and d['outer_after']>d['outer_before']: errors.append('outer-shared-shortening')
if not set(d['intermediate'])<=set(d['recorded']): errors.append('deref-intermediates')
if d['implicit'] and d['moving_deref']: errors.append('implicit-moving-deref')
if not set(d['captured'])<=set(d['reified']): errors.append('function-reification-capture')
if d['never_branch'] and bool(d['invented']): errors.append('never-no-origin')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'source_shared': False, 'target_unique': False, 'source_owner': None, 'target_owner': None, 'unsized': False, 'metadata': True, 'array_size': 0, 'slice_size': 0, 'array_coerce': False, 'nested_mut': False, 'inner_before': 0, 'inner_after': 0, 'shared_outer': False, 'outer_before': 0, 'outer_after': 0, 'intermediate': [], 'recorded': [], 'moving_deref': False, 'implicit': False, 'captured': [], 'reified': [], 'never_branch': False, 'invented': []}
check('well formed empty obligations',solve(base),[])
check('freeze-direction regression 0', solve(dict(base, **({'source_shared':True,'target_unique':True}))), ['freeze-direction'])
check('freeze-direction regression 1', solve(dict(base, **({'source_shared':True,'target_unique':True,'outer_before':N,'outer_after':N}))), ['freeze-direction'])
check('unsize-owner regression 0', solve(dict(base, **({'source_owner':'a','target_owner':'b'}))), ['unsize-owner'])
check('unsize-owner regression 1', solve(dict(base, **({'source_owner':N,'target_owner':N+1}))), ['unsize-owner'])
check('unsize-metadata regression 0', solve(dict(base, **({'unsized':True,'metadata':False}))), ['unsize-metadata'])
check('unsize-metadata regression 1', solve(dict(base, **({'unsized':True,'metadata':False,'outer_before':N,'outer_after':N}))), ['unsize-metadata'])
check('array-slice-extent regression 0', solve(dict(base, **({'array_coerce':True,'array_size':N+1,'slice_size':N}))), ['array-slice-extent'])
check('array-slice-extent regression 1', solve(dict(base, **({'array_coerce':True,'array_size':N+2,'slice_size':N+1}))), ['array-slice-extent'])
check('nested-mut-invariance regression 0', solve(dict(base, **({'nested_mut':True,'inner_before':N+1,'inner_after':N}))), ['nested-mut-invariance'])
check('nested-mut-invariance regression 1', solve(dict(base, **({'nested_mut':True,'inner_before':N+2,'inner_after':N+1}))), ['nested-mut-invariance'])
check('outer-shared-shortening regression 0', solve(dict(base, **({'shared_outer':True,'outer_before':N,'outer_after':N+1}))), ['outer-shared-shortening'])
check('outer-shared-shortening regression 1', solve(dict(base, **({'shared_outer':True,'outer_before':N+1,'outer_after':N+2}))), ['outer-shared-shortening'])
check('deref-intermediates regression 0', solve(dict(base, **({'intermediate':['a','b'],'recorded':['a']}))), ['deref-intermediates'])
check('deref-intermediates regression 1', solve(dict(base, **({'intermediate':list(range(N+1)),'recorded':[0]}))), ['deref-intermediates'])
check('implicit-moving-deref regression 0', solve(dict(base, **({'implicit':True,'moving_deref':True}))), ['implicit-moving-deref'])
check('implicit-moving-deref regression 1', solve(dict(base, **({'implicit':True,'moving_deref':True,'outer_before':N,'outer_after':N}))), ['implicit-moving-deref'])
check('function-reification-capture regression 0', solve(dict(base, **({'captured':['a','b'],'reified':['a']}))), ['function-reification-capture'])
check('function-reification-capture regression 1', solve(dict(base, **({'captured':[N,N+1],'reified':[N]}))), ['function-reification-capture'])
check('never-no-origin regression 0', solve(dict(base, **({'never_branch':True,'invented':['r']}))), ['never-no-origin'])
check('never-no-origin regression 1', solve(dict(base, **({'never_branch':True,'invented':[N]}))), ['never-no-origin'])
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 |
| freeze-direction regression 0 | [] | ['freeze-direction'] | Failed |
| freeze-direction regression 1 | [] | ['freeze-direction'] | Failed |
| unsize-owner regression 0 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-owner regression 1 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-metadata regression 0 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| unsize-metadata regression 1 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| array-slice-extent regression 0 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| array-slice-extent regression 1 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| nested-mut-invariance regression 0 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| nested-mut-invariance regression 1 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| outer-shared-shortening regression 0 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| outer-shared-shortening regression 1 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| deref-intermediates regression 0 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| deref-intermediates regression 1 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| implicit-moving-deref regression 0 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| implicit-moving-deref regression 1 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| function-reification-capture regression 0 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| function-reification-capture regression 1 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| never-no-origin regression 0 | ['never-no-origin'] | ['never-no-origin'] | Passed |
| never-no-origin regression 1 | ['never-no-origin'] | ['never-no-origin'] | Passed |
SHA-256 / c45c01ecec84aeb953ad876ccfd463a6f434082d9e4531e02609801908675b7f
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['source_shared'] and d['target_unique'] and d['nested_mut']: errors.append('freeze-direction')
if d['source_owner']!=d['target_owner']: errors.append('unsize-owner')
if d['unsized'] and not d['metadata']: errors.append('unsize-metadata')
if d['array_coerce'] and d['array_size']!=d['slice_size']: errors.append('array-slice-extent')
if d['nested_mut'] and d['inner_before']!=d['inner_after']: errors.append('nested-mut-invariance')
if d['shared_outer'] and d['outer_after']>d['outer_before']: errors.append('outer-shared-shortening')
if not set(d['intermediate'])<=set(d['recorded']): errors.append('deref-intermediates')
if d['implicit'] and d['moving_deref']: errors.append('implicit-moving-deref')
if not set(d['captured'])<=set(d['reified']): errors.append('function-reification-capture')
if d['never_branch'] and bool(d['invented']): errors.append('never-no-origin')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'source_shared': False, 'target_unique': False, 'source_owner': None, 'target_owner': None, 'unsized': False, 'metadata': True, 'array_size': 0, 'slice_size': 0, 'array_coerce': False, 'nested_mut': False, 'inner_before': 0, 'inner_after': 0, 'shared_outer': False, 'outer_before': 0, 'outer_after': 0, 'intermediate': [], 'recorded': [], 'moving_deref': False, 'implicit': False, 'captured': [], 'reified': [], 'never_branch': False, 'invented': []}
check('well formed empty obligations',solve(base),[])
check('freeze-direction regression 0', solve(dict(base, **({'source_shared':True,'target_unique':True}))), ['freeze-direction'])
check('freeze-direction regression 1', solve(dict(base, **({'source_shared':True,'target_unique':True,'outer_before':N,'outer_after':N}))), ['freeze-direction'])
check('unsize-owner regression 0', solve(dict(base, **({'source_owner':'a','target_owner':'b'}))), ['unsize-owner'])
check('unsize-owner regression 1', solve(dict(base, **({'source_owner':N,'target_owner':N+1}))), ['unsize-owner'])
check('unsize-metadata regression 0', solve(dict(base, **({'unsized':True,'metadata':False}))), ['unsize-metadata'])
check('unsize-metadata regression 1', solve(dict(base, **({'unsized':True,'metadata':False,'outer_before':N,'outer_after':N}))), ['unsize-metadata'])
check('array-slice-extent regression 0', solve(dict(base, **({'array_coerce':True,'array_size':N+1,'slice_size':N}))), ['array-slice-extent'])
check('array-slice-extent regression 1', solve(dict(base, **({'array_coerce':True,'array_size':N+2,'slice_size':N+1}))), ['array-slice-extent'])
check('nested-mut-invariance regression 0', solve(dict(base, **({'nested_mut':True,'inner_before':N+1,'inner_after':N}))), ['nested-mut-invariance'])
check('nested-mut-invariance regression 1', solve(dict(base, **({'nested_mut':True,'inner_before':N+2,'inner_after':N+1}))), ['nested-mut-invariance'])
check('outer-shared-shortening regression 0', solve(dict(base, **({'shared_outer':True,'outer_before':N,'outer_after':N+1}))), ['outer-shared-shortening'])
check('outer-shared-shortening regression 1', solve(dict(base, **({'shared_outer':True,'outer_before':N+1,'outer_after':N+2}))), ['outer-shared-shortening'])
check('deref-intermediates regression 0', solve(dict(base, **({'intermediate':['a','b'],'recorded':['a']}))), ['deref-intermediates'])
check('deref-intermediates regression 1', solve(dict(base, **({'intermediate':list(range(N+1)),'recorded':[0]}))), ['deref-intermediates'])
check('implicit-moving-deref regression 0', solve(dict(base, **({'implicit':True,'moving_deref':True}))), ['implicit-moving-deref'])
check('implicit-moving-deref regression 1', solve(dict(base, **({'implicit':True,'moving_deref':True,'outer_before':N,'outer_after':N}))), ['implicit-moving-deref'])
check('function-reification-capture regression 0', solve(dict(base, **({'captured':['a','b'],'reified':['a']}))), ['function-reification-capture'])
check('function-reification-capture regression 1', solve(dict(base, **({'captured':[N,N+1],'reified':[N]}))), ['function-reification-capture'])
check('never-no-origin regression 0', solve(dict(base, **({'never_branch':True,'invented':['r']}))), ['never-no-origin'])
check('never-no-origin regression 1', solve(dict(base, **({'never_branch':True,'invented':[N]}))), ['never-no-origin'])
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 |
| freeze-direction regression 0 | [] | ['freeze-direction'] | Failed |
| freeze-direction regression 1 | [] | ['freeze-direction'] | Failed |
| unsize-owner regression 0 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-owner regression 1 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-metadata regression 0 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| unsize-metadata regression 1 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| array-slice-extent regression 0 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| array-slice-extent regression 1 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| nested-mut-invariance regression 0 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| nested-mut-invariance regression 1 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| outer-shared-shortening regression 0 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| outer-shared-shortening regression 1 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| deref-intermediates regression 0 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| deref-intermediates regression 1 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| implicit-moving-deref regression 0 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| implicit-moving-deref regression 1 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| function-reification-capture regression 0 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| function-reification-capture regression 1 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| never-no-origin regression 0 | ['never-no-origin'] | ['never-no-origin'] | Passed |
| never-no-origin regression 1 | ['never-no-origin'] | ['never-no-origin'] | Passed |
SHA-256 / cac1a1e3309d88581bf56565f2aa32aacba3ecbcb73a9ca11d41eccc53274ac4
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['source_shared'] and d['target_unique']: errors.append('freeze-direction')
if d['source_owner']!=d['target_owner']: errors.append('unsize-owner')
if d['unsized'] and not d['metadata']: errors.append('unsize-metadata')
if d['array_coerce'] and d['array_size']!=d['slice_size']: errors.append('array-slice-extent')
if d['nested_mut'] and d['inner_before']!=d['inner_after']: errors.append('nested-mut-invariance')
if d['shared_outer'] and d['outer_after']>d['outer_before']: errors.append('outer-shared-shortening')
if not set(d['intermediate'])<=set(d['recorded']): errors.append('deref-intermediates')
if d['implicit'] and d['moving_deref']: errors.append('implicit-moving-deref')
if not set(d['captured'])<=set(d['reified']): errors.append('function-reification-capture')
if d['never_branch'] and bool(d['invented']): errors.append('never-no-origin')
return errors
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'source_shared': False, 'target_unique': False, 'source_owner': None, 'target_owner': None, 'unsized': False, 'metadata': True, 'array_size': 0, 'slice_size': 0, 'array_coerce': False, 'nested_mut': False, 'inner_before': 0, 'inner_after': 0, 'shared_outer': False, 'outer_before': 0, 'outer_after': 0, 'intermediate': [], 'recorded': [], 'moving_deref': False, 'implicit': False, 'captured': [], 'reified': [], 'never_branch': False, 'invented': []}
check('well formed empty obligations',solve(base),[])
check('freeze-direction regression 0', solve(dict(base, **({'source_shared':True,'target_unique':True}))), ['freeze-direction'])
check('freeze-direction regression 1', solve(dict(base, **({'source_shared':True,'target_unique':True,'outer_before':N,'outer_after':N}))), ['freeze-direction'])
check('unsize-owner regression 0', solve(dict(base, **({'source_owner':'a','target_owner':'b'}))), ['unsize-owner'])
check('unsize-owner regression 1', solve(dict(base, **({'source_owner':N,'target_owner':N+1}))), ['unsize-owner'])
check('unsize-metadata regression 0', solve(dict(base, **({'unsized':True,'metadata':False}))), ['unsize-metadata'])
check('unsize-metadata regression 1', solve(dict(base, **({'unsized':True,'metadata':False,'outer_before':N,'outer_after':N}))), ['unsize-metadata'])
check('array-slice-extent regression 0', solve(dict(base, **({'array_coerce':True,'array_size':N+1,'slice_size':N}))), ['array-slice-extent'])
check('array-slice-extent regression 1', solve(dict(base, **({'array_coerce':True,'array_size':N+2,'slice_size':N+1}))), ['array-slice-extent'])
check('nested-mut-invariance regression 0', solve(dict(base, **({'nested_mut':True,'inner_before':N+1,'inner_after':N}))), ['nested-mut-invariance'])
check('nested-mut-invariance regression 1', solve(dict(base, **({'nested_mut':True,'inner_before':N+2,'inner_after':N+1}))), ['nested-mut-invariance'])
check('outer-shared-shortening regression 0', solve(dict(base, **({'shared_outer':True,'outer_before':N,'outer_after':N+1}))), ['outer-shared-shortening'])
check('outer-shared-shortening regression 1', solve(dict(base, **({'shared_outer':True,'outer_before':N+1,'outer_after':N+2}))), ['outer-shared-shortening'])
check('deref-intermediates regression 0', solve(dict(base, **({'intermediate':['a','b'],'recorded':['a']}))), ['deref-intermediates'])
check('deref-intermediates regression 1', solve(dict(base, **({'intermediate':list(range(N+1)),'recorded':[0]}))), ['deref-intermediates'])
check('implicit-moving-deref regression 0', solve(dict(base, **({'implicit':True,'moving_deref':True}))), ['implicit-moving-deref'])
check('implicit-moving-deref regression 1', solve(dict(base, **({'implicit':True,'moving_deref':True,'outer_before':N,'outer_after':N}))), ['implicit-moving-deref'])
check('function-reification-capture regression 0', solve(dict(base, **({'captured':['a','b'],'reified':['a']}))), ['function-reification-capture'])
check('function-reification-capture regression 1', solve(dict(base, **({'captured':[N,N+1],'reified':[N]}))), ['function-reification-capture'])
check('never-no-origin regression 0', solve(dict(base, **({'never_branch':True,'invented':['r']}))), ['never-no-origin'])
check('never-no-origin regression 1', solve(dict(base, **({'never_branch':True,'invented':[N]}))), ['never-no-origin'])
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 |
| freeze-direction regression 0 | ['freeze-direction'] | ['freeze-direction'] | Passed |
| freeze-direction regression 1 | ['freeze-direction'] | ['freeze-direction'] | Passed |
| unsize-owner regression 0 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-owner regression 1 | ['unsize-owner'] | ['unsize-owner'] | Passed |
| unsize-metadata regression 0 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| unsize-metadata regression 1 | ['unsize-metadata'] | ['unsize-metadata'] | Passed |
| array-slice-extent regression 0 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| array-slice-extent regression 1 | ['array-slice-extent'] | ['array-slice-extent'] | Passed |
| nested-mut-invariance regression 0 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| nested-mut-invariance regression 1 | ['nested-mut-invariance'] | ['nested-mut-invariance'] | Passed |
| outer-shared-shortening regression 0 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| outer-shared-shortening regression 1 | ['outer-shared-shortening'] | ['outer-shared-shortening'] | Passed |
| deref-intermediates regression 0 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| deref-intermediates regression 1 | ['deref-intermediates'] | ['deref-intermediates'] | Passed |
| implicit-moving-deref regression 0 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| implicit-moving-deref regression 1 | ['implicit-moving-deref'] | ['implicit-moving-deref'] | Passed |
| function-reification-capture regression 0 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| function-reification-capture regression 1 | ['function-reification-capture'] | ['function-reification-capture'] | Passed |
| never-no-origin regression 0 | ['never-no-origin'] | ['never-no-origin'] | Passed |
| never-no-origin regression 1 | ['never-no-origin'] | ['never-no-origin'] | Passed |
SHA-256 / e5f05aeb93b9ae07ee8dd2d488fd64c0d9538e0b13b3d71a98870b9e863043b1
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:07.625578+00:00.
Case digest / 31a4e91bd680f43d430377441226def65b78cba73383de119077aa27add47810