FAILURE MAP
← Case archive

FA-44211 / Borrow checking / Open access

Lifetime substitution rewrites the distinguished static lifetime · case 01

Lifetime substitution rewrites the distinguished static lifetime.

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

ROOT CAUSE

The static analyzer mishandles static preservation: lifetime substitution rewrites the distinguished static lifetime.

VERIFIED REPAIR

Apply the specified transfer or inference rule at this site: if d['static_before']!=d['static_after']: errors.append('static-preservation').

Unsuccessful approach: The partial repair uses if d['static_before'] is not None and d['static_after'] is None: errors.append('static-preservation'), which still violates the stipulated analysis contract.

Case contract

Check generic borrow-summary instantiation. Generic lifetime arguments match parameter arity; parameter substitution is positional; repeated occurrences substitute consistently; recursive instantiation uses each callee actual mapping; static lifetime is not substituted; inferred anonymous lifetimes are fresh per call; where-outlives obligations instantiated in declared direction; associated lifetime applications include all type arguments; recursive summary fixed point cannot be accepted while new obligations remain; monomorphized reference types retain lifetime proof metadata. 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 len(d['params'])!=len(d['args']): errors.append('lifetime-arity')
    if d['expected_mapping']!=d['actual_mapping']: errors.append('positional-substitution')
    if any(len(set(xs))>1 for xs in d['occurrences'].values()): errors.append('repeated-substitution')
    if d['recursive_expected']!=d['recursive_actual']: errors.append('recursive-actual-map')
    if False: errors.append('static-preservation')
    if len(d['anonymous_calls'])==len(d['anonymous_ids']) and len(set(d['anonymous_ids']))!=len(d['anonymous_ids']): errors.append('anonymous-freshness')
    if set(map(tuple,d['expected_outlives']))!=set(map(tuple,d['actual_outlives'])): errors.append('where-direction')
    if d['associated_args']!=d['recorded_args']: errors.append('associated-arguments')
    if d['accepted'] and bool(d['pending']): errors.append('summary-fixed-point')
    if not set(d['reference_types'])<=set(d['proof_metadata']): errors.append('erased-proof-metadata')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': [], 'args': [], 'expected_mapping': {}, 'actual_mapping': {}, 'occurrences': {}, 'recursive_expected': {}, 'recursive_actual': {}, 'static_before': None, 'static_after': None, 'anonymous_calls': [], 'anonymous_ids': [], 'expected_outlives': [], 'actual_outlives': [], 'associated_args': [], 'recorded_args': [], 'pending': [], 'accepted': False, 'reference_types': [], 'proof_metadata': []}
check('well formed empty obligations',solve(base),[])
check('lifetime-arity regression 0', solve(dict(base, **({'params':['a'],'args':['x','y']}))), ['lifetime-arity'])
check('lifetime-arity regression 1', solve(dict(base, **({'params':[N],'args':[N,N+1]}))), ['lifetime-arity'])
check('positional-substitution regression 0', solve(dict(base, **({'expected_mapping':{'a':'x','b':'y'},'actual_mapping':{'a':'y','b':'x'}}))), ['positional-substitution'])
check('positional-substitution regression 1', solve(dict(base, **({'expected_mapping':{'a':N,'b':N+1},'actual_mapping':{'a':N+1,'b':N}}))), ['positional-substitution'])
check('repeated-substitution regression 0', solve(dict(base, **({'occurrences':{'a':['x','y']}}))), ['repeated-substitution'])
check('repeated-substitution regression 1', solve(dict(base, **({'occurrences':{'a':[N,N+1]}}))), ['repeated-substitution'])
check('recursive-actual-map regression 0', solve(dict(base, **({'recursive_expected':{'call':'b'},'recursive_actual':{'call':'a'}}))), ['recursive-actual-map'])
check('recursive-actual-map regression 1', solve(dict(base, **({'recursive_expected':{'call':N+1},'recursive_actual':{'call':N}}))), ['recursive-actual-map'])
check('static-preservation regression 0', solve(dict(base, **({'static_before':'static','static_after':'a'}))), ['static-preservation'])
check('static-preservation regression 1', solve(dict(base, **({'static_before':'static','static_after':N}))), ['static-preservation'])
check('anonymous-freshness regression 0', solve(dict(base, **({'anonymous_calls':['c1','c2'],'anonymous_ids':['r','r']}))), ['anonymous-freshness'])
check('anonymous-freshness regression 1', solve(dict(base, **({'anonymous_calls':[N,N+1],'anonymous_ids':[0,0]}))), ['anonymous-freshness'])
check('where-direction regression 0', solve(dict(base, **({'expected_outlives':[('a','b')],'actual_outlives':[('b','a')]}))), ['where-direction'])
check('where-direction regression 1', solve(dict(base, **({'expected_outlives':[(N,N+1)],'actual_outlives':[(N+1,N)]}))), ['where-direction'])
check('associated-arguments regression 0', solve(dict(base, **({'associated_args':['a','b'],'recorded_args':['b','a']}))), ['associated-arguments'])
check('associated-arguments regression 1', solve(dict(base, **({'associated_args':[N,N+1],'recorded_args':[N+1,N]}))), ['associated-arguments'])
check('summary-fixed-point regression 0', solve(dict(base, **({'accepted':True,'pending':['a']}))), ['summary-fixed-point'])
check('summary-fixed-point regression 1', solve(dict(base, **({'accepted':True,'pending':[N]}))), ['summary-fixed-point'])
check('erased-proof-metadata regression 0', solve(dict(base, **({'reference_types':['a','b'],'proof_metadata':['a']}))), ['erased-proof-metadata'])
check('erased-proof-metadata regression 1', solve(dict(base, **({'reference_types':[N,N+1],'proof_metadata':[N]}))), ['erased-proof-metadata'])
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
lifetime-arity regression 0['lifetime-arity']['lifetime-arity']Passed
lifetime-arity regression 1['lifetime-arity']['lifetime-arity']Passed
positional-substitution regression 0['positional-substitution']['positional-substitution']Passed
positional-substitution regression 1['positional-substitution']['positional-substitution']Passed
repeated-substitution regression 0['repeated-substitution']['repeated-substitution']Passed
repeated-substitution regression 1['repeated-substitution']['repeated-substitution']Passed
recursive-actual-map regression 0['recursive-actual-map']['recursive-actual-map']Passed
recursive-actual-map regression 1['recursive-actual-map']['recursive-actual-map']Passed
static-preservation regression 0[]['static-preservation']Failed
static-preservation regression 1[]['static-preservation']Failed
anonymous-freshness regression 0['anonymous-freshness']['anonymous-freshness']Passed
anonymous-freshness regression 1['anonymous-freshness']['anonymous-freshness']Passed
where-direction regression 0['where-direction']['where-direction']Passed
where-direction regression 1['where-direction']['where-direction']Passed
associated-arguments regression 0['associated-arguments']['associated-arguments']Passed
associated-arguments regression 1['associated-arguments']['associated-arguments']Passed
summary-fixed-point regression 0['summary-fixed-point']['summary-fixed-point']Passed
summary-fixed-point regression 1['summary-fixed-point']['summary-fixed-point']Passed
erased-proof-metadata regression 0['erased-proof-metadata']['erased-proof-metadata']Passed
erased-proof-metadata regression 1['erased-proof-metadata']['erased-proof-metadata']Passed

SHA-256 / 36f2cd3a6541b5ddc23dd1839f25ac03bcb6551f8f702ad4aa7e6ef505fc4317

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(d):
    errors=[]
    if len(d['params'])!=len(d['args']): errors.append('lifetime-arity')
    if d['expected_mapping']!=d['actual_mapping']: errors.append('positional-substitution')
    if any(len(set(xs))>1 for xs in d['occurrences'].values()): errors.append('repeated-substitution')
    if d['recursive_expected']!=d['recursive_actual']: errors.append('recursive-actual-map')
    if d['static_before'] is not None and d['static_after'] is None: errors.append('static-preservation')
    if len(d['anonymous_calls'])==len(d['anonymous_ids']) and len(set(d['anonymous_ids']))!=len(d['anonymous_ids']): errors.append('anonymous-freshness')
    if set(map(tuple,d['expected_outlives']))!=set(map(tuple,d['actual_outlives'])): errors.append('where-direction')
    if d['associated_args']!=d['recorded_args']: errors.append('associated-arguments')
    if d['accepted'] and bool(d['pending']): errors.append('summary-fixed-point')
    if not set(d['reference_types'])<=set(d['proof_metadata']): errors.append('erased-proof-metadata')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': [], 'args': [], 'expected_mapping': {}, 'actual_mapping': {}, 'occurrences': {}, 'recursive_expected': {}, 'recursive_actual': {}, 'static_before': None, 'static_after': None, 'anonymous_calls': [], 'anonymous_ids': [], 'expected_outlives': [], 'actual_outlives': [], 'associated_args': [], 'recorded_args': [], 'pending': [], 'accepted': False, 'reference_types': [], 'proof_metadata': []}
check('well formed empty obligations',solve(base),[])
check('lifetime-arity regression 0', solve(dict(base, **({'params':['a'],'args':['x','y']}))), ['lifetime-arity'])
check('lifetime-arity regression 1', solve(dict(base, **({'params':[N],'args':[N,N+1]}))), ['lifetime-arity'])
check('positional-substitution regression 0', solve(dict(base, **({'expected_mapping':{'a':'x','b':'y'},'actual_mapping':{'a':'y','b':'x'}}))), ['positional-substitution'])
check('positional-substitution regression 1', solve(dict(base, **({'expected_mapping':{'a':N,'b':N+1},'actual_mapping':{'a':N+1,'b':N}}))), ['positional-substitution'])
check('repeated-substitution regression 0', solve(dict(base, **({'occurrences':{'a':['x','y']}}))), ['repeated-substitution'])
check('repeated-substitution regression 1', solve(dict(base, **({'occurrences':{'a':[N,N+1]}}))), ['repeated-substitution'])
check('recursive-actual-map regression 0', solve(dict(base, **({'recursive_expected':{'call':'b'},'recursive_actual':{'call':'a'}}))), ['recursive-actual-map'])
check('recursive-actual-map regression 1', solve(dict(base, **({'recursive_expected':{'call':N+1},'recursive_actual':{'call':N}}))), ['recursive-actual-map'])
check('static-preservation regression 0', solve(dict(base, **({'static_before':'static','static_after':'a'}))), ['static-preservation'])
check('static-preservation regression 1', solve(dict(base, **({'static_before':'static','static_after':N}))), ['static-preservation'])
check('anonymous-freshness regression 0', solve(dict(base, **({'anonymous_calls':['c1','c2'],'anonymous_ids':['r','r']}))), ['anonymous-freshness'])
check('anonymous-freshness regression 1', solve(dict(base, **({'anonymous_calls':[N,N+1],'anonymous_ids':[0,0]}))), ['anonymous-freshness'])
check('where-direction regression 0', solve(dict(base, **({'expected_outlives':[('a','b')],'actual_outlives':[('b','a')]}))), ['where-direction'])
check('where-direction regression 1', solve(dict(base, **({'expected_outlives':[(N,N+1)],'actual_outlives':[(N+1,N)]}))), ['where-direction'])
check('associated-arguments regression 0', solve(dict(base, **({'associated_args':['a','b'],'recorded_args':['b','a']}))), ['associated-arguments'])
check('associated-arguments regression 1', solve(dict(base, **({'associated_args':[N,N+1],'recorded_args':[N+1,N]}))), ['associated-arguments'])
check('summary-fixed-point regression 0', solve(dict(base, **({'accepted':True,'pending':['a']}))), ['summary-fixed-point'])
check('summary-fixed-point regression 1', solve(dict(base, **({'accepted':True,'pending':[N]}))), ['summary-fixed-point'])
check('erased-proof-metadata regression 0', solve(dict(base, **({'reference_types':['a','b'],'proof_metadata':['a']}))), ['erased-proof-metadata'])
check('erased-proof-metadata regression 1', solve(dict(base, **({'reference_types':[N,N+1],'proof_metadata':[N]}))), ['erased-proof-metadata'])
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
lifetime-arity regression 0['lifetime-arity']['lifetime-arity']Passed
lifetime-arity regression 1['lifetime-arity']['lifetime-arity']Passed
positional-substitution regression 0['positional-substitution']['positional-substitution']Passed
positional-substitution regression 1['positional-substitution']['positional-substitution']Passed
repeated-substitution regression 0['repeated-substitution']['repeated-substitution']Passed
repeated-substitution regression 1['repeated-substitution']['repeated-substitution']Passed
recursive-actual-map regression 0['recursive-actual-map']['recursive-actual-map']Passed
recursive-actual-map regression 1['recursive-actual-map']['recursive-actual-map']Passed
static-preservation regression 0[]['static-preservation']Failed
static-preservation regression 1[]['static-preservation']Failed
anonymous-freshness regression 0['anonymous-freshness']['anonymous-freshness']Passed
anonymous-freshness regression 1['anonymous-freshness']['anonymous-freshness']Passed
where-direction regression 0['where-direction']['where-direction']Passed
where-direction regression 1['where-direction']['where-direction']Passed
associated-arguments regression 0['associated-arguments']['associated-arguments']Passed
associated-arguments regression 1['associated-arguments']['associated-arguments']Passed
summary-fixed-point regression 0['summary-fixed-point']['summary-fixed-point']Passed
summary-fixed-point regression 1['summary-fixed-point']['summary-fixed-point']Passed
erased-proof-metadata regression 0['erased-proof-metadata']['erased-proof-metadata']Passed
erased-proof-metadata regression 1['erased-proof-metadata']['erased-proof-metadata']Passed

SHA-256 / df27f11aa84f2b7a368cf28429f95471ba90fa96fec3f7817cb7dde0497100a2

3 / The verified repair

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

N = 1
observations = []
def solve(d):
    errors=[]
    if len(d['params'])!=len(d['args']): errors.append('lifetime-arity')
    if d['expected_mapping']!=d['actual_mapping']: errors.append('positional-substitution')
    if any(len(set(xs))>1 for xs in d['occurrences'].values()): errors.append('repeated-substitution')
    if d['recursive_expected']!=d['recursive_actual']: errors.append('recursive-actual-map')
    if d['static_before']!=d['static_after']: errors.append('static-preservation')
    if len(d['anonymous_calls'])==len(d['anonymous_ids']) and len(set(d['anonymous_ids']))!=len(d['anonymous_ids']): errors.append('anonymous-freshness')
    if set(map(tuple,d['expected_outlives']))!=set(map(tuple,d['actual_outlives'])): errors.append('where-direction')
    if d['associated_args']!=d['recorded_args']: errors.append('associated-arguments')
    if d['accepted'] and bool(d['pending']): errors.append('summary-fixed-point')
    if not set(d['reference_types'])<=set(d['proof_metadata']): errors.append('erased-proof-metadata')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': [], 'args': [], 'expected_mapping': {}, 'actual_mapping': {}, 'occurrences': {}, 'recursive_expected': {}, 'recursive_actual': {}, 'static_before': None, 'static_after': None, 'anonymous_calls': [], 'anonymous_ids': [], 'expected_outlives': [], 'actual_outlives': [], 'associated_args': [], 'recorded_args': [], 'pending': [], 'accepted': False, 'reference_types': [], 'proof_metadata': []}
check('well formed empty obligations',solve(base),[])
check('lifetime-arity regression 0', solve(dict(base, **({'params':['a'],'args':['x','y']}))), ['lifetime-arity'])
check('lifetime-arity regression 1', solve(dict(base, **({'params':[N],'args':[N,N+1]}))), ['lifetime-arity'])
check('positional-substitution regression 0', solve(dict(base, **({'expected_mapping':{'a':'x','b':'y'},'actual_mapping':{'a':'y','b':'x'}}))), ['positional-substitution'])
check('positional-substitution regression 1', solve(dict(base, **({'expected_mapping':{'a':N,'b':N+1},'actual_mapping':{'a':N+1,'b':N}}))), ['positional-substitution'])
check('repeated-substitution regression 0', solve(dict(base, **({'occurrences':{'a':['x','y']}}))), ['repeated-substitution'])
check('repeated-substitution regression 1', solve(dict(base, **({'occurrences':{'a':[N,N+1]}}))), ['repeated-substitution'])
check('recursive-actual-map regression 0', solve(dict(base, **({'recursive_expected':{'call':'b'},'recursive_actual':{'call':'a'}}))), ['recursive-actual-map'])
check('recursive-actual-map regression 1', solve(dict(base, **({'recursive_expected':{'call':N+1},'recursive_actual':{'call':N}}))), ['recursive-actual-map'])
check('static-preservation regression 0', solve(dict(base, **({'static_before':'static','static_after':'a'}))), ['static-preservation'])
check('static-preservation regression 1', solve(dict(base, **({'static_before':'static','static_after':N}))), ['static-preservation'])
check('anonymous-freshness regression 0', solve(dict(base, **({'anonymous_calls':['c1','c2'],'anonymous_ids':['r','r']}))), ['anonymous-freshness'])
check('anonymous-freshness regression 1', solve(dict(base, **({'anonymous_calls':[N,N+1],'anonymous_ids':[0,0]}))), ['anonymous-freshness'])
check('where-direction regression 0', solve(dict(base, **({'expected_outlives':[('a','b')],'actual_outlives':[('b','a')]}))), ['where-direction'])
check('where-direction regression 1', solve(dict(base, **({'expected_outlives':[(N,N+1)],'actual_outlives':[(N+1,N)]}))), ['where-direction'])
check('associated-arguments regression 0', solve(dict(base, **({'associated_args':['a','b'],'recorded_args':['b','a']}))), ['associated-arguments'])
check('associated-arguments regression 1', solve(dict(base, **({'associated_args':[N,N+1],'recorded_args':[N+1,N]}))), ['associated-arguments'])
check('summary-fixed-point regression 0', solve(dict(base, **({'accepted':True,'pending':['a']}))), ['summary-fixed-point'])
check('summary-fixed-point regression 1', solve(dict(base, **({'accepted':True,'pending':[N]}))), ['summary-fixed-point'])
check('erased-proof-metadata regression 0', solve(dict(base, **({'reference_types':['a','b'],'proof_metadata':['a']}))), ['erased-proof-metadata'])
check('erased-proof-metadata regression 1', solve(dict(base, **({'reference_types':[N,N+1],'proof_metadata':[N]}))), ['erased-proof-metadata'])
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
lifetime-arity regression 0['lifetime-arity']['lifetime-arity']Passed
lifetime-arity regression 1['lifetime-arity']['lifetime-arity']Passed
positional-substitution regression 0['positional-substitution']['positional-substitution']Passed
positional-substitution regression 1['positional-substitution']['positional-substitution']Passed
repeated-substitution regression 0['repeated-substitution']['repeated-substitution']Passed
repeated-substitution regression 1['repeated-substitution']['repeated-substitution']Passed
recursive-actual-map regression 0['recursive-actual-map']['recursive-actual-map']Passed
recursive-actual-map regression 1['recursive-actual-map']['recursive-actual-map']Passed
static-preservation regression 0['static-preservation']['static-preservation']Passed
static-preservation regression 1['static-preservation']['static-preservation']Passed
anonymous-freshness regression 0['anonymous-freshness']['anonymous-freshness']Passed
anonymous-freshness regression 1['anonymous-freshness']['anonymous-freshness']Passed
where-direction regression 0['where-direction']['where-direction']Passed
where-direction regression 1['where-direction']['where-direction']Passed
associated-arguments regression 0['associated-arguments']['associated-arguments']Passed
associated-arguments regression 1['associated-arguments']['associated-arguments']Passed
summary-fixed-point regression 0['summary-fixed-point']['summary-fixed-point']Passed
summary-fixed-point regression 1['summary-fixed-point']['summary-fixed-point']Passed
erased-proof-metadata regression 0['erased-proof-metadata']['erased-proof-metadata']Passed
erased-proof-metadata regression 1['erased-proof-metadata']['erased-proof-metadata']Passed

SHA-256 / cad9ef22ae66e85a0cf9ece541118c28b4ea5b071f000a75cf09c4de239d4263

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

Case digest / 8a53eaed8b20dc68fd8b0d870f6790cc8d6a0b6d86f4fefbc30954c3e9891ca8