# HG changeset patch # User Simon Heath # Date 1689713913 14400 # Tue Jul 18 16:58:33 2023 -0400 # Branch devel # Node ID beacbe9526376132d12d923176db96dec40199c8 # Parent 30675ced262ab3fbe0574f7724840b655f291ed1 Revert commit 24722db3fc92 Rc'ing types instead of cloning does improve performance of passes and other tree-manip-stuff by roughly 10%, but is inconvenient enough that it's prolly not worth it. Interning them would work better and also be easier since it'd make all our types Copy. But that attempt also had a bit of nice code cleanup in it, so I've tried to preserve it. diff --git a/benches/basic.rs b/benches/basic.rs --- a/benches/basic.rs +++ b/benches/basic.rs @@ -66,7 +66,7 @@ buf } -fn bench_with_rust_backend(c: &mut Criterion) { +fn bench_compile(c: &mut Criterion) { let code = gen_dumb_test_code(103); let lines = code.lines().count(); let name = format!("compile {}ish lines to Rust", lines); @@ -81,7 +81,6 @@ b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Rust)) }); - /* let code = gen_dumb_test_code(103 * 16); let lines = code.lines().count(); let name = format!("compile {}ish lines", lines); @@ -94,30 +93,6 @@ ) }) }); - */ -} - -fn bench_with_null_backend(c: &mut Criterion) { - let code = gen_dumb_test_code(103); - let lines = code.lines().count(); - let name = format!("compile {}ish lines to nothing", lines); - c.bench_function(&name, |b| { - b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Null)) - }); - - let code = gen_dumb_test_code(103 * 8); - let lines = code.lines().count(); - let name = format!("compile {}ish lines to nothing", lines); - c.bench_function(&name, |b| { - b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Null)) - }); - - let code = gen_dumb_test_code(103 * 16); - let lines = code.lines().count(); - let name = format!("compile {}ish lines to nothing", lines); - c.bench_function(&name, |b| { - b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Rust)) - }); } fn bench_stages(c: &mut Criterion) { @@ -161,15 +136,14 @@ }); let hir = passes::run_typechecked_passes(hir, tck); - c.bench_function("codegen", |b| { + c.bench_function("codegen to Rust", |b| { b.iter(|| backend::output(backend::Backend::Rust, black_box(&hir), black_box(tck))) }); + + c.bench_function("codegen to null", |b| { + b.iter(|| backend::output(backend::Backend::Null, black_box(&hir), black_box(tck))) + }); } -criterion_group!( - benches, - //bench_with_rust_backend, - //bench_with_null_backend, - bench_stages -); +criterion_group!(benches, bench_compile, bench_stages); criterion_main!(benches); diff --git a/src/ast.rs b/src/ast.rs --- a/src/ast.rs +++ b/src/ast.rs @@ -96,11 +96,11 @@ #[derive(Debug, Clone, PartialEq)] pub struct Signature { /// Parameters - pub params: Arc>, + pub params: Vec<(Sym, Type)>, /// Return type pub rettype: Type, /// Type parameters - pub typeparams: Arc>, + pub typeparams: Vec, } impl Signature { @@ -108,8 +108,8 @@ pub fn to_type(&self) -> Type { let paramtypes = self.params.iter().map(|(_nm, ty)| ty.clone()).collect(); Type::Func( - Arc::new(paramtypes), - Arc::new(self.rettype.clone()), + paramtypes, + Box::new(self.rettype.clone()), self.typeparams.clone(), ) } @@ -150,14 +150,14 @@ let new_params = self .params .iter() - .zip(params.as_ref()) + .zip(params) .map(|((nm, _t1), t2)| (*nm, t2.clone())) .collect(); let new_rettype = rettype.clone(); let new_type_params = typeparams.clone(); Self { - params: Arc::new(new_params), - rettype: new_rettype.as_ref().clone(), + params: new_params, + rettype: *new_rettype, typeparams: new_type_params, } } diff --git a/src/backend/rust.rs b/src/backend/rust.rs --- a/src/backend/rust.rs +++ b/src/backend/rust.rs @@ -44,7 +44,7 @@ Named(s, types) if s == &Sym::new("Tuple") => { trace!("Compiling tuple {:?}...", t); let mut accm = String::from("("); - for typ in &**types { + for typ in types { accm += &compile_typename(typ); accm += ", "; } @@ -68,7 +68,7 @@ } */ accm += "("; - for p in &**params { + for p in params { accm += &compile_typename(p); accm += ", "; } @@ -149,7 +149,7 @@ /// Driver that turns a pile of Ir into Rust code. pub(super) fn output(lir: &hir::Ir, tck: &Tck) -> Vec { let mut output = Vec::new(); - for builtin in &*builtins::all() { + for builtin in &*builtins::BUILTINS { output.extend(builtin.code[&backend::Backend::Rust].as_bytes()); } for decl in lir.decls.iter() { @@ -223,7 +223,7 @@ params.iter().map(|sym| (*sym.val()).clone()).collect(); let args = param_strings.join(", "); writeln!(w, "pub enum {}<{}> {{ ", nstr, args)?; - for (nm, ty) in &**body { + for (nm, ty) in body { writeln!(w, " {} ({}),", nm, compile_typename(ty))?; } writeln!(w, "}}")?; diff --git a/src/bin/garnetfmt.rs b/src/bin/garnetfmt.rs --- a/src/bin/garnetfmt.rs +++ b/src/bin/garnetfmt.rs @@ -39,6 +39,7 @@ // anything let formatted_data = &formatted_src.into_inner(); let formatted_str = String::from_utf8_lossy(formatted_data); + println!("{}", formatted_str); let formatted_ast = { let mut parser = parser::Parser::new(filename, &formatted_str); parser.parse() diff --git a/src/builtins.rs b/src/builtins.rs --- a/src/builtins.rs +++ b/src/builtins.rs @@ -6,6 +6,8 @@ use std::collections::BTreeMap; +use once_cell::sync::Lazy; + use crate::backend::Backend; use crate::*; @@ -20,6 +22,8 @@ pub code: BTreeMap, } +pub static BUILTINS: Lazy> = Lazy::new(Builtin::all); + impl Builtin { /// Generate all appropriate methods for the given numeric type. /// Right now we just stick em in the toplevel with constructed names, @@ -104,99 +108,99 @@ vec![ Builtin { name: Sym::new(format!("__println_{name}")), - sig: Type::function(&vec![ty.clone()], &Type::unit(), &vec![]), + sig: Type::Func(vec![ty.clone()], Box::new(Type::unit()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, println)]), }, Builtin { name: Sym::new(format!("__band_{name}")), - sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, band)]), }, Builtin { name: Sym::new(format!("__bor_{name}")), - sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bor)]), }, Builtin { name: Sym::new(format!("__bxor_{name}")), - sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bxor)]), }, Builtin { name: Sym::new(format!("__bnot_{name}")), - sig: Type::function(&vec![ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bnot)]), }, Builtin { name: Sym::new(format!("__rshift_{name}")), - sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, rshift)]), }, Builtin { name: Sym::new(format!("__lshift_{name}")), - sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, lshift)]), }, Builtin { name: Sym::new(format!("__rol_{name}")), - sig: Type::function(&vec![ty.clone(), Type::i32()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), Type::i32()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, rol)]), }, Builtin { name: Sym::new(format!("__ror_{name}")), - sig: Type::function(&vec![ty.clone(), Type::i32()], &ty.clone(), &vec![]), + sig: Type::Func(vec![ty.clone(), Type::i32()], Box::new(ty.clone()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, ror)]), }, Builtin { name: Sym::new(format!("__{name}_to_i32")), - sig: Type::function(&vec![ty.clone()], &Type::i32(), &vec![]), + sig: Type::Func(vec![ty.clone()], Box::new(Type::i32()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, cast_i32)]), }, Builtin { name: Sym::new(format!("__{name}_to_u32")), - sig: Type::function(&vec![ty.clone()], &Type::u32(), &vec![]), + sig: Type::Func(vec![ty.clone()], Box::new(Type::u32()), vec![]), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, cast_u32)]), }, ] } -} -/// A function that returns all the compiler builtin info. Just -/// use the `BUILTINS` global instead, this is basically here -/// to initialize it. -pub fn all() -> Vec { - let rust_println = r#"fn __println(x: i32) { + /// A function that returns all the compiler builtin info. Just + /// use the `BUILTINS` global instead, this is basically here + /// to initialize it. + fn all() -> Vec { + let rust_println = r#"fn __println(x: i32) { println!("{}", x); }"#; - let rust_println_bool = r#" + let rust_println_bool = r#" fn __println_bool(x: bool) { println!("{}", x); }"#; - let mut funcs = vec![ - Builtin { - name: Sym::new("__println"), - sig: Type::function(&vec![Type::i32()], &Type::unit(), &vec![]), - code: BTreeMap::from([ - (Backend::Null, "".into()), - (Backend::Rust, rust_println.into()), - ]), - }, - Builtin { - name: Sym::new("__println_bool"), - sig: Type::function(&vec![Type::bool()], &Type::unit(), &vec![]), - code: BTreeMap::from([ - (Backend::Null, "".into()), - (Backend::Rust, rust_println_bool.into()), - ]), - }, - ]; - funcs.extend(Builtin::generate_numerics_for("i8", Type::i8())); - funcs.extend(Builtin::generate_numerics_for("i16", Type::i16())); - funcs.extend(Builtin::generate_numerics_for("i32", Type::i32())); - funcs.extend(Builtin::generate_numerics_for("i64", Type::i64())); - funcs.extend(Builtin::generate_numerics_for("u8", Type::u8())); - funcs.extend(Builtin::generate_numerics_for("u16", Type::u16())); - funcs.extend(Builtin::generate_numerics_for("u32", Type::u32())); - funcs.extend(Builtin::generate_numerics_for("u64", Type::u64())); - funcs + let mut funcs = vec![ + Builtin { + name: Sym::new("__println"), + sig: Type::Func(vec![Type::i32()], Box::new(Type::unit()), vec![]), + code: BTreeMap::from([ + (Backend::Null, "".into()), + (Backend::Rust, rust_println.into()), + ]), + }, + Builtin { + name: Sym::new("__println_bool"), + sig: Type::Func(vec![Type::bool()], Box::new(Type::unit()), vec![]), + code: BTreeMap::from([ + (Backend::Null, "".into()), + (Backend::Rust, rust_println_bool.into()), + ]), + }, + ]; + funcs.extend(Self::generate_numerics_for("i8", Type::i8())); + funcs.extend(Self::generate_numerics_for("i16", Type::i16())); + funcs.extend(Self::generate_numerics_for("i32", Type::i32())); + funcs.extend(Self::generate_numerics_for("i64", Type::i64())); + funcs.extend(Self::generate_numerics_for("u8", Type::u8())); + funcs.extend(Self::generate_numerics_for("u16", Type::u16())); + funcs.extend(Self::generate_numerics_for("u32", Type::u32())); + funcs.extend(Self::generate_numerics_for("u64", Type::u64())); + funcs + } } diff --git a/src/hir.rs b/src/hir.rs --- a/src/hir.rs +++ b/src/hir.rs @@ -768,10 +768,10 @@ let struct_signature = ts .iter() //.map(|(enumname, _enumval)| (*enumname, ty.clone())) - .map(|(enumname, _enumval)| (*enumname, Type::Named(name, Arc::new(vec![])))) + .map(|(enumname, _enumval)| (*enumname, Type::Named(name, vec![]))) .collect(); // Enums cannot have type parameters, so this works. - let init_type = Type::Struct(Arc::new(struct_signature), Arc::new(vec![])); + let init_type = Type::Struct(struct_signature, vec![]); let new_constdef = Const { name, typ: init_type, @@ -798,7 +798,7 @@ .map(|(variant_name, variant_type)| { let paramname = Sym::new("x"); let signature = ast::Signature { - params: Arc::new(vec![(paramname, variant_type.clone())]), + params: vec![(paramname, variant_type.clone())], rettype: Type::Named(name, generics.clone()), typeparams: generics.clone(), }; @@ -822,15 +822,15 @@ // `fn(variant_type) name` ( *variant_name, - Type::function( - &[variant_type.clone()], - &Type::Named(name, generics.clone()), - &generics, + Type::Func( + vec![variant_type.clone()], + Box::new(Type::Named(name, generics.clone())), + generics.clone(), ), ) }) .collect(); - let struct_type = Type::Struct(Arc::new(struct_typebody), generics.clone()); + let struct_type = Type::Struct(struct_typebody, generics.clone()); let new_constdef = Const { name: name.to_owned(), typ: struct_type, @@ -843,10 +843,9 @@ other => { let s = Sym::new("x"); trace!("Lowering params {:?}", params); - let type_params: Arc> = - Arc::new(params.iter().map(|s| Type::Generic(*s)).collect()); + let type_params: Vec<_> = params.iter().map(|s| Type::Generic(*s)).collect(); let signature = ast::Signature { - params: Arc::new(vec![(s, other.clone())]), + params: vec![(s, other.clone())], rettype: Type::Named(name.to_owned(), type_params.clone()), typeparams: type_params.clone(), }; @@ -854,7 +853,7 @@ // in a type constructor let body = vec![ExprNode::new(Expr::TypeCtor { name, - type_params: type_params.to_vec(), + type_params, body: ExprNode::new(Expr::Var { name: s }), })]; //println!("{} is {:#?}", variant_name, e); diff --git a/src/lib.rs b/src/lib.rs --- a/src/lib.rs +++ b/src/lib.rs @@ -74,26 +74,26 @@ /// Never type, the type of an infinite loop Never, /// A C-like enum, and the integer values it corresponds to - Enum(Arc>), + Enum(Vec<(Sym, i32)>), /// A nominal type of some kind; may be built-in (like Tuple) /// or user-defined. - Named(Sym, Arc>), + Named(Sym, Vec), /// A function pointer. /// /// The contents are arg types, return types, type parameters - Func(Arc>, Arc, Arc>), + Func(Vec, Box, Vec), /// An anonymous struct. The vec is type parameters. - Struct(Arc>, Arc>), + Struct(BTreeMap, Vec), /// Sum type. /// /// Like structs, contains a list of type parameters. - Sum(Arc>, Arc>), + Sum(BTreeMap, Vec), /// Arrays are just a type and a number. - Array(Arc, usize), + Array(Box, usize), /// A generic type parameter that has been given an explicit name. Generic(Sym), /// Unique borrow - Uniq(Arc), + Uniq(Box), } impl Type { @@ -126,18 +126,18 @@ helper(rettype, accm) } Type::Struct(body, generics) => { - for (_, ty) in &**body { + for (_, ty) in body { helper(ty, accm); } - for g in &**generics { + for g in generics { helper(g, accm); } } Type::Sum(body, generics) => { - for (_, ty) in &**body { + for (_, ty) in body { helper(ty, accm); } - for g in &**generics { + for g in generics { helper(g, accm); } } @@ -238,29 +238,29 @@ /// Shortcut for getting the type for Unit pub fn unit() -> Self { - Self::Named(Sym::new("Tuple"), Arc::new(vec![])) + Self::Named(Sym::new("Tuple"), vec![]) } /// Shortcut for getting the type for Never pub fn never() -> Self { - Self::Named(Sym::new("Never"), Arc::new(vec![])) + Self::Named(Sym::new("Never"), vec![]) } /// Create a Tuple with the given values - pub fn tuple(args: Arc>) -> Self { + pub fn tuple(args: Vec) -> Self { Self::Named(Sym::new("Tuple"), args) } /// Used in some tests pub fn array(t: &Type, len: usize) -> Self { - Self::Array(Arc::new(t.clone()), len) + Self::Array(Box::new(t.clone()), len) } fn function(params: &[Type], rettype: &Type, generics: &[Type]) -> Self { Type::Func( - Arc::new(Vec::from(params)), - Arc::new(rettype.clone()), - Arc::new(Vec::from(generics)), + Vec::from(params), + Box::new(rettype.clone()), + Vec::from(generics), ) } @@ -446,11 +446,11 @@ if !body1.keys().eq(body2.keys()) { panic!("subst for sum type had non-matching keys") } - for ((_nm1, t1), (_nm2, t2)) in (&**body1).iter().zip(&**body2) { + for ((_nm1, t1), (_nm2, t2)) in body1.iter().zip(body2) { t1._find_substs(t2, substitutions); } - for (p1, p2) in (&**generics1).iter().zip(&**generics2) { + for (p1, p2) in (&**generics1).iter().zip(generics2) { p1._find_substs(p2, substitutions); } } @@ -488,15 +488,11 @@ if typeparams1.len() > 0 { todo!("Hsfjkdslfjs"); } - Type::Func( - Arc::new(new_params), - Arc::new(new_rettype), - Arc::new(vec![]), - ) + Type::Func(new_params, Box::new(new_rettype), vec![]) } Type::Named(n1, args1) => { let new_args = args1.iter().map(|p1| p1._apply_substs(substs)).collect(); - Type::Named(*n1, Arc::new(new_args)) + Type::Named(*n1, new_args) } Type::Struct(_, _) => unreachable!("see other unreachable in substitute()"), Type::Sum(body, generics) => { @@ -505,9 +501,9 @@ .map(|(nm, ty)| (*nm, ty._apply_substs(substs))) .collect(); let new_generics = generics.iter().map(|p1| p1._apply_substs(substs)).collect(); - Type::Sum(Arc::new(new_body), Arc::new(new_generics)) + Type::Sum(new_body, new_generics) } - Type::Array(body, len) => Type::Array(Arc::new(body._apply_substs(substs)), *len), + Type::Array(body, len) => Type::Array(Box::new(body._apply_substs(substs)), *len), Type::Generic(nm) => substs .get(&nm) .unwrap_or_else(|| panic!("No substitution found for generic named {}!", nm)) diff --git a/src/parser.rs b/src/parser.rs --- a/src/parser.rs +++ b/src/parser.rs @@ -706,9 +706,9 @@ let (params, typeparams) = self.parse_fn_args(); let rettype = self.try_parse_type().unwrap_or(Type::unit()); ast::Signature { - params: Arc::new(params), + params, rettype, - typeparams: Arc::new(typeparams), + typeparams, } } @@ -890,19 +890,19 @@ } }); self.expect(T::RBrace); - Some(Type::tuple(Arc::new(body))) + Some(Type::tuple(body)) } fn try_parse_struct_type(&mut self) -> Option { let (fields, type_params) = self.parse_struct_fields(); self.expect(T::End); - Some(Type::Struct(Arc::new(fields), Arc::new(type_params))) + Some(Type::Struct(fields, type_params)) } fn parse_enum_type(&mut self) -> Type { let variants = self.parse_enum_fields(); self.expect(T::End); - Type::Enum(Arc::new(variants)) + Type::Enum(variants) } /// isomorphic-ish with parse_type_list() @@ -941,7 +941,7 @@ .map(|ty| Type::Generic(ty)) .collect(); */ - Type::Sum(Arc::new(fields), Arc::new(generics)) + Type::Sum(fields, generics) } fn parse_exprs(&mut self) -> Vec { @@ -1384,7 +1384,7 @@ } else { vec![] }; - Type::Named(Sym::new(s), Arc::new(type_params)) + Type::Named(Sym::new(s), type_params) } } T::At => { @@ -1401,11 +1401,11 @@ assert!(len >= 0); self.expect(T::RBracket); let inner = self.parse_type(); - Type::Array(Arc::new(inner), len as usize) + Type::Array(Box::new(inner), len as usize) } T::Ampersand => { let next = self.try_parse_type()?; - Type::Uniq(Arc::new(next)) + Type::Uniq(Box::new(next)) } _ => { // Wind the parse stream back to wherever we started @@ -1554,9 +1554,9 @@ ast::Decl::Function { name: Sym::new("foo"), signature: ast::Signature { - params: Arc::new(vec![(Sym::new("x"), i32_t.clone())]), + params: vec![(Sym::new("x"), i32_t.clone())], rettype: i32_t, - typeparams: Arc::new(vec![]), + typeparams: vec![], }, body: vec![Expr::int(9)], doc_comment: vec![], diff --git a/src/passes.rs b/src/passes.rs --- a/src/passes.rs +++ b/src/passes.rs @@ -319,8 +319,8 @@ } } -fn types_map(typs: Arc>, f: &mut dyn FnMut(Type) -> Type) -> Arc> { - Arc::new(typs.iter().cloned().map(|t| type_map(t, f)).collect()) +fn types_map(typs: Vec, f: &mut dyn FnMut(Type) -> Type) -> Vec { + typs.into_iter().map(|t| type_map(t, f)).collect() } /// Recursion scheme to turn one type into another. @@ -330,17 +330,15 @@ /// it generic over any iterator, if we want to make life even harder for /// ourself. fn types_map_btree( - typs: Arc>, + typs: BTreeMap, f: &mut dyn FnMut(Type) -> Type, - ) -> Arc> + ) -> BTreeMap where - K: Ord + Clone, + K: Ord, { - Arc::new( - typs.iter() - .map(|(key, ty)| (key.clone(), type_map(ty.clone(), f))) - .collect(), - ) + typs.into_iter() + .map(|(key, ty)| (key, type_map(ty, f))) + .collect() } let res = match typ { Type::Struct(fields, generics) => { @@ -351,12 +349,12 @@ let new_fields = types_map_btree(fields, f); Type::Sum(new_fields, generics) } - Type::Array(ty, len) => Type::array(&type_map(ty.as_ref().clone(), f), len), + Type::Array(ty, len) => Type::Array(Box::new(type_map(*ty, f)), len), Type::Func(args, rettype, typeparams) => { let new_args = types_map(args, f); - let new_rettype = type_map(rettype.as_ref().clone(), f); + let new_rettype = type_map(*rettype, f); let new_typeparams = types_map(typeparams, f); - Type::function(&new_args, &new_rettype, &new_typeparams) + Type::Func(new_args, Box::new(new_rettype), new_typeparams) } // Not super sure whether this is necessary, but can't hurt. Type::Named(nm, tys) => Type::Named(nm, types_map(tys, f)), @@ -365,8 +363,8 @@ Type::Enum(_) => typ, Type::Generic(_) => typ, Type::Uniq(t) => { - let new_t = type_map(t.as_ref().clone(), f); - Type::Uniq(Arc::new(new_t)) + let new_t = type_map(*t, f); + Type::Uniq(Box::new(new_t)) } }; f(res) @@ -376,12 +374,11 @@ fn signature_map(sig: hir::Signature, f: &mut dyn FnMut(Type) -> Type) -> hir::Signature { let new_params = sig .params - .iter() - .cloned() + .into_iter() .map(|(sym, ty)| (sym, type_map(ty, f))) .collect(); hir::Signature { - params: Arc::new(new_params), + params: new_params, rettype: type_map(sig.rettype, f), typeparams: types_map(sig.typeparams, f), } diff --git a/src/passes/struct_to_tuple.rs b/src/passes/struct_to_tuple.rs --- a/src/passes/struct_to_tuple.rs +++ b/src/passes/struct_to_tuple.rs @@ -38,11 +38,9 @@ // on the field names. // TODO: What do we do with generics? Anything? - let tuple_fields = fields - .values() - .map(|ty| type_map(ty.clone(), &mut tuplize_type)) + let tuple_fields = fields.values().map(|ty| type_map(ty.clone(), &mut tuplize_type)) .collect(); - Type::tuple(Arc::new(tuple_fields)) + Type::tuple(tuple_fields) } other => other, } @@ -79,7 +77,10 @@ .map(|(ky, vl)| (offset_of_field(type_body, ky), vl)) .collect(); ordered_body.sort_by(|a, b| a.0.cmp(&b.0)); - let new_body = ordered_body.into_iter().map(|(_i, expr)| expr).collect(); + let new_body = ordered_body + .into_iter() + .map(|(_i, expr)| expr) + .collect(); E::TupleCtor { body: new_body } } @@ -270,15 +271,14 @@ let mut body = BTreeMap::new(); body.insert(Sym::new("foo"), Type::i32()); body.insert(Sym::new("bar"), Type::i64()); - let body = Arc::new(body); - let desired = tuplize_type(Type::Struct(body.clone(), Arc::new(vec![]))); - let inp = Type::Struct(body, Arc::new(vec![])); + let desired = tuplize_type(Type::Struct(body.clone(), vec![])); + let inp = Type::Struct(body, vec![]); let out = type_map(inp.clone(), &mut tuplize_type); assert_eq!(out, desired); - let desired2 = Type::array(&out, 3); - let inp2 = Type::array(&inp, 3); + let desired2 = Type::Array(Box::new(out), 3); + let inp2 = Type::Array(Box::new(inp), 3); let out2 = type_map(inp2, &mut tuplize_type); assert_eq!(out2, desired2); } diff --git a/src/typeck.rs b/src/typeck.rs --- a/src/typeck.rs +++ b/src/typeck.rs @@ -409,7 +409,7 @@ let tinfo = match t { Type::Prim(ty) => TypeInfo::Prim(*ty), Type::Never => TypeInfo::Never, - Type::Enum(vals) => TypeInfo::Enum((&**vals).clone()), + Type::Enum(vals) => TypeInfo::Enum(vals.clone()), Type::Named(s, args) => { let new_args = args.iter().map(|t| self.insert_known(t)).collect(); TypeInfo::Named(*s, new_args) @@ -726,11 +726,11 @@ Never => Ok(Type::Never), Prim(ty) => Ok(Type::Prim(*ty)), Ref(id) => self.reconstruct(*id), - Enum(ts) => Ok(Type::Enum(Arc::new(ts.clone()))), + Enum(ts) => Ok(Type::Enum(ts.clone())), Named(s, args) => { let arg_types: Result, _> = args.iter().map(|x| self.reconstruct(*x)).collect(); - Ok(Type::Named(*s, Arc::new(arg_types?))) + Ok(Type::Named(*s, arg_types?)) } Func(args, rettype, typeparams) => { let real_args: Result, TypeError> = @@ -738,12 +738,10 @@ let type_param_types: Result, _> = typeparams.iter().map(|x| self.reconstruct(*x)).collect(); - let real_args = real_args?; - let type_param_types = type_param_types?; - Ok(Type::function( - &real_args, - &self.reconstruct(*rettype)?, - &type_param_types, + Ok(Type::Func( + real_args?, + Box::new(self.reconstruct(*rettype)?), + type_param_types?, )) } TypeParam(name) => Ok(Type::Generic(*name)), @@ -757,11 +755,11 @@ .collect(); // TODO: The empty params here feels suspicious, verify. let params = vec![]; - Ok(Type::Struct(Arc::new(real_body?), Arc::new(params))) + Ok(Type::Struct(real_body?, params)) } Array(ty, len) => { let real_body = self.reconstruct(*ty)?; - Ok(Type::array(&real_body, len.unwrap())) + Ok(Type::Array(Box::new(real_body), len.unwrap())) } Sum(body) => { let real_body: Result, TypeError> = body @@ -772,11 +770,11 @@ }) .collect(); let params = vec![]; - Ok(Type::Sum(Arc::new(real_body?), Arc::new(params))) + Ok(Type::Sum(real_body?, params)) } Uniq(ty) => { let inner_type = self.reconstruct(*ty)?; - Ok(Type::Uniq(Arc::new(inner_type))) + Ok(Type::Uniq(Box::new(inner_type))) } } } @@ -806,7 +804,7 @@ let typeinfo = match t { Type::Prim(val) => TypeInfo::Prim(*val), Type::Never => TypeInfo::Never, - Type::Enum(vals) => TypeInfo::Enum((**vals).clone()), + Type::Enum(vals) => TypeInfo::Enum(vals.clone()), Type::Named(s, args) => { let inst_args: Vec<_> = args.iter().map(|t| helper(tck, named_types, t)).collect(); @@ -916,7 +914,7 @@ impl Symtbl { fn add_builtins(&self, tck: &mut Tck) { - for builtin in &*builtins::all() { + for builtin in &*builtins::BUILTINS { let ty = tck.insert_known(&builtin.sig); self.add_var(builtin.name, ty, false); } @@ -1010,7 +1008,7 @@ */ // Insert info about the function signature let mut params = vec![]; - for (_paramname, paramtype) in &*signature.params { + for (_paramname, paramtype) in &signature.params { let p = tck.insert_known(paramtype); params.push(p); } @@ -1033,7 +1031,7 @@ // Add params to function's scope let _guard = symtbl.push_scope(); - for (paramname, paramtype) in &*signature.params { + for (paramname, paramtype) in &signature.params { let p = tck.insert_known(paramtype); symtbl.add_var(*paramname, p, false); } @@ -1474,8 +1472,7 @@ tck.unify(symtbl, tid, body_type)?; trace!("Done unifying type ctor"); // The type the expression returns - let constructed_type = - tck.insert_known(&Type::Named(*name, Arc::new(type_params.clone()))); + let constructed_type = tck.insert_known(&Type::Named(*name, type_params.clone())); tck.set_expr_type(expr, constructed_type); Ok(constructed_type) } @@ -1626,7 +1623,7 @@ } => { // TODO: Kinda duplicated, not a huge fan. let mut params = vec![]; - for (_paramname, paramtype) in &*signature.params { + for (_paramname, paramtype) in &signature.params { let p = tck.insert_known(paramtype); params.push(p); }