FAILURE MAP
← Case archive

FA-44016 / Borrow checking / Open access

Shared-reference coercion extends the outer borrow lifetime · case 01

Shared-reference coercion extends the outer borrow lifetime.

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

ROOT CAUSE

The static analyzer mishandles outer shared shortening: shared-reference coercion extends the outer borrow lifetime.

VERIFIED REPAIR

Apply the specified transfer or inference rule at this site: if d['shared_outer'] and d['outer_after']>d['outer_before']: errors.append('outer-shared-shortening').

Unsuccessful approach: The partial repair uses if d['shared_outer'] and d['outer_after']>d['outer_before']+1: errors.append('outer-shared-shortening'), 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 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 False: 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 fixtureActualExpectedOutcome
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']Failed
outer-shared-shortening regression 1[]['outer-shared-shortening']Failed
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 / 3d8454e3e0af6fa552a9d68e12979afed600cd40bd0008c6114971d43bcf317e

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']: 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']+1: 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 fixtureActualExpectedOutcome
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']Failed
outer-shared-shortening regression 1[]['outer-shared-shortening']Failed
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 / 3c46c3ebaec1dd0fc75f131c93c6ff26806ebbb4d3d0cacbc3aae53edc1cadc5

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

Case digest / 6418e42d991f45173223bac4b499429e763763fdf2d6a7b81199f30836f032b1