FAILURE MAP
← Case archive

FA-43361 / Borrow checking / Open access

A unique child only suspends parent access when their use regions are identical · case 01

A unique child only suspends parent access when their use regions are identical.

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

ROOT CAUSE

The static analyzer mishandles parent suspension: a unique child only suspends parent access when their use regions are identical.

VERIFIED REPAIR

Apply the specified transfer or inference rule at this site: if bool(set(d['parent_use'])&set(d['unique_child_use'])): errors.append('parent-suspension').

Unsuccessful approach: The partial repair uses if set(d['parent_use'])==set(d['unique_child_use']) and bool(d['parent_use']): errors.append('parent-suspension'), which still violates the stipulated analysis contract.

Case contract

Check statically resolved reborrow chains. Every child has declared parent; chains acyclic; child lifetime subset of parent; mutable child requires unique parent permission; parent use cannot overlap child unique-use points; child place must descend from parent place; nested child cannot bypass suspended intermediate parent; sibling unique reborrows may not overlap points; ending a child does not end its ancestors; killing a parent kills all descendants. Descriptor supplies inferred facts and requested proof obligations. 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 not set(d['parents'].values())<=set(d['declared']): errors.append('parent-resolution')
    if any(len(x)>0 for x in d['cycles']): errors.append('lineage-cycle')
    if not set(d['child_points'])<=set(d['parent_points']): errors.append('child-region')
    if d['child_mut'] and not d['parent_unique']: errors.append('permission-inheritance')
    if False: errors.append('parent-suspension')
    if d['child_place'][:len(d['parent_place'])]!=d['parent_place']: errors.append('place-descent')
    if bool(set(d['bypassed'])&set(d['suspended'])): errors.append('intermediate-suspension')
    if bool(set(d['sibling_a'])&set(d['sibling_b'])): errors.append('sibling-regions')
    if d['ended_child'] and bool(d['ended_ancestors']): errors.append('child-end-locality')
    if d['killed_parent'] and bool(d['surviving_descendants']): errors.append('parent-kill-cascade')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'parents': {}, 'declared': [], 'cycles': [], 'child_points': [], 'parent_points': [], 'child_mut': False, 'parent_unique': True, 'parent_use': [], 'unique_child_use': [], 'child_place': [], 'parent_place': [], 'bypassed': [], 'suspended': [], 'sibling_a': [], 'sibling_b': [], 'ended_child': False, 'ended_ancestors': [], 'killed_parent': False, 'surviving_descendants': []}
check('well formed empty obligations',solve(base),[])
check('parent-resolution regression 0', solve(dict(base, **({'parents':{'c':'p','d':'q'},'declared':['p']}))), ['parent-resolution'])
check('parent-resolution regression 1', solve(dict(base, **({'parents':{N:'p',N+1:'q'},'declared':['p']}))), ['parent-resolution'])
check('lineage-cycle regression 0', solve(dict(base, **({'cycles':[['a','b']]}))), ['lineage-cycle'])
check('lineage-cycle regression 1', solve(dict(base, **({'cycles':[[N]]}))), ['lineage-cycle'])
check('child-region regression 0', solve(dict(base, **({'child_points':[N],'parent_points':[N+1]}))), ['child-region'])
check('child-region regression 1', solve(dict(base, **({'child_points':[N,N+1],'parent_points':[N+1,N+2]}))), ['child-region'])
check('permission-inheritance regression 0', solve(dict(base, **({'child_mut':True,'parent_unique':False}))), ['permission-inheritance'])
check('permission-inheritance regression 1', solve(dict(base, **({'child_mut':True,'parent_unique':False,'parent_points':list(range(N))}))), ['permission-inheritance'])
check('parent-suspension regression 0', solve(dict(base, **({'parent_use':[N,N+1],'unique_child_use':[N]}))), ['parent-suspension'])
check('parent-suspension regression 1', solve(dict(base, **({'parent_use':[N],'unique_child_use':[N,N+1]}))), ['parent-suspension'])
check('place-descent regression 0', solve(dict(base, **({'child_place':['r','b'],'parent_place':['r','a']}))), ['place-descent'])
check('place-descent regression 1', solve(dict(base, **({'child_place':['r',N+1],'parent_place':['r',N]}))), ['place-descent'])
check('intermediate-suspension regression 0', solve(dict(base, **({'bypassed':['p'],'suspended':['p']}))), ['intermediate-suspension'])
check('intermediate-suspension regression 1', solve(dict(base, **({'bypassed':[N],'suspended':[N]}))), ['intermediate-suspension'])
check('sibling-regions regression 0', solve(dict(base, **({'sibling_a':[N,N+1],'sibling_b':[N+1]}))), ['sibling-regions'])
check('sibling-regions regression 1', solve(dict(base, **({'sibling_a':[N],'sibling_b':[N,N+1]}))), ['sibling-regions'])
check('child-end-locality regression 0', solve(dict(base, **({'ended_child':True,'ended_ancestors':['p']}))), ['child-end-locality'])
check('child-end-locality regression 1', solve(dict(base, **({'ended_child':True,'ended_ancestors':[N]}))), ['child-end-locality'])
check('parent-kill-cascade regression 0', solve(dict(base, **({'killed_parent':True,'surviving_descendants':['c']}))), ['parent-kill-cascade'])
check('parent-kill-cascade regression 1', solve(dict(base, **({'killed_parent':True,'surviving_descendants':[N]}))), ['parent-kill-cascade'])
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
parent-resolution regression 0['parent-resolution']['parent-resolution']Passed
parent-resolution regression 1['parent-resolution']['parent-resolution']Passed
lineage-cycle regression 0['lineage-cycle']['lineage-cycle']Passed
lineage-cycle regression 1['lineage-cycle']['lineage-cycle']Passed
child-region regression 0['child-region']['child-region']Passed
child-region regression 1['child-region']['child-region']Passed
permission-inheritance regression 0['permission-inheritance']['permission-inheritance']Passed
permission-inheritance regression 1['permission-inheritance']['permission-inheritance']Passed
parent-suspension regression 0[]['parent-suspension']Failed
parent-suspension regression 1[]['parent-suspension']Failed
place-descent regression 0['place-descent']['place-descent']Passed
place-descent regression 1['place-descent']['place-descent']Passed
intermediate-suspension regression 0['intermediate-suspension']['intermediate-suspension']Passed
intermediate-suspension regression 1['intermediate-suspension']['intermediate-suspension']Passed
sibling-regions regression 0['sibling-regions']['sibling-regions']Passed
sibling-regions regression 1['sibling-regions']['sibling-regions']Passed
child-end-locality regression 0['child-end-locality']['child-end-locality']Passed
child-end-locality regression 1['child-end-locality']['child-end-locality']Passed
parent-kill-cascade regression 0['parent-kill-cascade']['parent-kill-cascade']Passed
parent-kill-cascade regression 1['parent-kill-cascade']['parent-kill-cascade']Passed

SHA-256 / d596ff47d43938ae1bd9a5030980fe49c9445c14cbc1b734a6381247f229e6c4

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    errors=[]
    if not set(d['parents'].values())<=set(d['declared']): errors.append('parent-resolution')
    if any(len(x)>0 for x in d['cycles']): errors.append('lineage-cycle')
    if not set(d['child_points'])<=set(d['parent_points']): errors.append('child-region')
    if d['child_mut'] and not d['parent_unique']: errors.append('permission-inheritance')
    if set(d['parent_use'])==set(d['unique_child_use']) and bool(d['parent_use']): errors.append('parent-suspension')
    if d['child_place'][:len(d['parent_place'])]!=d['parent_place']: errors.append('place-descent')
    if bool(set(d['bypassed'])&set(d['suspended'])): errors.append('intermediate-suspension')
    if bool(set(d['sibling_a'])&set(d['sibling_b'])): errors.append('sibling-regions')
    if d['ended_child'] and bool(d['ended_ancestors']): errors.append('child-end-locality')
    if d['killed_parent'] and bool(d['surviving_descendants']): errors.append('parent-kill-cascade')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'parents': {}, 'declared': [], 'cycles': [], 'child_points': [], 'parent_points': [], 'child_mut': False, 'parent_unique': True, 'parent_use': [], 'unique_child_use': [], 'child_place': [], 'parent_place': [], 'bypassed': [], 'suspended': [], 'sibling_a': [], 'sibling_b': [], 'ended_child': False, 'ended_ancestors': [], 'killed_parent': False, 'surviving_descendants': []}
check('well formed empty obligations',solve(base),[])
check('parent-resolution regression 0', solve(dict(base, **({'parents':{'c':'p','d':'q'},'declared':['p']}))), ['parent-resolution'])
check('parent-resolution regression 1', solve(dict(base, **({'parents':{N:'p',N+1:'q'},'declared':['p']}))), ['parent-resolution'])
check('lineage-cycle regression 0', solve(dict(base, **({'cycles':[['a','b']]}))), ['lineage-cycle'])
check('lineage-cycle regression 1', solve(dict(base, **({'cycles':[[N]]}))), ['lineage-cycle'])
check('child-region regression 0', solve(dict(base, **({'child_points':[N],'parent_points':[N+1]}))), ['child-region'])
check('child-region regression 1', solve(dict(base, **({'child_points':[N,N+1],'parent_points':[N+1,N+2]}))), ['child-region'])
check('permission-inheritance regression 0', solve(dict(base, **({'child_mut':True,'parent_unique':False}))), ['permission-inheritance'])
check('permission-inheritance regression 1', solve(dict(base, **({'child_mut':True,'parent_unique':False,'parent_points':list(range(N))}))), ['permission-inheritance'])
check('parent-suspension regression 0', solve(dict(base, **({'parent_use':[N,N+1],'unique_child_use':[N]}))), ['parent-suspension'])
check('parent-suspension regression 1', solve(dict(base, **({'parent_use':[N],'unique_child_use':[N,N+1]}))), ['parent-suspension'])
check('place-descent regression 0', solve(dict(base, **({'child_place':['r','b'],'parent_place':['r','a']}))), ['place-descent'])
check('place-descent regression 1', solve(dict(base, **({'child_place':['r',N+1],'parent_place':['r',N]}))), ['place-descent'])
check('intermediate-suspension regression 0', solve(dict(base, **({'bypassed':['p'],'suspended':['p']}))), ['intermediate-suspension'])
check('intermediate-suspension regression 1', solve(dict(base, **({'bypassed':[N],'suspended':[N]}))), ['intermediate-suspension'])
check('sibling-regions regression 0', solve(dict(base, **({'sibling_a':[N,N+1],'sibling_b':[N+1]}))), ['sibling-regions'])
check('sibling-regions regression 1', solve(dict(base, **({'sibling_a':[N],'sibling_b':[N,N+1]}))), ['sibling-regions'])
check('child-end-locality regression 0', solve(dict(base, **({'ended_child':True,'ended_ancestors':['p']}))), ['child-end-locality'])
check('child-end-locality regression 1', solve(dict(base, **({'ended_child':True,'ended_ancestors':[N]}))), ['child-end-locality'])
check('parent-kill-cascade regression 0', solve(dict(base, **({'killed_parent':True,'surviving_descendants':['c']}))), ['parent-kill-cascade'])
check('parent-kill-cascade regression 1', solve(dict(base, **({'killed_parent':True,'surviving_descendants':[N]}))), ['parent-kill-cascade'])
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
parent-resolution regression 0['parent-resolution']['parent-resolution']Passed
parent-resolution regression 1['parent-resolution']['parent-resolution']Passed
lineage-cycle regression 0['lineage-cycle']['lineage-cycle']Passed
lineage-cycle regression 1['lineage-cycle']['lineage-cycle']Passed
child-region regression 0['child-region']['child-region']Passed
child-region regression 1['child-region']['child-region']Passed
permission-inheritance regression 0['permission-inheritance']['permission-inheritance']Passed
permission-inheritance regression 1['permission-inheritance']['permission-inheritance']Passed
parent-suspension regression 0[]['parent-suspension']Failed
parent-suspension regression 1[]['parent-suspension']Failed
place-descent regression 0['place-descent']['place-descent']Passed
place-descent regression 1['place-descent']['place-descent']Passed
intermediate-suspension regression 0['intermediate-suspension']['intermediate-suspension']Passed
intermediate-suspension regression 1['intermediate-suspension']['intermediate-suspension']Passed
sibling-regions regression 0['sibling-regions']['sibling-regions']Passed
sibling-regions regression 1['sibling-regions']['sibling-regions']Passed
child-end-locality regression 0['child-end-locality']['child-end-locality']Passed
child-end-locality regression 1['child-end-locality']['child-end-locality']Passed
parent-kill-cascade regression 0['parent-kill-cascade']['parent-kill-cascade']Passed
parent-kill-cascade regression 1['parent-kill-cascade']['parent-kill-cascade']Passed

SHA-256 / e07d3c8add33294fe54f50b30b51892fc3220b37a7495369c1795c5e0a0af986

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    errors=[]
    if not set(d['parents'].values())<=set(d['declared']): errors.append('parent-resolution')
    if any(len(x)>0 for x in d['cycles']): errors.append('lineage-cycle')
    if not set(d['child_points'])<=set(d['parent_points']): errors.append('child-region')
    if d['child_mut'] and not d['parent_unique']: errors.append('permission-inheritance')
    if bool(set(d['parent_use'])&set(d['unique_child_use'])): errors.append('parent-suspension')
    if d['child_place'][:len(d['parent_place'])]!=d['parent_place']: errors.append('place-descent')
    if bool(set(d['bypassed'])&set(d['suspended'])): errors.append('intermediate-suspension')
    if bool(set(d['sibling_a'])&set(d['sibling_b'])): errors.append('sibling-regions')
    if d['ended_child'] and bool(d['ended_ancestors']): errors.append('child-end-locality')
    if d['killed_parent'] and bool(d['surviving_descendants']): errors.append('parent-kill-cascade')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'parents': {}, 'declared': [], 'cycles': [], 'child_points': [], 'parent_points': [], 'child_mut': False, 'parent_unique': True, 'parent_use': [], 'unique_child_use': [], 'child_place': [], 'parent_place': [], 'bypassed': [], 'suspended': [], 'sibling_a': [], 'sibling_b': [], 'ended_child': False, 'ended_ancestors': [], 'killed_parent': False, 'surviving_descendants': []}
check('well formed empty obligations',solve(base),[])
check('parent-resolution regression 0', solve(dict(base, **({'parents':{'c':'p','d':'q'},'declared':['p']}))), ['parent-resolution'])
check('parent-resolution regression 1', solve(dict(base, **({'parents':{N:'p',N+1:'q'},'declared':['p']}))), ['parent-resolution'])
check('lineage-cycle regression 0', solve(dict(base, **({'cycles':[['a','b']]}))), ['lineage-cycle'])
check('lineage-cycle regression 1', solve(dict(base, **({'cycles':[[N]]}))), ['lineage-cycle'])
check('child-region regression 0', solve(dict(base, **({'child_points':[N],'parent_points':[N+1]}))), ['child-region'])
check('child-region regression 1', solve(dict(base, **({'child_points':[N,N+1],'parent_points':[N+1,N+2]}))), ['child-region'])
check('permission-inheritance regression 0', solve(dict(base, **({'child_mut':True,'parent_unique':False}))), ['permission-inheritance'])
check('permission-inheritance regression 1', solve(dict(base, **({'child_mut':True,'parent_unique':False,'parent_points':list(range(N))}))), ['permission-inheritance'])
check('parent-suspension regression 0', solve(dict(base, **({'parent_use':[N,N+1],'unique_child_use':[N]}))), ['parent-suspension'])
check('parent-suspension regression 1', solve(dict(base, **({'parent_use':[N],'unique_child_use':[N,N+1]}))), ['parent-suspension'])
check('place-descent regression 0', solve(dict(base, **({'child_place':['r','b'],'parent_place':['r','a']}))), ['place-descent'])
check('place-descent regression 1', solve(dict(base, **({'child_place':['r',N+1],'parent_place':['r',N]}))), ['place-descent'])
check('intermediate-suspension regression 0', solve(dict(base, **({'bypassed':['p'],'suspended':['p']}))), ['intermediate-suspension'])
check('intermediate-suspension regression 1', solve(dict(base, **({'bypassed':[N],'suspended':[N]}))), ['intermediate-suspension'])
check('sibling-regions regression 0', solve(dict(base, **({'sibling_a':[N,N+1],'sibling_b':[N+1]}))), ['sibling-regions'])
check('sibling-regions regression 1', solve(dict(base, **({'sibling_a':[N],'sibling_b':[N,N+1]}))), ['sibling-regions'])
check('child-end-locality regression 0', solve(dict(base, **({'ended_child':True,'ended_ancestors':['p']}))), ['child-end-locality'])
check('child-end-locality regression 1', solve(dict(base, **({'ended_child':True,'ended_ancestors':[N]}))), ['child-end-locality'])
check('parent-kill-cascade regression 0', solve(dict(base, **({'killed_parent':True,'surviving_descendants':['c']}))), ['parent-kill-cascade'])
check('parent-kill-cascade regression 1', solve(dict(base, **({'killed_parent':True,'surviving_descendants':[N]}))), ['parent-kill-cascade'])
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
parent-resolution regression 0['parent-resolution']['parent-resolution']Passed
parent-resolution regression 1['parent-resolution']['parent-resolution']Passed
lineage-cycle regression 0['lineage-cycle']['lineage-cycle']Passed
lineage-cycle regression 1['lineage-cycle']['lineage-cycle']Passed
child-region regression 0['child-region']['child-region']Passed
child-region regression 1['child-region']['child-region']Passed
permission-inheritance regression 0['permission-inheritance']['permission-inheritance']Passed
permission-inheritance regression 1['permission-inheritance']['permission-inheritance']Passed
parent-suspension regression 0['parent-suspension']['parent-suspension']Passed
parent-suspension regression 1['parent-suspension']['parent-suspension']Passed
place-descent regression 0['place-descent']['place-descent']Passed
place-descent regression 1['place-descent']['place-descent']Passed
intermediate-suspension regression 0['intermediate-suspension']['intermediate-suspension']Passed
intermediate-suspension regression 1['intermediate-suspension']['intermediate-suspension']Passed
sibling-regions regression 0['sibling-regions']['sibling-regions']Passed
sibling-regions regression 1['sibling-regions']['sibling-regions']Passed
child-end-locality regression 0['child-end-locality']['child-end-locality']Passed
child-end-locality regression 1['child-end-locality']['child-end-locality']Passed
parent-kill-cascade regression 0['parent-kill-cascade']['parent-kill-cascade']Passed
parent-kill-cascade regression 1['parent-kill-cascade']['parent-kill-cascade']Passed

SHA-256 / 0e28c7c793074932f23803aceac0fbce281d703db2f73f0119b2c61297bab062

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

Case digest / 4d9dcc538d9fe69ec7978bd68960db24705183659029ab4ba69a969e0eaf4a93