use crate::{ast::ConditionKind, builder::module_builder::SpecBlockContext};
pub const VERIFY_PRAGMA: &str = "verify";
pub const TIMEOUT_PRAGMA: &str = "timeout";
pub const SEED_PRAGMA: &str = "seed";
pub const VERIFY_DURATION_ESTIMATE_PRAGMA: &str = "verify_duration_estimate";
pub const INTRINSIC_PRAGMA: &str = "intrinsic";
pub const OPAQUE_PRAGMA: &str = "opaque";
pub const EMITS_IS_PARTIAL_PRAGMA: &str = "emits_is_partial";
pub const EMITS_IS_STRICT_PRAGMA: &str = "emits_is_strict";
pub const ABORTS_IF_IS_PARTIAL_PRAGMA: &str = "aborts_if_is_partial";
pub const ABORTS_IF_IS_STRICT_PRAGMA: &str = "aborts_if_is_strict";
pub const REQUIRES_IF_ABORTS_PRAGMA: &str = "requires_if_aborts";
pub const ALWAYS_ABORTS_TEST_PRAGMA: &str = "always_aborts_test";
pub const ADDITION_OVERFLOW_UNCHECKED_PRAGMA: &str = "addition_overflow_unchecked";
pub const ASSUME_NO_ABORT_FROM_HERE_PRAGMA: &str = "assume_no_abort_from_here";
pub const EXPORT_ENSURES_PRAGMA: &str = "export_ensures";
pub const FRIEND_PRAGMA: &str = "friend";
pub const DISABLE_INVARIANTS_IN_BODY_PRAGMA: &str = "disable_invariants_in_body";
pub const DELEGATE_INVARIANTS_TO_CALLER_PRAGMA: &str = "delegate_invariants_to_caller";
pub fn is_pragma_valid_for_block(target: &SpecBlockContext<'_>, pragma: &str) -> bool {
use crate::builder::module_builder::SpecBlockContext::*;
match target {
Module => matches!(
pragma,
VERIFY_PRAGMA
| EMITS_IS_STRICT_PRAGMA
| EMITS_IS_PARTIAL_PRAGMA
| ABORTS_IF_IS_STRICT_PRAGMA
| ABORTS_IF_IS_PARTIAL_PRAGMA
| INTRINSIC_PRAGMA
),
Function(..) => matches!(
pragma,
VERIFY_PRAGMA
| TIMEOUT_PRAGMA
| SEED_PRAGMA
| VERIFY_DURATION_ESTIMATE_PRAGMA
| INTRINSIC_PRAGMA
| OPAQUE_PRAGMA
| EMITS_IS_STRICT_PRAGMA
| EMITS_IS_PARTIAL_PRAGMA
| ABORTS_IF_IS_PARTIAL_PRAGMA
| ABORTS_IF_IS_STRICT_PRAGMA
| REQUIRES_IF_ABORTS_PRAGMA
| ALWAYS_ABORTS_TEST_PRAGMA
| ADDITION_OVERFLOW_UNCHECKED_PRAGMA
| ASSUME_NO_ABORT_FROM_HERE_PRAGMA
| EXPORT_ENSURES_PRAGMA
| FRIEND_PRAGMA
| DISABLE_INVARIANTS_IN_BODY_PRAGMA
| DELEGATE_INVARIANTS_TO_CALLER_PRAGMA
),
Struct(..) => matches!(pragma, INTRINSIC_PRAGMA),
_ => false,
}
}
pub const CONDITION_INJECTED_PROP: &str = "$injected";
pub const CONDITION_EXPORT_PROP: &str = "export";
pub const CONDITION_GLOBAL_PROP: &str = "global";
pub const CONDITION_ISOLATED_PROP: &str = "isolated";
pub const CONDITION_ABSTRACT_PROP: &str = "abstract";
pub const CONDITION_CONCRETE_PROP: &str = "concrete";
pub const CONDITION_ABORT_ASSUME_PROP: &str = "assume";
pub const CONDITION_ABORT_ASSERT_PROP: &str = "assert";
pub const CONDITION_DEACTIVATED_PROP: &str = "deactivated";
pub const CONDITION_CHECK_ABORT_CODES_PROP: &str = "check";
pub const CONDITION_SUSPENDABLE_PROP: &str = "suspendable";
pub fn is_property_valid_for_condition(kind: &ConditionKind, prop: &str) -> bool {
if matches!(
prop,
CONDITION_INJECTED_PROP
| CONDITION_EXPORT_PROP
| CONDITION_ABSTRACT_PROP
| CONDITION_CONCRETE_PROP
| CONDITION_DEACTIVATED_PROP
) {
return true;
}
use crate::ast::ConditionKind::*;
match kind {
GlobalInvariant(..) | GlobalInvariantUpdate(..) => {
matches!(
prop,
CONDITION_GLOBAL_PROP | CONDITION_ISOLATED_PROP | CONDITION_SUSPENDABLE_PROP
)
}
SucceedsIf | AbortsIf => matches!(
prop,
CONDITION_ABORT_ASSERT_PROP | CONDITION_ABORT_ASSUME_PROP
),
AbortsWith => matches!(prop, CONDITION_CHECK_ABORT_CODES_PROP),
_ => {
false
}
}
}