Skip to content

Commit d8d6cd4

Browse files
authored
Fn output fix (#2477)
1 parent f47cca5 commit d8d6cd4

3 files changed

Lines changed: 39 additions & 7 deletions

File tree

source/rust_verify_test/tests/fndef_types.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,5 +2006,34 @@ test_verify_one_file_with_options! {
20062006
y.touch();
20072007
assert(y.index() == y.seq().len());
20082008
}
2009+
2010+
2011+
// Module `a` defines a struct with restricted visibility and a
2012+
// function whose signature mentions it. The function is used as an
2013+
// FnDef value, so Verus emits an auto-generated
2014+
// `<FnDef(takes_hidden) as FnOnce<(Hidden,)>>::Output = Hidden`
2015+
// AssocTypeImpl referencing `Hidden`.
2016+
mod a {
2017+
mod inner {
2018+
pub(super) struct Hidden { pub x: u32 }
2019+
}
2020+
2021+
fn takes_hidden(h: inner::Hidden) -> inner::Hidden { h }
2022+
2023+
fn use_as_fndef() {
2024+
let _f = takes_hidden;
2025+
}
2026+
}
2027+
2028+
// Module `b` cannot see `Hidden`.
2029+
// `b`'s code reaches the `FnOnce::Output` associated-type decl via
2030+
// the `F::Output` projection inside the `HasItem for Ad<F>` impl.
2031+
mod b {
2032+
fn foo(x: u32) -> u32 { x }
2033+
2034+
fn use_fn() {
2035+
let _y = crate::W { i: crate::Ad(foo) };
2036+
}
2037+
}
20092038
} => Ok(())
20102039
}

source/vir/src/ast_simplify.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,11 +1044,9 @@ fn add_fndef_axioms_to_function(
10441044
let (trait_impls_out, assoc_type_impl) = if fn_once_trait_in_scope {
10451045
let self_typ = Arc::new(TypX::FnDef(fun.clone(), typ_args.clone(), None));
10461046
let arg_typs: Vec<Typ> = params.iter().map(|p| p.a.clone()).collect();
1047-
let args_tuple_typ = Arc::new(TypX::Datatype(
1048-
Dt::Tuple(arg_typs.len()),
1049-
Arc::new(arg_typs),
1050-
Arc::new(vec![]),
1051-
));
1047+
let tuple_dt = state.tuple_type_name(arg_typs.len());
1048+
let args_tuple_typ =
1049+
Arc::new(TypX::Datatype(tuple_dt, Arc::new(arg_typs), Arc::new(vec![])));
10521050
let trait_typ_args = Arc::new(vec![self_typ, args_tuple_typ]);
10531051

10541052
let mk_impl_path = |kind: ClosureKind| {

source/vir/src/prune.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ enum ReachedType {
3535
Float(u32),
3636
SpecFn(usize),
3737
Datatype(Dt),
38+
FnDef(Fun, Vec<ReachedType>),
3839
StrSlice,
3940
Array,
4041
Primitive,
@@ -131,7 +132,9 @@ fn typ_to_reached_type(typ: &Typ) -> ReachedType {
131132
TypX::AnonymousClosure(..) => ReachedType::None,
132133
TypX::Datatype(dt, _, _) => ReachedType::Datatype(dt.clone()),
133134
TypX::Dyn(..) => ReachedType::None,
134-
TypX::FnDef(..) => ReachedType::None,
135+
TypX::FnDef(fun, typs, _) => {
136+
ReachedType::FnDef(fun.clone(), typs.iter().map(typ_to_reached_type).collect())
137+
}
135138
TypX::Decorate(_, _, t) => typ_to_reached_type(t),
136139
TypX::Boxed(t) => typ_to_reached_type(t),
137140
TypX::TypParam(_) => ReachedType::None,
@@ -309,9 +312,11 @@ fn reach_typ(ctxt: &Ctxt, state: &mut State, typ: &Typ) {
309312
reach_assoc_type_decl(ctxt, state, &(trait_path.clone(), name.clone()));
310313
// let visitor handle self_typ, trait_typ_args
311314
}
312-
TypX::FnDef(fun, _typs, res_fun_opt) => {
315+
TypX::FnDef(fun, typs, res_fun_opt) => {
313316
state.fndef_types.insert(fun.clone());
314317
reach_function(ctxt, state, fun);
318+
let typ_args: Vec<ReachedType> = typs.iter().map(typ_to_reached_type).collect();
319+
reach_type(ctxt, state, &ReachedType::FnDef(fun.clone(), typ_args));
315320

316321
if let Some(res_fun) = res_fun_opt {
317322
state.fndef_types.insert(res_fun.clone());

0 commit comments

Comments
 (0)