use super::{allocated, common::SmtCheckResult, in_bound};
use crate::verify::{
contract::Property, verifier::ForwardVisitResult, helpers::Checkpoint, report::CheckResult,
};
pub(crate) fn check<'tcx>(
checker: &super::common::SmtChecker<'tcx>,
checkpoint: &Checkpoint<'tcx>,
property: &Property<'tcx>,
forward: &ForwardVisitResult<'tcx>,
) -> SmtCheckResult {
let allocated = allocated::check(checker, checkpoint, property, forward);
let in_bound = in_bound::check(checker, checkpoint, property, forward);
match (&allocated.result, &in_bound.result) {
(CheckResult::Proved, CheckResult::Proved) => {
SmtCheckResult::proved("Deref proved: target range is allocated and in bounds")
}
(CheckResult::Failed, _) | (_, CheckResult::Failed) => SmtCheckResult {
result: CheckResult::Failed,
query: None,
notes: vec![String::from(
"Deref failed: Allocated and InBound must both hold",
)],
},
_ => SmtCheckResult::unknown("Deref unknown: Allocated or InBound is not proved"),
}
.with_note(format!(
"primitive Allocated via SMT: {:?}",
allocated.result
))
.with_note(format!("primitive InBound via SMT: {:?}", in_bound.result))
}