use super::common::{SmtCheckResult, SmtChecker, SmtObligation};
use crate::verify::{contract::Property, helpers::Checkpoint, verifier::ForwardVisitResult};
pub(crate) fn check<'tcx>(
checker: &SmtChecker<'tcx>,
checkpoint: &Checkpoint<'tcx>,
property: &Property<'tcx>,
forward: &ForwardVisitResult<'tcx>,
) -> SmtCheckResult {
let Some(target) = checker.property_target(checkpoint, property) else {
return SmtCheckResult::unknown("Init target could not be resolved");
};
let Some(required_ty) = checker.property_required_ty(checkpoint, property) else {
return SmtCheckResult::unknown("Init type could not be resolved");
};
let Some(elements_expr) = checker.property_len_expr(checkpoint, property) else {
return SmtCheckResult::unknown("Init element-count argument could not be resolved");
};
let Some(elements_term) = checker.contract_expr_to_smt_term(checkpoint.caller, &elements_expr)
else {
return SmtCheckResult::unknown("Init element-count argument could not be lowered to SMT");
};
checker.prove_obligation(
checkpoint,
forward,
SmtObligation::Initialized {
place: target,
ty_name: format!("{required_ty:?}"),
elements: elements_term,
},
)
}
pub(crate) fn check_for_checkpoint<'tcx>(
checker: &SmtChecker<'tcx>,
caller: rustc_hir::def_id::DefId,
property: &Property<'tcx>,
forward: &ForwardVisitResult<'tcx>,
) -> SmtCheckResult {
let Some(target) = checker.property_target_direct(property) else {
return SmtCheckResult::unknown("Init target could not be resolved");
};
let Some(required_ty) = checker.property_required_ty_direct(property) else {
return SmtCheckResult::unknown("Init type could not be resolved");
};
let Some(elements_expr) = checker.property_len_expr_direct(property) else {
return SmtCheckResult::unknown("Init element-count argument could not be resolved");
};
let Some(elements) = checker.contract_expr_to_smt_term(caller, &elements_expr) else {
return SmtCheckResult::unknown("Init element-count argument could not be lowered to SMT");
};
checker.prove_obligation_for_checkpoint(
caller,
forward,
SmtObligation::Initialized {
place: target,
ty_name: format!("{required_ty:?}"),
elements,
},
)
}