Skip to content

Commit df70fcf

Browse files
Add table/dynamic_field in pure functions. (#441)
1 parent d7538ab commit df70fcf

File tree

4 files changed

+25
-21
lines changed

4 files changed

+25
-21
lines changed

crates/move-prover-boogie-backend/src/boogie_backend/bytecode_translator.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,7 +2750,13 @@ impl<'env> FunctionTranslator<'env> {
27502750
let native_fn =
27512751
self.parent.env.should_be_used_as_func(&mid.qualified(*fid));
27522752
// Handle function calls for functions that can be emitted as Boogie functions
2753-
if self.can_callee_be_function(mid, fid) || native_fn {
2753+
if self.can_callee_be_function(mid, fid)
2754+
|| PureFunctionAnalysisProcessor::native_pure_variants(
2755+
self.parent.env,
2756+
)
2757+
.contains(&mid.qualified(*fid))
2758+
|| native_fn
2759+
{
27542760
let inst = &self.inst_slice(inst);
27552761
let fun_name = boogie_function_name(
27562762
&callee_env,
@@ -2763,14 +2769,6 @@ impl<'env> FunctionTranslator<'env> {
27632769
);
27642770
let args = srcs.iter().map(|s| fmt_temp(*s)).join(", ");
27652771
format!("{}({})", fun_name, args)
2766-
} else if let Some(fun_name) =
2767-
PureFunctionAnalysisProcessor::special_pure_functions_map(
2768-
self.parent.env,
2769-
)
2770-
.get(&mid.qualified(*fid))
2771-
{
2772-
let args = srcs.iter().map(|s| fmt_temp(*s)).join(", ");
2773-
format!("{}({})", fun_name, args)
27742772
} else {
27752773
unreachable!(
27762774
"Cannot emit function call to {:?} as pure function",

crates/move-prover-boogie-backend/src/boogie_backend/prelude/native.bpl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ procedure {:inline 1} $1_vector_borrow{{S}}(v: Vec ({{T}}), i: int) returns (dst
254254
dst := ReadVec(v, i);
255255
}
256256

257-
function {:inline} $1_vector_$borrow{{S}}(v: Vec ({{T}}), i: int): {{T}} {
257+
function {:inline} $1_vector_borrow{{S}}$pure(v: Vec ({{T}}), i: int): {{T}} {
258258
ReadVec(v, i)
259259
}
260260

@@ -271,10 +271,6 @@ returns (dst: $Mutation ({{T}}), m': $Mutation (Vec ({{T}})))
271271
m' := m;
272272
}
273273

274-
function {:inline} $1_vector_$borrow_mut{{S}}(v: Vec ({{T}}), i: int): {{T}} {
275-
ReadVec(v, i)
276-
}
277-
278274
procedure {:inline 1} $1_vector_destroy_empty{{S}}(v: Vec ({{T}})) {
279275
if (!IsEmptyVec(v)) {
280276
call $ExecFailureAbort();
@@ -774,6 +770,9 @@ procedure {:inline 2} {{impl.fun_borrow}}{{S}}(t: {{Type}}{{S}}, k: {{K}}) retur
774770
v := GetTable(t->$contents, {{ENC}}(k));
775771
}
776772
}
773+
function {:inline} {{impl.fun_borrow}}{{S}}$pure(t: {{Type}}{{S}}, k: {{K}}): {{V}} {
774+
GetTable(t->$contents, {{ENC}}(k))
775+
}
777776
{%- endif %}
778777

779778
{%- if impl.fun_borrow_mut != "" %}
@@ -880,6 +879,9 @@ procedure {:inline 2} {{impl.fun_borrow}}{{DF_S}}(t: {{Type}}, k: {{K}}) returns
880879
v := GetTable(t->$dynamic_fields{{S}}, {{ENC}}(k));
881880
}
882881
}
882+
function {:inline} {{impl.fun_borrow}}{{DF_S}}$pure(t: {{Type}}, k: {{K}}): {{V}} {
883+
GetTable(t->$dynamic_fields{{S}}, {{ENC}}(k))
884+
}
883885
{%- endif %}
884886

885887
{%- if impl.fun_borrow_mut != "" %}

crates/move-stackless-bytecode/src/pure_function_analysis.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use codespan_reporting::diagnostic::Severity;
22
use move_model::model::{FunId, FunctionEnv, GlobalEnv, ModuleId, QualifiedId};
3-
use std::collections::BTreeMap;
3+
use std::collections::BTreeSet;
44

55
use crate::{
66
deterministic_analysis,
@@ -16,10 +16,14 @@ impl PureFunctionAnalysisProcessor {
1616
Box::new(Self())
1717
}
1818

19-
pub fn special_pure_functions_map(env: &GlobalEnv) -> BTreeMap<QualifiedId<FunId>, String> {
20-
let mut special_funcs = BTreeMap::new();
21-
special_funcs.insert(env.std_vector_borrow_qid().unwrap(), "ReadVec".to_string());
22-
special_funcs
19+
pub fn native_pure_variants(env: &GlobalEnv) -> BTreeSet<QualifiedId<FunId>> {
20+
BTreeSet::from([
21+
env.std_vector_borrow_qid().unwrap(),
22+
env.table_borrow_qid().unwrap(),
23+
env.object_table_borrow_qid().unwrap(),
24+
env.dynamic_field_borrow_qid().unwrap(),
25+
env.dynamic_object_field_borrow_qid().unwrap(),
26+
])
2327
}
2428

2529
fn check_function(
@@ -32,7 +36,7 @@ impl PureFunctionAnalysisProcessor {
3236
let func_env = env.get_function(qid);
3337
if targets.is_pure_fun(&func_env.get_qualified_id())
3438
|| env.should_be_used_as_func(&qid)
35-
|| Self::special_pure_functions_map(env).contains_key(&qid)
39+
|| Self::native_pure_variants(env).contains(&qid)
3640
{
3741
return None;
3842
} else {

crates/sui-prover/tests/snapshots/multiple_specs/include_external.fail.move.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ source: crates/sui-prover/tests/integration.rs
33
expression: output
44
---
55
[internal] boogie exited with compilation errors:
6-
output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl(4368,4): Error: call to undeclared procedure: $42_fb_foo
6+
output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl(4364,4): Error: call to undeclared procedure: $42_fb_foo
77
1 name resolution errors detected in output/multiple_specs/include_external.fail/bar_specs_double_foo_imported_module::bar_spec_Assume.bpl

0 commit comments

Comments
 (0)