1use rustc_hir::def_id::DefId;
8
9use super::{contract::Property};
10use crate::helpers::mir_scan::CheckpointLocation;
11
12#[derive(Clone, Debug, PartialEq)]
14pub enum CheckResult {
15 Proved,
17 Failed,
19 Unknown,
21}
22
23impl CheckResult {
24 pub fn and(self, other: CheckResult) -> CheckResult {
27 match (self, other) {
28 (CheckResult::Failed, _) | (_, CheckResult::Failed) => CheckResult::Failed,
29 (CheckResult::Unknown, _) | (_, CheckResult::Unknown) => CheckResult::Unknown,
30 _ => CheckResult::Proved,
31 }
32 }
33
34 pub fn or(self, other: CheckResult) -> CheckResult {
37 match (self, other) {
38 (CheckResult::Proved, _) | (_, CheckResult::Proved) => CheckResult::Proved,
39 (CheckResult::Failed, CheckResult::Failed) => CheckResult::Failed,
40 _ => CheckResult::Unknown,
41 }
42 }
43}
44
45#[derive(Clone, Debug)]
47pub struct PropertyCheckResult<'tcx> {
48 pub checkpoint: CheckpointLocation,
50 pub checkpoint_index: usize,
52 pub path_index: usize,
54 pub property_index: usize,
56 pub property: Property<'tcx>,
58 pub result: CheckResult,
60 pub diagnostics: Option<String>,
62 pub path_description: String,
64 pub callee_name: String,
66}
67
68#[derive(Clone, Debug)]
70pub struct VerificationReport<'tcx> {
71 pub function: DefId,
73 pub results: Vec<PropertyCheckResult<'tcx>>,
75}
76
77impl<'tcx> VerificationReport<'tcx> {
78 pub fn new(function: DefId) -> Self {
80 Self {
81 function,
82 results: Vec::new(),
83 }
84 }
85
86 pub fn push(&mut self, result: PropertyCheckResult<'tcx>) {
88 self.results.push(result);
89 }
90
91 pub fn len(&self) -> usize {
93 self.results.len()
94 }
95
96 pub fn is_empty(&self) -> bool {
98 self.results.is_empty()
99 }
100
101 pub fn describe(&self) -> String {
103 let mut out = String::new();
104 out.push_str(&format!(
105 "[rapx::verify::diagnostics] function {:?}: {} check item(s)\n",
106 self.function,
107 self.results.len()
108 ));
109
110 for (index, result) in self.results.iter().enumerate() {
111 out.push_str(&format!(
112 " check #{index}: checkpoint #{}, bb{}, path #{}, property #{} {:?}, result {:?}\n",
113 result.checkpoint_index,
114 result.checkpoint.block.as_usize(),
115 result.path_index,
116 result.property_index,
117 result.property.kind(),
118 result.result
119 ));
120
121 if let Some(diagnostics) = &result.diagnostics {
122 out.push_str(diagnostics);
123 if !diagnostics.ends_with('\n') {
124 out.push('\n');
125 }
126 }
127 }
128
129 out
130 }
131}