FAILURE MAP
← Case archive

FA-43136 / Borrow checking / Open access

An unused lifetime parameter survives when another parameter is used · case 01

An unused lifetime parameter survives when another parameter is used.

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

ROOT CAUSE

The static analyzer mishandles unused param: an unused lifetime parameter survives when another parameter is used.

VERIFIED REPAIR

Apply the specified transfer or inference rule at this site: if not set(d['params'])<=set(d['used_params']): errors.append('unused-param').

Unsuccessful approach: The partial repair uses if not d['used_params']: errors.append('unused-param'), which still violates the stipulated analysis contract.

Case contract

Check borrowed function signature well-formedness: lifetime parameters unique; all occurrences declared or static; output elision needs exactly one input lifetime; receiver elision uses receiver lifetime; every output source is an input; by-reference return cannot originate in a local; returned mutable borrow requires mutable input; output extent must fit source extent; bound lifetime cannot escape binder depth; unused lifetime parameters rejected in this toy language. 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(set(d['params'])): errors.append('duplicate-param')
    if any(x not in d['params'] and x!='static' for x in d['uses']): errors.append('undeclared-occurrence')
    if d['elided'] and d['receiver'] is None and len(set(d['inputs']))!=1: errors.append('ambiguous-elision')
    if d['elided'] and d['receiver'] is not None and d['output']!=d['receiver']: errors.append('receiver-elision')
    if any(x not in d['inputs'] for x in d['sources']): errors.append('output-source')
    if bool(set(d['sources'])&set(d['locals'])): errors.append('local-return')
    if d['mutable_out'] and not set(d['sources'])<=set(d['mutable_inputs']): errors.append('mutable-source')
    if not set(d['required'])<=set(d['available']): errors.append('return-extent')
    if d['bound_depth']>d['output_depth']: errors.append('binder-escape')
    if False: errors.append('unused-param')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': ['a'], 'uses': ['a'], 'inputs': ['a'], 'output': None, 'receiver': None, 'elided': False, 'sources': [], 'locals': [], 'mutable_out': False, 'mutable_inputs': [], 'required': [], 'available': [], 'bound_depth': 0, 'output_depth': 0, 'used_params': ['a']}
check('well formed empty obligations',solve(base),[])
check('duplicate-param regression 0', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('duplicate-param regression 1', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('undeclared-occurrence regression 0', solve(dict(base, **({'uses':['a','b'+str(N)]}))), ['undeclared-occurrence'])
check('undeclared-occurrence regression 1', solve(dict(base, **({'uses':['a','z']}))), ['undeclared-occurrence'])
check('ambiguous-elision regression 0', solve(dict(base, **({'elided':True,'inputs':['a','b']}))), ['ambiguous-elision'])
check('ambiguous-elision regression 1', solve(dict(base, **({'elided':True,'inputs':list(range(N+2))}))), ['ambiguous-elision'])
check('receiver-elision regression 0', solve(dict(base, **({'elided':True,'receiver':'a','output':'b'}))), ['receiver-elision'])
check('receiver-elision regression 1', solve(dict(base, **({'elided':True,'receiver':'a','output':'static'}))), ['receiver-elision'])
check('output-source regression 0', solve(dict(base, **({'sources':['a','b']}))), ['output-source'])
check('output-source regression 1', solve(dict(base, **({'sources':['a','z'+str(N)]}))), ['output-source'])
check('local-return regression 0', solve(dict(base, **({'inputs':['a','b'],'sources':['a','b'],'locals':['b']}))), ['local-return'])
check('local-return regression 1', solve(dict(base, **({'inputs':['a','c'],'sources':['a','c'],'locals':['c']}))), ['local-return'])
check('mutable-source regression 0', solve(dict(base, **({'mutable_out':True,'inputs':['a','b'],'sources':['a','b'],'mutable_inputs':['a']}))), ['mutable-source'])
check('mutable-source regression 1', solve(dict(base, **({'mutable_out':True,'sources':['a'],'mutable_inputs':['b']}))), ['mutable-source'])
check('return-extent regression 0', solve(dict(base, **({'required':[N],'available':[N+1]}))), ['return-extent'])
check('return-extent regression 1', solve(dict(base, **({'required':[N,N+1],'available':[N+1,N+2]}))), ['return-extent'])
check('binder-escape regression 0', solve(dict(base, **({'bound_depth':N,'output_depth':N-1}))), ['binder-escape'])
check('binder-escape regression 1', solve(dict(base, **({'bound_depth':N+1,'output_depth':N}))), ['binder-escape'])
check('unused-param regression 0', solve(dict(base, **({'params':['a','b'],'used_params':['a']}))), ['unused-param'])
check('unused-param regression 1', solve(dict(base, **({'params':['a','z'+str(N)],'used_params':['a']}))), ['unused-param'])
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
duplicate-param regression 0['duplicate-param']['duplicate-param']Passed
duplicate-param regression 1['duplicate-param']['duplicate-param']Passed
undeclared-occurrence regression 0['undeclared-occurrence']['undeclared-occurrence']Passed
undeclared-occurrence regression 1['undeclared-occurrence']['undeclared-occurrence']Passed
ambiguous-elision regression 0['ambiguous-elision']['ambiguous-elision']Passed
ambiguous-elision regression 1['ambiguous-elision']['ambiguous-elision']Passed
receiver-elision regression 0['receiver-elision']['receiver-elision']Passed
receiver-elision regression 1['receiver-elision']['receiver-elision']Passed
output-source regression 0['output-source']['output-source']Passed
output-source regression 1['output-source']['output-source']Passed
local-return regression 0['local-return']['local-return']Passed
local-return regression 1['local-return']['local-return']Passed
mutable-source regression 0['mutable-source']['mutable-source']Passed
mutable-source regression 1['mutable-source']['mutable-source']Passed
return-extent regression 0['return-extent']['return-extent']Passed
return-extent regression 1['return-extent']['return-extent']Passed
binder-escape regression 0['binder-escape']['binder-escape']Passed
binder-escape regression 1['binder-escape']['binder-escape']Passed
unused-param regression 0[]['unused-param']Failed
unused-param regression 1[]['unused-param']Failed

SHA-256 / 313bef7800e468fb591560b7860eee7c0a2c09852abe5784932d69ad9a2b7d97

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(set(d['params'])): errors.append('duplicate-param')
    if any(x not in d['params'] and x!='static' for x in d['uses']): errors.append('undeclared-occurrence')
    if d['elided'] and d['receiver'] is None and len(set(d['inputs']))!=1: errors.append('ambiguous-elision')
    if d['elided'] and d['receiver'] is not None and d['output']!=d['receiver']: errors.append('receiver-elision')
    if any(x not in d['inputs'] for x in d['sources']): errors.append('output-source')
    if bool(set(d['sources'])&set(d['locals'])): errors.append('local-return')
    if d['mutable_out'] and not set(d['sources'])<=set(d['mutable_inputs']): errors.append('mutable-source')
    if not set(d['required'])<=set(d['available']): errors.append('return-extent')
    if d['bound_depth']>d['output_depth']: errors.append('binder-escape')
    if not d['used_params']: errors.append('unused-param')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': ['a'], 'uses': ['a'], 'inputs': ['a'], 'output': None, 'receiver': None, 'elided': False, 'sources': [], 'locals': [], 'mutable_out': False, 'mutable_inputs': [], 'required': [], 'available': [], 'bound_depth': 0, 'output_depth': 0, 'used_params': ['a']}
check('well formed empty obligations',solve(base),[])
check('duplicate-param regression 0', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('duplicate-param regression 1', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('undeclared-occurrence regression 0', solve(dict(base, **({'uses':['a','b'+str(N)]}))), ['undeclared-occurrence'])
check('undeclared-occurrence regression 1', solve(dict(base, **({'uses':['a','z']}))), ['undeclared-occurrence'])
check('ambiguous-elision regression 0', solve(dict(base, **({'elided':True,'inputs':['a','b']}))), ['ambiguous-elision'])
check('ambiguous-elision regression 1', solve(dict(base, **({'elided':True,'inputs':list(range(N+2))}))), ['ambiguous-elision'])
check('receiver-elision regression 0', solve(dict(base, **({'elided':True,'receiver':'a','output':'b'}))), ['receiver-elision'])
check('receiver-elision regression 1', solve(dict(base, **({'elided':True,'receiver':'a','output':'static'}))), ['receiver-elision'])
check('output-source regression 0', solve(dict(base, **({'sources':['a','b']}))), ['output-source'])
check('output-source regression 1', solve(dict(base, **({'sources':['a','z'+str(N)]}))), ['output-source'])
check('local-return regression 0', solve(dict(base, **({'inputs':['a','b'],'sources':['a','b'],'locals':['b']}))), ['local-return'])
check('local-return regression 1', solve(dict(base, **({'inputs':['a','c'],'sources':['a','c'],'locals':['c']}))), ['local-return'])
check('mutable-source regression 0', solve(dict(base, **({'mutable_out':True,'inputs':['a','b'],'sources':['a','b'],'mutable_inputs':['a']}))), ['mutable-source'])
check('mutable-source regression 1', solve(dict(base, **({'mutable_out':True,'sources':['a'],'mutable_inputs':['b']}))), ['mutable-source'])
check('return-extent regression 0', solve(dict(base, **({'required':[N],'available':[N+1]}))), ['return-extent'])
check('return-extent regression 1', solve(dict(base, **({'required':[N,N+1],'available':[N+1,N+2]}))), ['return-extent'])
check('binder-escape regression 0', solve(dict(base, **({'bound_depth':N,'output_depth':N-1}))), ['binder-escape'])
check('binder-escape regression 1', solve(dict(base, **({'bound_depth':N+1,'output_depth':N}))), ['binder-escape'])
check('unused-param regression 0', solve(dict(base, **({'params':['a','b'],'used_params':['a']}))), ['unused-param'])
check('unused-param regression 1', solve(dict(base, **({'params':['a','z'+str(N)],'used_params':['a']}))), ['unused-param'])
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
duplicate-param regression 0['duplicate-param']['duplicate-param']Passed
duplicate-param regression 1['duplicate-param']['duplicate-param']Passed
undeclared-occurrence regression 0['undeclared-occurrence']['undeclared-occurrence']Passed
undeclared-occurrence regression 1['undeclared-occurrence']['undeclared-occurrence']Passed
ambiguous-elision regression 0['ambiguous-elision']['ambiguous-elision']Passed
ambiguous-elision regression 1['ambiguous-elision']['ambiguous-elision']Passed
receiver-elision regression 0['receiver-elision']['receiver-elision']Passed
receiver-elision regression 1['receiver-elision']['receiver-elision']Passed
output-source regression 0['output-source']['output-source']Passed
output-source regression 1['output-source']['output-source']Passed
local-return regression 0['local-return']['local-return']Passed
local-return regression 1['local-return']['local-return']Passed
mutable-source regression 0['mutable-source']['mutable-source']Passed
mutable-source regression 1['mutable-source']['mutable-source']Passed
return-extent regression 0['return-extent']['return-extent']Passed
return-extent regression 1['return-extent']['return-extent']Passed
binder-escape regression 0['binder-escape']['binder-escape']Passed
binder-escape regression 1['binder-escape']['binder-escape']Passed
unused-param regression 0[]['unused-param']Failed
unused-param regression 1[]['unused-param']Failed

SHA-256 / a20a9309971a2bfffb4b6c847e16513eb53876331317353ca19b288fd14efefa

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(set(d['params'])): errors.append('duplicate-param')
    if any(x not in d['params'] and x!='static' for x in d['uses']): errors.append('undeclared-occurrence')
    if d['elided'] and d['receiver'] is None and len(set(d['inputs']))!=1: errors.append('ambiguous-elision')
    if d['elided'] and d['receiver'] is not None and d['output']!=d['receiver']: errors.append('receiver-elision')
    if any(x not in d['inputs'] for x in d['sources']): errors.append('output-source')
    if bool(set(d['sources'])&set(d['locals'])): errors.append('local-return')
    if d['mutable_out'] and not set(d['sources'])<=set(d['mutable_inputs']): errors.append('mutable-source')
    if not set(d['required'])<=set(d['available']): errors.append('return-extent')
    if d['bound_depth']>d['output_depth']: errors.append('binder-escape')
    if not set(d['params'])<=set(d['used_params']): errors.append('unused-param')
    return errors
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
base={'params': ['a'], 'uses': ['a'], 'inputs': ['a'], 'output': None, 'receiver': None, 'elided': False, 'sources': [], 'locals': [], 'mutable_out': False, 'mutable_inputs': [], 'required': [], 'available': [], 'bound_depth': 0, 'output_depth': 0, 'used_params': ['a']}
check('well formed empty obligations',solve(base),[])
check('duplicate-param regression 0', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('duplicate-param regression 1', solve(dict(base, **({'params':['a','a']}))), ['duplicate-param'])
check('undeclared-occurrence regression 0', solve(dict(base, **({'uses':['a','b'+str(N)]}))), ['undeclared-occurrence'])
check('undeclared-occurrence regression 1', solve(dict(base, **({'uses':['a','z']}))), ['undeclared-occurrence'])
check('ambiguous-elision regression 0', solve(dict(base, **({'elided':True,'inputs':['a','b']}))), ['ambiguous-elision'])
check('ambiguous-elision regression 1', solve(dict(base, **({'elided':True,'inputs':list(range(N+2))}))), ['ambiguous-elision'])
check('receiver-elision regression 0', solve(dict(base, **({'elided':True,'receiver':'a','output':'b'}))), ['receiver-elision'])
check('receiver-elision regression 1', solve(dict(base, **({'elided':True,'receiver':'a','output':'static'}))), ['receiver-elision'])
check('output-source regression 0', solve(dict(base, **({'sources':['a','b']}))), ['output-source'])
check('output-source regression 1', solve(dict(base, **({'sources':['a','z'+str(N)]}))), ['output-source'])
check('local-return regression 0', solve(dict(base, **({'inputs':['a','b'],'sources':['a','b'],'locals':['b']}))), ['local-return'])
check('local-return regression 1', solve(dict(base, **({'inputs':['a','c'],'sources':['a','c'],'locals':['c']}))), ['local-return'])
check('mutable-source regression 0', solve(dict(base, **({'mutable_out':True,'inputs':['a','b'],'sources':['a','b'],'mutable_inputs':['a']}))), ['mutable-source'])
check('mutable-source regression 1', solve(dict(base, **({'mutable_out':True,'sources':['a'],'mutable_inputs':['b']}))), ['mutable-source'])
check('return-extent regression 0', solve(dict(base, **({'required':[N],'available':[N+1]}))), ['return-extent'])
check('return-extent regression 1', solve(dict(base, **({'required':[N,N+1],'available':[N+1,N+2]}))), ['return-extent'])
check('binder-escape regression 0', solve(dict(base, **({'bound_depth':N,'output_depth':N-1}))), ['binder-escape'])
check('binder-escape regression 1', solve(dict(base, **({'bound_depth':N+1,'output_depth':N}))), ['binder-escape'])
check('unused-param regression 0', solve(dict(base, **({'params':['a','b'],'used_params':['a']}))), ['unused-param'])
check('unused-param regression 1', solve(dict(base, **({'params':['a','z'+str(N)],'used_params':['a']}))), ['unused-param'])
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
duplicate-param regression 0['duplicate-param']['duplicate-param']Passed
duplicate-param regression 1['duplicate-param']['duplicate-param']Passed
undeclared-occurrence regression 0['undeclared-occurrence']['undeclared-occurrence']Passed
undeclared-occurrence regression 1['undeclared-occurrence']['undeclared-occurrence']Passed
ambiguous-elision regression 0['ambiguous-elision']['ambiguous-elision']Passed
ambiguous-elision regression 1['ambiguous-elision']['ambiguous-elision']Passed
receiver-elision regression 0['receiver-elision']['receiver-elision']Passed
receiver-elision regression 1['receiver-elision']['receiver-elision']Passed
output-source regression 0['output-source']['output-source']Passed
output-source regression 1['output-source']['output-source']Passed
local-return regression 0['local-return']['local-return']Passed
local-return regression 1['local-return']['local-return']Passed
mutable-source regression 0['mutable-source']['mutable-source']Passed
mutable-source regression 1['mutable-source']['mutable-source']Passed
return-extent regression 0['return-extent']['return-extent']Passed
return-extent regression 1['return-extent']['return-extent']Passed
binder-escape regression 0['binder-escape']['binder-escape']Passed
binder-escape regression 1['binder-escape']['binder-escape']Passed
unused-param regression 0['unused-param']['unused-param']Passed
unused-param regression 1['unused-param']['unused-param']Passed

SHA-256 / 3034ed1110cb2e8383151540923c39e1e3b4eb5cef0a09367e4601ae444e6b56

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

Case digest / d041a81c0fa95427dbacecbb98b04ffb2e48e69be13c6e8d2a53fcc64b627651