fn verification_analysis(env: &mut GlobalEnv, targets: &FunctionTargetsHolder) {
    let mut target_resources = BTreeSet::new();

    // Collect all resources mentioned in the invariants in target modules
    for module_env in env.get_modules() {
        if !module_env.is_dependency() {
            let module_id = module_env.get_id();
            env.add_module_to_should_translate(module_id);
            propagate_should_translate(env, module_id);
            let mentioned_resources: BTreeSet<QualifiedId<StructId>> = env
                .get_global_invariants_by_module(module_id)
                .iter()
                .flat_map(|id| env.get_global_invariant(*id).unwrap().mem_usage.clone())
                .collect();
            target_resources.extend(mentioned_resources);
        }
    }

    for module_env in env.get_modules() {
        for func_env in module_env.get_functions() {
            if func_env.has_friend() {
                let loc = func_env.get_loc();
                if func_env.is_opaque() {
                    env.error(&loc, "function with a friend cannot be declared as opaque");
                }
                let calling_functions = func_env.get_calling_functions();

                // Construct a set containing all friends of the function in the system.
                // Right now there can be at most one friend.
                let mut friends = BTreeSet::new();
                if let Some(friend_env) = func_env.get_friend_env() {
                    friends.insert(friend_env.get_qualified_id());
                }

                // If the set of callers is not a subset of the friends set,
                // then some non-friend calls the function so generate an error message.
                if !calling_functions.is_subset(&friends) {
                    env.error(&loc, &format!("function `{}` is called by other functions while it can only be called by its friend {}",
                                             func_env.get_name_string(),
                                             func_env.get_friend_name().unwrap())
                    );
                }
            }

            let fun_target = targets.get_annotated_target(&func_env);
            let directly_modified_structs =
                usage_analysis::get_directly_modified_memory(&fun_target);
            // Verify the function if it modifies one of the target resources
            if !directly_modified_structs.is_disjoint(&target_resources) {
                // If the function has a friend, then (1) this functions cannot
                // be verified on its own, and (2) it has to be verified in the
                // context of its friend.
                let friend = func_env.get_transitive_friend();
                let friend_module = &friend.module_env;
                friend_module.add_fun_to_should_verify(friend.get_id());
                env.add_module_to_should_translate(friend_module.get_id());
                propagate_should_translate(env, friend_module.get_id());
            }
        }
    }
}
/// This function analyzes the Move modules to be translated and the Move functions
/// to be verified by doing the following:
/// (1) Go through all invariants in the target modules and gather all resources
///     mentioned in the invariants.
/// (2) Go through all functions in all modules. If a function modifies one of
///     the resources in (1) directly, then
///     (a) Mark the function or its transitive friend(if there exists one) as should_verify and
///     (b) Mark the module owning the function as should_translate.
/// (3) Propagate should_translate to dependency modules.
This function analyzes the Move modules to be translated and the Move functions
to be verified by doing the following:
(1) Go through all invariants in the target modules and gather all resources
mentioned in the invariants.
(2) Go through all functions in all modules. If a function modifies one of
the resources in (1) directly, then
(a) Mark the function or its transitive friend(if there exists one) as should_verify and
(b) Mark the module owning the function as should_translate.
(3) Propagate should_translate to dependency modules.
This function analyzes the Move modules to be translated and the Move functions to be verified by doing the following : ( 1 ) Go through all invariants in the target modules and gather all resources mentioned in the invariants . ( 2 ) Go through all functions in all modules . If a function modifies one of the resources in ( 1 ) directly then ( a ) Mark the function or its transitive friend ( if there exists one ) as should_verify and ( b ) Mark the module owning the function as should_translate . ( 3 ) Propagate should_translate to dependency modules .
fn verification_analysis(env: &mut GlobalEnv, targets: &FunctionTargetsHolder) {
    let mut target_resources = BTreeSet::new();
    // Collect all resources mentioned in the invariants in target modules
    for module_env in env.get_modules() {
        if !module_env.is_dependency() {
            let module_id = module_env.get_id();
            env.add_module_to_should_translate(module_id);
            propagate_should_translate(env, module_id);
            let mentioned_resources: BTreeSet<QualifiedId<StructId>> = env
                .get_global_invariants_by_module(module_id)
                .iter()
                .flat_map(|id| env.get_global_invariant(*id).unwrap().mem_usage.clone())
                .collect();
            target_resources.extend(mentioned_resources);
        }
    }
    for module_env in env.get_modules() {
        for func_env in module_env.get_functions() {
            if func_env.has_friend() {
                let loc = func_env.get_loc();
                if func_env.is_opaque() {
                    env.error(&loc, "function with a friend cannot be declared as opaque");
                }
                let calling_functions = func_env.get_calling_functions();
                // Construct a set containing all friends of the function in the system.
                // Right now there can be at most one friend.
                let mut friends = BTreeSet::new();
                if let Some(friend_env) = func_env.get_friend_env() {
                    friends.insert(friend_env.get_qualified_id());
                }
                // If the set of callers is not a subset of the friends set,
                // then some non-friend calls the function so generate an error message.
                if !calling_functions.is_subset(&friends) {
                    env.error(&loc, &format!("function `{}` is called by other functions while it can only be called by its friend {}",
                                             func_env.get_name_string(),
                                             func_env.get_friend_name().unwrap())
                    );
                }
            }
            let fun_target = targets.get_annotated_target(&func_env);
            let directly_modified_structs =
                usage_analysis::get_directly_modified_memory(&fun_target);
            // Verify the function if it modifies one of the target resources
            if !directly_modified_structs.is_disjoint(&target_resources) {
                // If the function has a friend, then (1) this functions cannot
                // be verified on its own, and (2) it has to be verified in the
                // context of its friend.
                let friend = func_env.get_transitive_friend();
                let friend_module = &friend.module_env;
                friend_module.add_fun_to_should_verify(friend.get_id());
                env.add_module_to_should_translate(friend_module.get_id());
                propagate_should_translate(env, friend_module.get_id());
            }
        }
    }
}
fn verification_analysis ( env : & mut GlobalEnv , targets : & FunctionTargetsHolder ) { let mut target_resources = BTreeSet :: new ( ) ; // Collect all resources mentioned in the invariants in target modules for module_env in env . get_modules ( ) { if ! module_env . is_dependency ( ) { let module_id = module_env . get_id ( ) ; env . add_module_to_should_translate ( module_id ) ; propagate_should_translate ( env , module_id ) ; let mentioned_resources : BTreeSet < QualifiedId < StructId > > = env . get_global_invariants_by_module ( module_id ) . iter ( ) . flat_map ( | id | env . get_global_invariant ( * id ) . unwrap ( ) . mem_usage . clone ( ) ) . collect ( ) ; target_resources . extend ( mentioned_resources ) ; } } for module_env in env . get_modules ( ) { for func_env in module_env . get_functions ( ) { if func_env . has_friend ( ) { let loc = func_env . get_loc ( ) ; if func_env . is_opaque ( ) { env . error ( & loc , " " ) ; } let calling_functions = func_env . get_calling_functions ( ) ; // Construct a set containing all friends of the function in the system. // Right now there can be at most one friend. let mut friends = BTreeSet :: new ( ) ; if let Some ( friend_env ) = func_env . get_friend_env ( ) { friends . insert ( friend_env . get_qualified_id ( ) ) ; } // If the set of callers is not a subset of the friends set, // then some non-friend calls the function so generate an error message. if ! calling_functions . is_subset ( & friends ) { env . error ( & loc , & format ! ( " " func_env get_name_string ( ) func_env get_friend_name ( ) unwrap ( ) ) ) ; } } let fun_target = targets . get_annotated_target ( & func_env ) ; let directly_modified_structs = usage_analysis :: get_directly_modified_memory ( & fun_target ) ; // Verify the function if it modifies one of the target resources if ! directly_modified_structs . is_disjoint ( & target_resources ) { // If the function has a friend, then (1) this functions cannot // be verified on its own, and (2) it has to be verified in the // context of its friend. let friend = func_env . get_transitive_friend ( ) ; let friend_module = & friend . module_env ; friend_module . add_fun_to_should_verify ( friend . get_id ( ) ) ; env . add_module_to_should_translate ( friend_module . get_id ( ) ) ; propagate_should_translate ( env , friend_module . get_id ( ) ) ; } } } }
This function analyzes the Move modules to be translated and the Move functions
to be verified by doing the following:
(1) Go through all invariants in the target modules and gather all resources
mentioned in the invariants.
This function analyzes the Move modules to be translated and the Move functions to be verified by doing the following : ( 1 ) Go through all invariants in the target modules and gather all resources mentioned in the invariants .
env
&mut GlobalEnv
targets
&FunctionTargetsHolder