Skip to content

Commit 70db079

Browse files
committed
[move-prover] Fix a bug in treatment of type reflection in spec funs
When calling a generic function in a specification expression which transitively uses type reflection, the function call type instantiation wasn't correctly treated for the type info parameters. The refined test generates this situation and failed before but passes now. Removes the boogie compilation error in #15605, but after this the example in this bug times out, even though the package does not contain any specs. I verified that all verification conditions belong to functions in this package, but this does not change this. Should be fixed in subsequent PR before closing the bug.
1 parent 7ccbfaf commit 70db079

File tree

6 files changed

+36
-14
lines changed

6 files changed

+36
-14
lines changed

third_party/move/move-model/src/model.rs

+11
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,17 @@ impl GlobalEnv {
885885
target_modules
886886
}
887887

888+
/// Find all primary target modules and return in a vector
889+
pub fn get_primary_target_modules(&self) -> Vec<ModuleEnv> {
890+
let mut target_modules: Vec<ModuleEnv> = vec![];
891+
for module_env in self.get_modules() {
892+
if module_env.is_primary_target() {
893+
target_modules.push(module_env);
894+
}
895+
}
896+
target_modules
897+
}
898+
888899
fn add_backtrace(msg: &str, _is_bug: bool) -> String {
889900
// Note that you need both MOVE_COMPILER_BACKTRACE=1 and RUST_BACKTRACE=1 for this to
890901
// actually generate a backtrace.

third_party/move/move-prover/boogie-backend/src/spec_translator.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,13 @@ impl<'env> SpecTranslator<'env> {
316316
let type_info_params = if type_reflection {
317317
(0..fun.type_params.len())
318318
.map(|i| {
319-
format!(
320-
"{}_info: $TypeParamInfo",
321-
boogie_type(self.env, &Type::TypeParameter(i as u16))
322-
)
319+
// Apply type instantiation if present
320+
let ty = self
321+
.type_inst
322+
.get(i)
323+
.cloned()
324+
.unwrap_or_else(|| Type::TypeParameter(i as u16));
325+
format!("{}_info: $TypeParamInfo", boogie_type(self.env, &ty))
323326
})
324327
.collect_vec()
325328
} else {
@@ -1156,11 +1159,7 @@ impl<'env> SpecTranslator<'env> {
11561159
{
11571160
for i in 0..fun_decl.type_params.len() {
11581161
maybe_comma();
1159-
emit!(
1160-
self.writer,
1161-
"{}_info",
1162-
boogie_type(self.env, &Type::TypeParameter(i as u16))
1163-
)
1162+
emit!(self.writer, "{}_info", boogie_type(self.env, &inst[i]))
11641163
}
11651164
}
11661165
// Add memory parameters.

third_party/move/move-prover/bytecode-pipeline/src/verification_analysis.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl FunctionTargetProcessor for VerificationAnalysisProcessor {
9696

9797
// Rule 2: verify the function if it is within the target modules
9898
let env = fun_env.module_env.env;
99-
let target_modules = env.get_target_modules();
99+
let target_modules = env.get_primary_target_modules();
100100

101101
let is_in_target_module = target_modules
102102
.iter()
@@ -162,7 +162,7 @@ impl FunctionTargetProcessor for VerificationAnalysisProcessor {
162162

163163
writeln!(f, "invariant applicability: [")?;
164164
let target_invs: BTreeSet<_> = env
165-
.get_target_modules()
165+
.get_primary_target_modules()
166166
.iter()
167167
.flat_map(|menv| env.get_global_invariants_by_module(menv.get_id()))
168168
.collect();

third_party/move/move-prover/bytecode-pipeline/src/verification_analysis_v2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ impl FunctionTargetProcessor for VerificationAnalysisProcessorV2 {
661661
_ => {},
662662
}
663663

664-
let target_modules = global_env.get_target_modules();
664+
let target_modules = global_env.get_primary_target_modules();
665665
let target_fun_ids: BTreeSet<QualifiedId<FunId>> = target_modules
666666
.iter()
667667
.flat_map(|mod_env| mod_env.get_functions())

third_party/move/move-prover/tests/sources/functional/type_reflection.move

+13-1
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,24 @@ module 0x42::test {
110110
type_info::type_of<A>()
111111
}
112112
spec generic_type_info_verification_target {
113-
ensures result == generic_type_info_spec_fun<A>();
113+
ensures result == generic_type_info_spec_fun<A>()
114+
&& result == generic_type_info_spec_fun_2<A>();
114115
}
115116

116117
spec fun generic_type_info_spec_fun<A>(): type_info::TypeInfo {
117118
type_info::type_of<A>()
118119
}
120+
121+
spec fun generic_type_info_spec_fun_2<A>(): type_info::TypeInfo {
122+
takes_2<A, A>()
123+
}
124+
125+
spec fun takes_2<A, B>(): type_info::TypeInfo {
126+
// Pass on the 2nd type parameter to be sure the instantiation
127+
// of B is correctly handled
128+
type_info::type_of<B>()
129+
}
130+
119131
}
120132

121133
module 0x43::test {

third_party/move/tools/move-cli/src/base/prove.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub fn run_move_prover(
230230
} else {
231231
"FAILURE".bold().red()
232232
},
233-
model.get_target_modules().len(),
233+
model.get_primary_target_modules().len(),
234234
basedir,
235235
now.elapsed().as_secs_f64()
236236
)?;

0 commit comments

Comments
 (0)