Generate statements for checking a closure specification. TODO: arguments, result (types are typically not known yet after parsing...)
(
&mut self,
inputs: Punctuated<Pat, Token![,]>,
output: Type,
preconds: Vec<(untyped::SpecificationId, untyped::Assertion)>,
postconds: Vec<(untyped::Specifica
| 161 | /// Generate statements for checking a closure specification. |
| 162 | /// TODO: arguments, result (types are typically not known yet after parsing...) |
| 163 | pub fn generate_cl_spec( |
| 164 | &mut self, |
| 165 | inputs: Punctuated<Pat, Token![,]>, |
| 166 | output: Type, |
| 167 | preconds: Vec<(untyped::SpecificationId, untyped::Assertion)>, |
| 168 | postconds: Vec<(untyped::SpecificationId, untyped::Assertion)> |
| 169 | ) -> (TokenStream, TokenStream) { |
| 170 | let process_cond = |is_post: bool, id: &untyped::SpecificationId, |
| 171 | assertion: &untyped::Assertion| -> TokenStream |
| 172 | { |
| 173 | let spec_id_str = id.to_string(); |
| 174 | let mut encoded = TokenStream::new(); |
| 175 | assertion.encode_type_check(&mut encoded); |
| 176 | let assertion_json = crate::specifications::json::to_json_string(assertion); |
| 177 | let name = format_ident!("prusti_{}_closure_{}", if is_post { "post" } else { "pre" }, spec_id_str); |
| 178 | let callsite_span = Span::call_site(); |
| 179 | let result = if is_post && !inputs.empty_or_trailing() { |
| 180 | quote_spanned! { callsite_span => , result: #output } |
| 181 | } else if is_post { |
| 182 | quote_spanned! { callsite_span => result: #output } |
| 183 | } else { |
| 184 | TokenStream::new() |
| 185 | }; |
| 186 | quote_spanned! { callsite_span => |
| 187 | #[prusti::spec_only] |
| 188 | #[prusti::spec_id = #spec_id_str] |
| 189 | #[prusti::assertion = #assertion_json] |
| 190 | fn #name(#inputs #result) { |
| 191 | #encoded |
| 192 | } |
| 193 | } |
| 194 | }; |
| 195 | |
| 196 | let mut pre_ts = TokenStream::new(); |
| 197 | for (id, precond) in preconds { |
| 198 | pre_ts.extend(process_cond(false, &id, &precond)); |
| 199 | } |
| 200 | |
| 201 | let mut post_ts = TokenStream::new(); |
| 202 | for (id, postcond) in postconds { |
| 203 | post_ts.extend(process_cond(true, &id, &postcond)); |
| 204 | } |
| 205 | |
| 206 | (pre_ts, post_ts) |
| 207 | } |
| 208 | } |
nothing calls this directly
no test coverage detected