Skip to content

Commit baccc4d

Browse files
authored
[anodized-core] fix: postcondition closure input type ascription (#152)
- If the closure's input already has a type ascription, leave it unchanged. - Refactor and comment.
1 parent d14f063 commit baccc4d

2 files changed

Lines changed: 15 additions & 34 deletions

File tree

crates/anodized-core/src/instrument/fns.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,19 @@ impl Config {
243243
postcondition_clauses.push(clause);
244244
}
245245
for postcondition in &spec.ensures {
246-
let closure = annotate_postcondition_closure_argument(
247-
postcondition.closure.clone(),
248-
return_type.clone(),
249-
);
250-
let expr = parse_quote! { (#closure)(&#output_ident) };
251-
let inputs = &postcondition.closure.inputs;
252-
let body = &postcondition.closure.body;
246+
let closure = &postcondition.closure;
247+
let input = &closure.inputs.first().unwrap();
248+
let output = &closure.output;
249+
let body = &closure.body;
250+
let expr = match input {
251+
Pat::Type(_) => parse_quote! { (#closure)(&#output_ident) },
252+
_ => parse_quote! {
253+
// If the closure's input doesn't have a type ascription, add one.
254+
(|#input: &#return_type| #output { #body })(&#output_ident)
255+
},
256+
};
253257
// Omit the closure's return type for brevity.
254-
let repr = quote! { |#inputs| #body }.to_string();
258+
let repr = quote! { |#input| #body }.to_string();
255259
let clause = self.build_clause_eval(postcondition.cfg.as_ref(), &expr, &repr);
256260
postcondition_clauses.push(clause);
257261
}
@@ -308,26 +312,3 @@ impl Config {
308312
}
309313
}
310314
}
311-
312-
fn annotate_postcondition_closure_argument(
313-
mut closure: syn::ExprClosure,
314-
return_type: syn::Type,
315-
) -> syn::ExprClosure {
316-
// Add type annotation: convert |param| to |param: &ReturnType|.
317-
if let Some(first_input) = closure.inputs.first_mut() {
318-
// Wrap the pattern with a type annotation
319-
let pattern = first_input.clone();
320-
*first_input = syn::Pat::Type(syn::PatType {
321-
attrs: vec![],
322-
pat: Box::new(pattern),
323-
colon_token: Default::default(),
324-
ty: Box::new(syn::Type::Reference(syn::TypeReference {
325-
and_token: Default::default(),
326-
lifetime: None,
327-
mutability: None,
328-
elem: Box::new(return_type),
329-
})),
330-
});
331-
}
332-
closure
333-
}

crates/anodized-core/src/instrument/fns_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn embed_spec_item_fn() {
2222
#[cfg(META_3)]
2323
ensures: [
2424
COND_8,
25-
|PAT_2| COND_9,
25+
|PAT_2: TYPE| COND_9,
2626
],
2727
};
2828
let item_fn: ItemFn = parse_quote! {
@@ -59,7 +59,7 @@ fn embed_spec_item_fn() {
5959
let (ALIAS_1, (ALIAS_2, ALIAS_3)) = ((| | EXPR_1)(), (| | EXPR_2)());
6060
let _ = |PAT_1: &RET_TYPE| -> bool { COND_7 };
6161
let _ = |PAT_1: &RET_TYPE| -> bool { COND_8 };
62-
let _ = |PAT_2: &RET_TYPE| -> bool { COND_9 };
62+
let _ = |PAT_2: TYPE| -> bool { COND_9 };
6363
}
6464

6565
fn FUNC(&self, PARAM_1: TYPE_1, PARAM_2: TYPE_2) -> RET_TYPE {
@@ -87,7 +87,7 @@ fn embed_spec_item_fn() {
8787
& (|| -> bool { COND_6 })()
8888
& (|PAT_1: &RET_TYPE| -> bool { COND_7 })(&__anodized_output)
8989
& (|PAT_1: &RET_TYPE| -> bool { COND_8 })(&__anodized_output)
90-
& (|PAT_2: &RET_TYPE| -> bool { COND_9 })(&__anodized_output);
90+
& (|PAT_2: TYPE| -> bool { COND_9 })(&__anodized_output);
9191
if !__anodized_postcond {}
9292
}
9393
__anodized_output

0 commit comments

Comments
 (0)