diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 1b338aa..1d8f662 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -7,7 +7,7 @@ use nac3core::{ }, symbol_resolver::ValueEnum, toplevel::{DefinitionId, GenCall, helper::PRIMITIVE_DEF_IDS}, - typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum} + typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum, VarMap} }; use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef}; @@ -667,7 +667,7 @@ pub fn attributes_writeback( default_value: None }).collect(), ret: ctx.primitives.none, - vars: HashMap::default() + vars: VarMap::default() }; let args: Vec<_> = values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect(); if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, PRIMITIVE_DEF_IDS.int32), args, generator) { diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index a1ae1df..f8f029f 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -16,7 +16,7 @@ use inkwell::{ use itertools::Itertools; use nac3core::codegen::{CodeGenLLVMOptions, CodeGenTargetMachineOptions, gen_func_impl}; use nac3core::toplevel::builtins::get_exn_constructor; -use nac3core::typecheck::typedef::{TypeEnum, Unifier}; +use nac3core::typecheck::typedef::{TypeEnum, Unifier, VarMap}; use nac3parser::{ ast::{ExprKind, Stmt, StmtKind, StrRef}, parser::parse_program, @@ -476,7 +476,7 @@ impl Nac3 { .unwrap(); let fun_signature = - FunSignature { args: vec![], ret: self.primitive.none, vars: HashMap::new() }; + FunSignature { args: vec![], ret: self.primitive.none, vars: VarMap::new() }; let mut store = ConcreteTypeStore::new(); let mut cache = HashMap::new(); let signature = @@ -816,7 +816,7 @@ impl Nac3 { let builtins = vec![ ( "now_mu".into(), - FunSignature { args: vec![], ret: primitive.int64, vars: HashMap::new() }, + FunSignature { args: vec![], ret: primitive.int64, vars: VarMap::new() }, Arc::new(GenCall::new(Box::new(move |ctx, _, _, _, _| { Ok(Some(time_fns.emit_now_mu(ctx))) }))), @@ -830,7 +830,7 @@ impl Nac3 { default_value: None, }], ret: primitive.none, - vars: HashMap::new(), + vars: VarMap::new(), }, Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { let arg_ty = fun.0.args[0].ty; @@ -848,7 +848,7 @@ impl Nac3 { default_value: None, }], ret: primitive.none, - vars: HashMap::new(), + vars: VarMap::new(), }, Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { let arg_ty = fun.0.args[0].ty; diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 6c1130d..ccba682 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -10,7 +10,7 @@ use nac3core::{ }, typecheck::{ type_inferencer::PrimitiveStore, - typedef::{Type, TypeEnum, Unifier}, + typedef::{Type, TypeEnum, Unifier, VarMap}, }, }; use nac3parser::ast::{self, StrRef}; @@ -519,7 +519,7 @@ impl InnerResolver { .iter() .zip(args.iter()) .map(|((id, _), ty)| (*id, *ty)) - .collect::>() + .collect::() }; Ok(Ok((unifier.subst(origin_ty, &subst).unwrap_or(origin_ty), true))) } @@ -722,7 +722,7 @@ impl InnerResolver { assert_eq!(*id, *id_var); (*id, unifier.get_fresh_var_with_range(range, *name, *loc).0) }) - .collect::>(); + .collect::(); return Ok(Ok(unifier.subst(primitives.option, &var_map).unwrap())) } @@ -734,7 +734,7 @@ impl InnerResolver { ))) } }; - let new_var_map: HashMap<_, _> = params.iter().map(|(id, _)| (*id, ty)).collect(); + let new_var_map: VarMap = params.iter().map(|(id, _)| (*id, ty)).collect(); let res = unifier.subst(extracted_ty, &new_var_map).unwrap_or(extracted_ty); Ok(Ok(res)) } @@ -751,7 +751,7 @@ impl InnerResolver { assert_eq!(*id, *id_var); (*id, unifier.get_fresh_var_with_range(range, *name, *loc).0) }) - .collect::>(); + .collect::(); let mut instantiate_obj = || { // loop through non-function fields of the class to get the instantiated value for field in fields { diff --git a/nac3core/src/codegen/concrete_type.rs b/nac3core/src/codegen/concrete_type.rs index 7745160..30de440 100644 --- a/nac3core/src/codegen/concrete_type.rs +++ b/nac3core/src/codegen/concrete_type.rs @@ -3,7 +3,7 @@ use crate::{ toplevel::DefinitionId, typecheck::{ type_inferencer::PrimitiveStore, - typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier}, + typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap}, }, }; @@ -274,7 +274,7 @@ impl ConcreteTypeStore { params: params .iter() .map(|(id, cty)| (*id, self.to_unifier_type(unifier, primitives, *cty, cache))) - .collect::>(), + .collect::(), }, ConcreteTypeEnum::TFunc { args, ret, vars } => TypeEnum::TFunc(FunSignature { args: args @@ -289,7 +289,7 @@ impl ConcreteTypeStore { vars: vars .iter() .map(|(id, cty)| (*id, self.to_unifier_type(unifier, primitives, *cty, cache))) - .collect::>(), + .collect::(), }), ConcreteTypeEnum::TLiteral { values, .. } => TypeEnum::TLiteral { values: values.clone(), diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 360d873..7bc16ee 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -20,7 +20,7 @@ use crate::{ TopLevelDef, }, typecheck::{ - typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier}, + typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap}, magic_methods::{binop_name, binop_assign_name}, }, }; @@ -41,7 +41,7 @@ use super::{CodeGenerator, llvm_intrinsics::call_memcpy_generic, need_sret}; pub fn get_subst_key( unifier: &mut Unifier, obj: Option, - fun_vars: &HashMap, + fun_vars: &VarMap, filter: Option<&Vec>, ) -> String { let mut vars = obj diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 2f6d224..159ac2b 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -25,6 +25,7 @@ use nac3parser::{ use parking_lot::RwLock; use std::collections::{HashMap, HashSet}; use std::sync::Arc; +use crate::typecheck::typedef::VarMap; struct Resolver { id_to_type: HashMap, @@ -111,7 +112,7 @@ fn test_primitives() { FuncArg { name: "b".into(), ty: primitives.int32, default_value: None }, ], ret: primitives.int32, - vars: HashMap::new(), + vars: VarMap::new(), }; let mut store = ConcreteTypeStore::new(); @@ -258,7 +259,7 @@ fn test_simple_call() { let signature = FunSignature { args: vec![FuncArg { name: "a".into(), ty: primitives.int32, default_value: None }], ret: primitives.int32, - vars: HashMap::new(), + vars: VarMap::new(), }; let fun_ty = unifier.add_ty(TypeEnum::TFunc(signature.clone())); let mut store = ConcreteTypeStore::new(); diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 74a79d3..de41ac1 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -8,7 +8,7 @@ use crate::{ toplevel::{DefinitionId, TopLevelDef, type_annotation::TypeAnnotation}, typecheck::{ type_inferencer::PrimitiveStore, - typedef::{Type, TypeEnum, Unifier}, + typedef::{Type, TypeEnum, Unifier, VarMap}, }, }; use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue, StructValue}; @@ -426,7 +426,7 @@ pub fn parse_type_annotation( Ok(unifier.add_ty(TypeEnum::TObj { obj_id, fields, - params: HashMap::default(), + params: VarMap::default(), })) } else { Err(HashSet::from([ @@ -515,7 +515,7 @@ pub fn parse_type_annotation( ), ])) } - let mut subst = HashMap::new(); + let mut subst = VarMap::new(); for (var, ty) in izip!(type_vars.iter(), types.iter()) { let id = if let TypeEnum::TVar { id, .. } = &*unifier.get_ty(*var) { *id diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index 635145d..3b90918 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -10,6 +10,7 @@ use crate::{ symbol_resolver::SymbolValue, toplevel::helper::PRIMITIVE_DEF_IDS, toplevel::numpy::*, + typecheck::typedef::VarMap, }; use inkwell::{ attributes::{Attribute, AttributeLoc}, @@ -56,12 +57,12 @@ pub fn get_exn_constructor( let exn_type = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(class_id), fields: exception_fields.iter().map(|(a, b, c)| (*a, (*b, *c))).collect(), - params: HashMap::default(), + params: VarMap::default(), }); let signature = unifier.add_ty(TypeEnum::TFunc(FunSignature { args: exn_cons_args, ret: exn_type, - vars: HashMap::default(), + vars: VarMap::default(), })); let fun_def = TopLevelDef::Function { name: format!("{name}.__init__"), @@ -100,7 +101,7 @@ pub fn get_exn_constructor( /// * `codegen_callback`: A lambda generating LLVM IR for the implementation of this function. fn create_fn_by_codegen( primitives: &mut (PrimitiveStore, Unifier), - var_map: &HashMap, + var_map: &VarMap, name: &'static str, ret_ty: Type, param_ty: &[(Type, &'static str)], @@ -136,7 +137,7 @@ fn create_fn_by_codegen( /// * `intrinsic_fn`: The fully-qualified name of the LLVM intrinsic function. fn create_fn_by_intrinsic( primitives: &mut (PrimitiveStore, Unifier), - var_map: &HashMap, + var_map: &VarMap, name: &'static str, ret_ty: Type, params: &[(Type, &'static str)], @@ -200,7 +201,7 @@ fn create_fn_by_intrinsic( /// already implied by the C ABI. fn create_fn_by_extern( primitives: &mut (PrimitiveStore, Unifier), - var_map: &HashMap, + var_map: &VarMap, name: &'static str, ret_ty: Type, params: &[(Type, &'static str)], @@ -295,7 +296,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { Some("N".into()), None, ); - let var_map: HashMap<_, _> = vec![(num_ty.1, num_ty.0)].into_iter().collect(); + let var_map: VarMap = vec![(num_ty.1, num_ty.0)].into_iter().collect(); let exception_fields = vec![ ("__name__".into(), int32, true), ("__file__".into(), string, true), @@ -1057,7 +1058,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }, ], ret: range, - vars: HashMap::default(), + vars: VarMap::default(), })), var_id: Vec::default(), instance_to_symbol: HashMap::default(), @@ -1149,7 +1150,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { signature: primitives.1.add_ty(TypeEnum::TFunc(FunSignature { args: vec![FuncArg { name: "s".into(), ty: string, default_value: None }], ret: string, - vars: HashMap::default(), + vars: VarMap::default(), })), var_id: Vec::default(), instance_to_symbol: HashMap::default(), @@ -1971,7 +1972,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { signature: primitives.1.add_ty(TypeEnum::TFunc(FunSignature { args: vec![FuncArg { name: "n".into(), ty: option_ty_var, default_value: None }], ret: primitives.0.option, - vars: HashMap::from([(option_ty_var_id, option_ty_var)]), + vars: VarMap::from([(option_ty_var_id, option_ty_var)]), })), var_id: vec![option_ty_var_id], instance_to_symbol: HashMap::default(), diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 448e05a..c51edae 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -4,7 +4,10 @@ use std::rc::Rc; use crate::{ codegen::{expr::get_subst_key, stmt::exn_constructor}, symbol_resolver::SymbolValue, - typecheck::type_inferencer::{FunctionData, Inferencer}, + typecheck::{ + type_inferencer::{FunctionData, Inferencer}, + typedef::VarMap, + }, }; use super::*; @@ -844,7 +847,7 @@ impl TopLevelComposer { let resolver = resolver.unwrap(); let resolver = &**resolver; - let mut function_var_map: HashMap = HashMap::new(); + let mut function_var_map = VarMap::new(); let arg_types = { // make sure no duplicate parameter let mut defined_parameter_name: HashSet<_> = HashSet::new(); @@ -1082,7 +1085,7 @@ impl TopLevelComposer { let (method_dummy_ty, method_id) = Self::get_class_method_def_info(class_methods_def, *name)?; - let mut method_var_map: HashMap = HashMap::new(); + let mut method_var_map = VarMap::new(); let arg_types: Vec = { // check method parameters cannot have same name @@ -1574,7 +1577,7 @@ impl TopLevelComposer { }, ], ret: self_type, - vars: HashMap::default(), + vars: VarMap::default(), })); let cons_fun = TopLevelDef::Function { name: format!("{}.{}", class_name, "__init__"), @@ -1598,7 +1601,7 @@ impl TopLevelComposer { // get the class constructor type correct let (contor_args, contor_type_vars) = { let mut constructor_args: Vec = Vec::new(); - let mut type_vars: HashMap = HashMap::new(); + let mut type_vars = VarMap::new(); for (name, func_sig, id) in methods { if *name == init_str_id { init_id = Some(*id); @@ -1749,13 +1752,13 @@ impl TopLevelComposer { }) .multi_cartesian_product() .collect_vec(); - let mut result: Vec> = Vec::default(); + let mut result: Vec = Vec::default(); for comb in var_combs { result.push(vars.keys().copied().zip(comb).collect()); } // NOTE: if is empty, means no type var, append a empty subst, ok to do this? if result.is_empty() { - result.push(HashMap::new()); + result.push(VarMap::new()); } (result, no_ranges) }; @@ -1795,7 +1798,7 @@ impl TopLevelComposer { None } }) - .collect::>() + .collect::() }; unifier.subst(self_type, &subst_for_self).unwrap_or(self_type) }) diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index c07c0ab..679b6c1 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -1,7 +1,7 @@ use std::convert::TryInto; use crate::symbol_resolver::SymbolValue; -use crate::typecheck::typedef::Mapping; +use crate::typecheck::typedef::{Mapping, VarMap}; use nac3parser::ast::{Constant, Location}; use super::*; @@ -112,37 +112,37 @@ impl TopLevelComposer { let int32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let int64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let float = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.float, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let bool = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.bool, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let none = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.none, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let range = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.range, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let str = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.str, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let exception = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.exception, @@ -159,29 +159,29 @@ impl TopLevelComposer { ] .into_iter() .collect::>(), - params: HashMap::new(), + params: VarMap::new(), }); let uint32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let uint64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let option_type_var = unifier.get_fresh_var(Some("option_type_var".into()), None); let is_some_type_fun_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![], ret: bool, - vars: HashMap::from([(option_type_var.1, option_type_var.0)]), + vars: VarMap::from([(option_type_var.1, option_type_var.0)]), })); let unwrap_fun_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![], ret: option_type_var.0, - vars: HashMap::from([(option_type_var.1, option_type_var.0)]), + vars: VarMap::from([(option_type_var.1, option_type_var.0)]), })); let option = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.option, @@ -192,7 +192,7 @@ impl TopLevelComposer { ] .into_iter() .collect::>(), - params: HashMap::from([(option_type_var.1, option_type_var.0)]), + params: VarMap::from([(option_type_var.1, option_type_var.0)]), }); let size_t_ty = match size_t { @@ -206,10 +206,10 @@ impl TopLevelComposer { let ndarray = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.ndarray, fields: Mapping::new(), - params: Mapping::from([ + params: VarMap::from([ (ndarray_dtype_tvar.1, ndarray_dtype_tvar.0), (ndarray_ndims_tvar.1, ndarray_ndims_tvar.0), - ]) + ]), }); let primitives = PrimitiveStore { diff --git a/nac3core/src/toplevel/mod.rs b/nac3core/src/toplevel/mod.rs index c204819..1209f51 100644 --- a/nac3core/src/toplevel/mod.rs +++ b/nac3core/src/toplevel/mod.rs @@ -8,7 +8,7 @@ use std::{ use super::codegen::CodeGenContext; use super::typecheck::type_inferencer::PrimitiveStore; -use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier}; +use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier, VarMap}; use crate::{ codegen::CodeGenerator, symbol_resolver::{SymbolResolver, ValueEnum}, @@ -76,7 +76,7 @@ impl Debug for GenCall { pub struct FunInstance { pub body: Arc>>>, pub calls: Arc>, - pub subst: HashMap, + pub subst: VarMap, pub unifier_id: usize, } diff --git a/nac3core/src/toplevel/numpy.rs b/nac3core/src/toplevel/numpy.rs index 2f60930..bc992ef 100644 --- a/nac3core/src/toplevel/numpy.rs +++ b/nac3core/src/toplevel/numpy.rs @@ -19,7 +19,7 @@ use crate::{ toplevel::{DefinitionId, helper::PRIMITIVE_DEF_IDS}, typecheck::{ type_inferencer::PrimitiveStore, - typedef::{FunSignature, Mapping, Type, TypeEnum, Unifier}, + typedef::{FunSignature, Type, TypeEnum, Unifier, VarMap}, }, }; @@ -48,7 +48,7 @@ pub fn make_ndarray_ty( .collect_vec(); debug_assert_eq!(tvar_ids.len(), 2); - let mut tvar_subst = Mapping::new(); + let mut tvar_subst = VarMap::new(); if let Some(dtype) = dtype { tvar_subst.insert(tvar_ids[0], dtype); } diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index 2086cfe..ddcf946 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -415,7 +415,7 @@ pub fn get_type_from_type_annotation_kinds( let subst = { // check for compatible range // TODO: if allow type var to be applied(now this disallowed in the parse_to_type_annotation), need more check - let mut result: HashMap = HashMap::new(); + let mut result = VarMap::new(); for (tvar, p) in type_vars.iter().zip(param_ty) { match unifier.get_ty(*tvar).as_ref() { TypeEnum::TVar { id, range, fields: None, name, loc, is_const_generic: false } => { diff --git a/nac3core/src/typecheck/magic_methods.rs b/nac3core/src/typecheck/magic_methods.rs index 9d92c08..d25fff5 100644 --- a/nac3core/src/typecheck/magic_methods.rs +++ b/nac3core/src/typecheck/magic_methods.rs @@ -1,6 +1,6 @@ use crate::typecheck::{ type_inferencer::*, - typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier}, + typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap}, }; use nac3parser::ast::StrRef; use nac3parser::ast::{Cmpop, Operator, Unaryop}; @@ -102,9 +102,9 @@ pub fn impl_binop( }; let function_vars = if let Some(var_id) = other_var_id { - vec![(var_id, other_ty)].into_iter().collect::>() + vec![(var_id, other_ty)].into_iter().collect::() } else { - HashMap::new() + VarMap::new() }; for op in ops { @@ -149,7 +149,7 @@ pub fn impl_unaryop(unifier: &mut Unifier, ty: Type, ret_ty: Type, ops: &[Unaryo ( unifier.add_ty(TypeEnum::TFunc(FunSignature { ret: ret_ty, - vars: HashMap::new(), + vars: VarMap::new(), args: vec![], })), false, @@ -173,7 +173,7 @@ pub fn impl_cmpop( ( unifier.add_ty(TypeEnum::TFunc(FunSignature { ret: store.bool, - vars: HashMap::new(), + vars: VarMap::new(), args: vec![FuncArg { ty: other_ty, default_value: None, diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index e379056..a6b72bb 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -3,7 +3,7 @@ use std::convert::{From, TryInto}; use std::iter::once; use std::{cell::RefCell, sync::Arc}; -use super::typedef::{Call, FunSignature, FuncArg, RecordField, Type, TypeEnum, Unifier}; +use super::typedef::{Call, FunSignature, FuncArg, RecordField, Type, TypeEnum, Unifier, VarMap}; use super::{magic_methods::*, typedef::CallId}; use crate::{ symbol_resolver::{SymbolResolver, SymbolValue}, @@ -425,13 +425,13 @@ impl<'a> Fold<()> for Inferencer<'a> { || self.unifier.get_dummy_var().0, |var| var.custom.unwrap(), ), - vars: HashMap::default(), + vars: VarMap::default(), }); let enter = self.unifier.add_ty(enter); let exit = TypeEnum::TFunc(FunSignature { args: vec![], ret: self.unifier.get_dummy_var().0, - vars: HashMap::default(), + vars: VarMap::default(), }); let exit = self.unifier.add_ty(exit); let mut fields = HashMap::new(); @@ -503,7 +503,7 @@ impl<'a> Fold<()> for Inferencer<'a> { assert_eq!(*id, *id_var); (*id, self.unifier.get_fresh_var_with_range(range, *name, *loc).0) }) - .collect::>(); + .collect::(); Some(self.unifier.subst(self.primitives.option, &var_map).unwrap()) } else { unreachable!("must be tobj") @@ -704,7 +704,7 @@ impl<'a> Inferencer<'a> { .map(|(k, ty)| FuncArg { name: *k, ty: *ty, default_value: None }) .collect(), ret, - vars: HashMap::default(), + vars: VarMap::default(), }; let body = new_context.fold_expr(body)?; new_context.unify(fun.ret, body.custom.unwrap(), &location)?; @@ -939,7 +939,7 @@ impl<'a> Inferencer<'a> { }, ], ret, - vars: HashMap::new(), + vars: VarMap::new(), })); return Ok(Some(Located { @@ -996,7 +996,7 @@ impl<'a> Inferencer<'a> { }, ], ret, - vars: HashMap::new(), + vars: VarMap::new(), })); return Ok(Some(Located { diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index 44747b7..8c72cfb 100644 --- a/nac3core/src/typecheck/type_inferencer/test.rs +++ b/nac3core/src/typecheck/type_inferencer/test.rs @@ -75,70 +75,70 @@ impl TestEnvironment { let int32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); with_fields(&mut unifier, int32, |unifier, fields| { let add_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![FuncArg { name: "other".into(), ty: int32, default_value: None }], ret: int32, - vars: HashMap::new(), + vars: VarMap::new(), })); fields.insert("__add__".into(), (add_ty, false)); }); let int64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let float = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.float, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let bool = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.bool, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let none = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.none, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let range = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.range, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let str = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.str, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let exception = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.exception, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let uint32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let uint64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let option = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.option, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let ndarray = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.ndarray, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let primitives = PrimitiveStore { int32, @@ -208,70 +208,70 @@ impl TestEnvironment { let int32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); with_fields(&mut unifier, int32, |unifier, fields| { let add_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![FuncArg { name: "other".into(), ty: int32, default_value: None }], ret: int32, - vars: HashMap::new(), + vars: VarMap::new(), })); fields.insert("__add__".into(), (add_ty, false)); }); let int64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.int64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let float = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.float, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let bool = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.bool, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let none = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.none, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let range = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.range, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let str = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.str, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let exception = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.exception, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let uint32 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint32, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let uint64 = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.uint64, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let option = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.option, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); let ndarray = unifier.add_ty(TypeEnum::TObj { obj_id: PRIMITIVE_DEF_IDS.ndarray, fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }); identifier_mapping.insert("None".into(), none); for (i, name) in ["int32", "int64", "float", "bool", "none", "range", "str", "Exception"] @@ -318,7 +318,7 @@ impl TestEnvironment { let foo_ty = unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(defs + 1), fields: [("a".into(), (v0, true))].iter().cloned().collect::>(), - params: [(id, v0)].iter().cloned().collect::>(), + params: [(id, v0)].iter().cloned().collect::(), }); top_level_defs.push( RwLock::new(TopLevelDef::Class { diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index 5cb99b9..c3c1c75 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -1,5 +1,5 @@ use std::cell::RefCell; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::fmt::Display; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -25,7 +25,14 @@ pub type Type = UnificationKey; pub struct CallId(pub(super) usize); pub type Mapping = HashMap; -type VarMap = Mapping; + +/// A [`Mapping`] sorted by its key. +/// +/// This type is recommended for mappings that should be stored and/or iterated by its sorted key. +pub type SortedMapping = BTreeMap; + +/// A [`BTreeMap`] storing the mapping between type variable ID and [unifier type][`Type`]. +pub type VarMap = SortedMapping; #[derive(Clone)] pub struct Call { @@ -1276,12 +1283,12 @@ impl Unifier { fn subst_map( &mut self, - map: &Mapping, + map: &SortedMapping, mapping: &VarMap, cache: &mut HashMap>, - ) -> Option> + ) -> Option> where - K: std::hash::Hash + Eq + Clone, + K: Ord + Eq + Clone, { let mut map2 = None; for (k, v) in map { diff --git a/nac3core/src/typecheck/typedef/test.rs b/nac3core/src/typecheck/typedef/test.rs index 4ebf2e1..24eece9 100644 --- a/nac3core/src/typecheck/typedef/test.rs +++ b/nac3core/src/typecheck/typedef/test.rs @@ -45,9 +45,9 @@ impl Unifier { } } - fn map_eq(&mut self, map1: &Mapping, map2: &Mapping) -> bool + fn map_eq(&mut self, map1: &SortedMapping, map2: &SortedMapping) -> bool where - K: std::hash::Hash + Eq + Clone, + K: Ord + Eq + Clone, { if map1.len() != map2.len() { return false; @@ -91,7 +91,7 @@ impl TestEnvironment { unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(0), fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }), ); type_mapping.insert( @@ -99,7 +99,7 @@ impl TestEnvironment { unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(1), fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }), ); type_mapping.insert( @@ -107,7 +107,7 @@ impl TestEnvironment { unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(2), fields: HashMap::new(), - params: HashMap::new(), + params: VarMap::new(), }), ); let (v0, id) = unifier.get_dummy_var(); @@ -116,7 +116,7 @@ impl TestEnvironment { unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(3), fields: [("a".into(), (v0, true))].iter().cloned().collect::>(), - params: [(id, v0)].iter().cloned().collect::>(), + params: [(id, v0)].iter().cloned().collect::(), }), ); @@ -363,7 +363,7 @@ fn test_virtual() { let fun = env.unifier.add_ty(TypeEnum::TFunc(FunSignature { args: vec![], ret: int, - vars: HashMap::new(), + vars: VarMap::new(), })); let bar = env.unifier.add_ty(TypeEnum::TObj { obj_id: DefinitionId(5), @@ -371,7 +371,7 @@ fn test_virtual() { .iter() .cloned() .collect::>(), - params: HashMap::new(), + params: VarMap::new(), }); let v0 = env.unifier.get_dummy_var().0; let v1 = env.unifier.get_dummy_var().0; diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index 8973cf3..f11acd1 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -17,12 +17,14 @@ use nac3core::{ }, symbol_resolver::SymbolResolver, toplevel::{ - composer::TopLevelComposer, helper::parse_parameter_default_value, type_annotation::*, + composer::{ComposerConfig, TopLevelComposer}, + helper::parse_parameter_default_value, + type_annotation::*, TopLevelDef, }, typecheck::{ type_inferencer::PrimitiveStore, - typedef::{FunSignature, Type, Unifier}, + typedef::{FunSignature, Type, Unifier, VarMap}, }, }; use nac3parser::{ @@ -32,7 +34,6 @@ use nac3parser::{ mod basic_symbol_resolver; use basic_symbol_resolver::*; -use nac3core::toplevel::composer::ComposerConfig; /// Command-line argument parser definition. #[derive(Parser)] @@ -345,7 +346,7 @@ fn main() { } } - let signature = FunSignature { args: vec![], ret: primitive.int32, vars: HashMap::new() }; + let signature = FunSignature { args: vec![], ret: primitive.int32, vars: VarMap::new() }; let mut store = ConcreteTypeStore::new(); let mut cache = HashMap::new(); let signature = store.from_signature(&mut composer.unifier, &primitive, &signature, &mut cache);