Summary
Verifying the body of a generic function that calls a closure whose argument type is a generic type parameter panics with called Option::unwrap() on a None value in rty::Instantiator::instantiate (src/rty.rs:1573).
This is independent of any specification — it reproduces on a plain higher-order function with no requires/ensures.
Reproduction
//@compile-flags: -C debug-assertions=off
fn apply<T, F: FnOnce(T) -> T>(x: T, f: F) -> T {
f(x)
}
fn call_apply<T>(x: T) -> T {
apply(x, |y| y)
}
fn main() {
let r = call_apply(3);
assert!(r == 3);
}
thread 'rustc' panicked at src/rty.rs:1573:56:
called `Option::unwrap()` on a `None` value
Abridged stack:
rty::Instantiator::instantiate (src/rty.rs:1573 Value => value_var.unwrap())
rty::clause_builder::RefinementClauseBuilder::add_body
analyze::basic_block::Analyzer::relate_fn_param_sub_types_with_builder
analyze::basic_block::Analyzer::relate_fn_sub_type
analyze::basic_block::Analyzer::type_call (analyzing the `f(x)` call inside apply)
...
analyze::Analyzer::def_ty_with_args (apply analyzed per-instantiation)
The Value variable in the closure parameter's refinement reaches Instantiator::instantiate without a value_var being set, during the RustCall parameter expansion for the f(x) call. It only triggers when the closure's argument type is a generic parameter (T); the monomorphic analogue (F: FnOnce(i32) -> i32) verifies fine.
Notes
Summary
Verifying the body of a generic function that calls a closure whose argument type is a generic type parameter panics with
called Option::unwrap() on a None valueinrty::Instantiator::instantiate(src/rty.rs:1573).This is independent of any specification — it reproduces on a plain higher-order function with no
requires/ensures.Reproduction
Abridged stack:
The
Valuevariable in the closure parameter's refinement reachesInstantiator::instantiatewithout avalue_varbeing set, during theRustCallparameter expansion for thef(x)call. It only triggers when the closure's argument type is a generic parameter (T); the monomorphic analogue (F: FnOnce(i32) -> i32) verifies fine.Notes
mainboth before and after Verify generic functions' bodies against requires/ensures contracts #105.closure_postcondition_generic.rstest exercises exactly this shape.)RustCallparameter-relation path.