fn exp_translator_for_context<'module_translator>(
        &'module_translator mut self,
        loc: &Loc,
        context: &SpecBlockContext,
        kind_opt: Option<&ConditionKind>,
        result_as_symbol: bool,
    ) -> ExpTranslator<'env, 'translator, 'module_translator> {
        use SpecBlockContext::*;
        let allow_old = if let Some(kind) = kind_opt {
            kind.allows_old()
        } else {
            false
        };
        match context {
            Function(name) => {
                let entry = &self
                    .parent
                    .fun_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if let Some(kind) = kind_opt {
                    et.enter_scope();
                    for (n, ty) in &entry.params {
                        et.define_local(loc, *n, ty.clone(), None);
                    }
                    // Define the placeholders for the result values of a function if this is an
                    // Ensures condition.
                    if matches!(kind, ConditionKind::Ensures) {
                        et.enter_scope();
                        if let Type::Tuple(ts) = &entry.result_type {
                            for (i, ty) in ts.iter().enumerate() {
                                let name = et.symbol_pool().make(&format!("result_{}", i + 1));
                                let oper = if result_as_symbol {
                                    None
                                } else {
                                    Some(Operation::Result(i))
                                };
                                et.define_local(loc, name, ty.clone(), oper);
                            }
                        } else {
                            let name = et.symbol_pool().make("result");
                            let oper = if result_as_symbol {
                                None
                            } else {
                                Some(Operation::Result(0))
                            };
                            et.define_local(loc, name, entry.result_type.clone(), oper);
                        }
                    }
                }
                et
            }
            FunctionCode(name, spec_info) => {
                let entry = &self
                    .parent
                    .fun_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if kind_opt.is_some() {
                    et.enter_scope();
                    for (n, info) in &spec_info.used_locals {
                        let sym = et.symbol_pool().make(n.0.value.as_str());
                        let ty = et.translate_hlir_single_type(&info.type_);
                        if ty == Type::Error {
                            et.error(
                                loc,
                                "[internal] error in translating hlir type to prover type",
                            );
                        }
                        et.define_local(loc, sym, ty, Some(Operation::Local(sym)));
                    }
                }
                et
            }
            Struct(name) => {
                let entry = &self
                    .parent
                    .struct_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();

                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if kind_opt.is_some() {
                    if let Some(fields) = &entry.fields {
                        et.enter_scope();
                        for (n, (_, ty)) in fields {
                            et.define_local(
                                loc,
                                *n,
                                ty.clone(),
                                Some(Operation::Select(
                                    entry.module_id,
                                    entry.struct_id,
                                    FieldId::new(*n),
                                )),
                            );
                        }
                    }
                }
                et
            }
            Module => {
                if let Some(ConditionKind::InvariantUpdate) = &kind_opt {
                    ExpTranslator::new_with_old(self, true)
                } else {
                    ExpTranslator::new(self)
                }
            }
            Schema(name) => {
                let entry = self
                    .parent
                    .spec_schema_table
                    .get(name)
                    .expect("schema defined");
                // Unfortunately need to clone elements from the entry because we need mut borrow
                // of self for expression translator.
                let type_params = entry.type_params.clone();
                let all_vars = entry.all_vars.clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in type_params {
                    et.define_type_param(loc, n, ty);
                }
                if kind_opt.is_some() {
                    et.enter_scope();
                    for (n, entry) in all_vars {
                        et.define_local(loc, n, entry.type_, None);
                    }
                }
                et
            }
        }
    }
/// Sets up an expression translator for the given spec block context. If kind
/// is given, includes all the symbols which can be consumed by the condition,
/// otherwise only defines type parameters.
Sets up an expression translator for the given spec block context. If kind
is given, includes all the symbols which can be consumed by the condition,
otherwise only defines type parameters.
Sets up an expression translator for the given spec block context . If kind is given includes all the symbols which can be consumed by the condition otherwise only defines type parameters .
fn exp_translator_for_context<'module_translator>(
        &'module_translator mut self,
        loc: &Loc,
        context: &SpecBlockContext,
        kind_opt: Option<&ConditionKind>,
        result_as_symbol: bool,
    ) -> ExpTranslator<'env, 'translator, 'module_translator> {
        use SpecBlockContext::*;
        let allow_old = if let Some(kind) = kind_opt {
            kind.allows_old()
        } else {
            false
        };
        match context {
            Function(name) => {
                let entry = &self
                    .parent
                    .fun_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if let Some(kind) = kind_opt {
                    et.enter_scope();
                    for (n, ty) in &entry.params {
                        et.define_local(loc, *n, ty.clone(), None);
                    }
                    // Define the placeholders for the result values of a function if this is an
                    // Ensures condition.
                    if matches!(kind, ConditionKind::Ensures) {
                        et.enter_scope();
                        if let Type::Tuple(ts) = &entry.result_type {
                            for (i, ty) in ts.iter().enumerate() {
                                let name = et.symbol_pool().make(&format!("result_{}", i + 1));
                                let oper = if result_as_symbol {
                                    None
                                } else {
                                    Some(Operation::Result(i))
                                };
                                et.define_local(loc, name, ty.clone(), oper);
                            }
                        } else {
                            let name = et.symbol_pool().make("result");
                            let oper = if result_as_symbol {
                                None
                            } else {
                                Some(Operation::Result(0))
                            };
                            et.define_local(loc, name, entry.result_type.clone(), oper);
                        }
                    }
                }
                et
            }
            FunctionCode(name, spec_info) => {
                let entry = &self
                    .parent
                    .fun_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if kind_opt.is_some() {
                    et.enter_scope();
                    for (n, info) in &spec_info.used_locals {
                        let sym = et.symbol_pool().make(n.0.value.as_str());
                        let ty = et.translate_hlir_single_type(&info.type_);
                        if ty == Type::Error {
                            et.error(
                                loc,
                                "[internal] error in translating hlir type to prover type",
                            );
                        }
                        et.define_local(loc, sym, ty, Some(Operation::Local(sym)));
                    }
                }
                et
            }
            Struct(name) => {
                let entry = &self
                    .parent
                    .struct_table
                    .get(name)
                    .expect("invalid spec block context")
                    .clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in &entry.type_params {
                    et.define_type_param(loc, *n, ty.clone());
                }
                if kind_opt.is_some() {
                    if let Some(fields) = &entry.fields {
                        et.enter_scope();
                        for (n, (_, ty)) in fields {
                            et.define_local(
                                loc,
                                *n,
                                ty.clone(),
                                Some(Operation::Select(
                                    entry.module_id,
                                    entry.struct_id,
                                    FieldId::new(*n),
                                )),
                            );
                        }
                    }
                }
                et
            }
            Module => {
                if let Some(ConditionKind::InvariantUpdate) = &kind_opt {
                    ExpTranslator::new_with_old(self, true)
                } else {
                    ExpTranslator::new(self)
                }
            }
            Schema(name) => {
                let entry = self
                    .parent
                    .spec_schema_table
                    .get(name)
                    .expect("schema defined");
                // Unfortunately need to clone elements from the entry because we need mut borrow
                // of self for expression translator.
                let type_params = entry.type_params.clone();
                let all_vars = entry.all_vars.clone();
                let mut et = ExpTranslator::new_with_old(self, allow_old);
                for (n, ty) in type_params {
                    et.define_type_param(loc, n, ty);
                }
                if kind_opt.is_some() {
                    et.enter_scope();
                    for (n, entry) in all_vars {
                        et.define_local(loc, n, entry.type_, None);
                    }
                }
                et
            }
        }
    }
fn exp_translator_for_context < ' module_translator > ( & ' module_translator mut self , loc : & Loc , context : & SpecBlockContext , kind_opt : Option < & ConditionKind > , result_as_symbol : bool , ) -> ExpTranslator < ' env , ' translator , ' module_translator > { use SpecBlockContext :: * ; let allow_old = if let Some ( kind ) = kind_opt { kind . allows_old ( ) } else { false } ; match context { Function ( name ) => { let entry = & self . parent . fun_table . get ( name ) . expect ( " " ) . clone ( ) ; let mut et = ExpTranslator :: new_with_old ( self , allow_old ) ; for ( n , ty ) in & entry . type_params { et . define_type_param ( loc , * n , ty . clone ( ) ) ; } if let Some ( kind ) = kind_opt { et . enter_scope ( ) ; for ( n , ty ) in & entry . params { et . define_local ( loc , * n , ty . clone ( ) , None ) ; } // Define the placeholders for the result values of a function if this is an // Ensures condition. if matches ! ( kind ConditionKind Ensures ) { et . enter_scope ( ) ; if let Type :: Tuple ( ts ) = & entry . result_type { for ( i , ty ) in ts . iter ( ) . enumerate ( ) { let name = et . symbol_pool ( ) . make ( & format ! ( " " i 1 ) ) ; let oper = if result_as_symbol { None } else { Some ( Operation :: Result ( i ) ) } ; et . define_local ( loc , name , ty . clone ( ) , oper ) ; } } else { let name = et . symbol_pool ( ) . make ( " " ) ; let oper = if result_as_symbol { None } else { Some ( Operation :: Result ( 0 ) ) } ; et . define_local ( loc , name , entry . result_type . clone ( ) , oper ) ; } } } et } FunctionCode ( name , spec_info ) => { let entry = & self . parent . fun_table . get ( name ) . expect ( " " ) . clone ( ) ; let mut et = ExpTranslator :: new_with_old ( self , allow_old ) ; for ( n , ty ) in & entry . type_params { et . define_type_param ( loc , * n , ty . clone ( ) ) ; } if kind_opt . is_some ( ) { et . enter_scope ( ) ; for ( n , info ) in & spec_info . used_locals { let sym = et . symbol_pool ( ) . make ( n . 0 . value . as_str ( ) ) ; let ty = et . translate_hlir_single_type ( & info . type_ ) ; if ty == Type :: Error { et . error ( loc , " " , ) ; } et . define_local ( loc , sym , ty , Some ( Operation :: Local ( sym ) ) ) ; } } et } Struct ( name ) => { let entry = & self . parent . struct_table . get ( name ) . expect ( " " ) . clone ( ) ; let mut et = ExpTranslator :: new_with_old ( self , allow_old ) ; for ( n , ty ) in & entry . type_params { et . define_type_param ( loc , * n , ty . clone ( ) ) ; } if kind_opt . is_some ( ) { if let Some ( fields ) = & entry . fields { et . enter_scope ( ) ; for ( n , ( _ , ty ) ) in fields { et . define_local ( loc , * n , ty . clone ( ) , Some ( Operation :: Select ( entry . module_id , entry . struct_id , FieldId :: new ( * n ) , ) ) , ) ; } } } et } Module => { if let Some ( ConditionKind :: InvariantUpdate ) = & kind_opt { ExpTranslator :: new_with_old ( self , true ) } else { ExpTranslator :: new ( self ) } } Schema ( name ) => { let entry = self . parent . spec_schema_table . get ( name ) . expect ( " " ) ; // Unfortunately need to clone elements from the entry because we need mut borrow // of self for expression translator. let type_params = entry . type_params . clone ( ) ; let all_vars = entry . all_vars . clone ( ) ; let mut et = ExpTranslator :: new_with_old ( self , allow_old ) ; for ( n , ty ) in type_params { et . define_type_param ( loc , n , ty ) ; } if kind_opt . is_some ( ) { et . enter_scope ( ) ; for ( n , entry ) in all_vars { et . define_local ( loc , n , entry . type_ , None ) ; } } et } } }
Sets up an expression translator for the given spec block context.
Sets up an expression translator for the given spec block context .
&'module_translator mut self
loc
&Loc
context
&SpecBlockContext
kind_opt
Option<&ConditionKind>
result_as_symbol
bool
&'module_translator mut self
loc
&Loc
context
&SpecBlockContext
kind_opt
Option<&ConditionKind>
result_as_symbol
bool