diff --git a/base/Cargo.toml b/base/Cargo.toml index 41a333a026..affc9b6a55 100644 --- a/base/Cargo.toml +++ b/base/Cargo.toml @@ -15,4 +15,5 @@ log = "0.3.6" quick-error = "1.0.0" fnv = "1.0.3" pretty = "0.1.0" -smallvec = "0.2.0" \ No newline at end of file +smallvec = { git = "https://github.com/servo/rust-smallvec", rev = "cc04c67174dfcd1aa9e893cd55b13b583180f8a9" } +collect-mac = "0.1.0" diff --git a/base/src/instantiate.rs b/base/src/instantiate.rs index cf3b79a6ba..2f0e69c641 100644 --- a/base/src/instantiate.rs +++ b/base/src/instantiate.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; use types; -use types::{AliasData, Type, Generic, ArcType, TypeEnv}; +use types::{AliasData, AppVec, Type, Generic, ArcType, TypeEnv}; use symbol::Symbol; use fnv::FnvMap; @@ -134,7 +134,7 @@ pub fn type_of_alias(alias: &AliasData, args: &[ArcType]) -> Op .count(); if alias_args.len() - args.len() <= allowed_missing_args { // Remove the args at the end of the aliased type - let arg_types: Vec<_> = arg_types.iter() + let arg_types: AppVec<_> = arg_types.iter() .take(arg_types.len() - (alias_args.len() - args.len())) .cloned() .collect(); diff --git a/base/src/lib.rs b/base/src/lib.rs index 0690887f2d..5e5d2bf470 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -7,6 +7,8 @@ extern crate log; extern crate quick_error; extern crate pretty; extern crate smallvec; +#[macro_use] +extern crate collect_mac; pub mod ast; pub mod error; diff --git a/base/src/types.rs b/base/src/types.rs index 07927f667d..48800036bf 100644 --- a/base/src/types.rs +++ b/base/src/types.rs @@ -282,13 +282,10 @@ impl Type } pub fn array(typ: T) -> T { - Type::app(Type::builtin(BuiltinType::Array), vec![typ]) + Type::app(Type::builtin(BuiltinType::Array), collect![typ]) } - pub fn app(id: T, args: I) -> T - where I: IntoIterator, - { - let args: AppVec = args.into_iter().collect(); + pub fn app(id: T, args: AppVec) -> T { if args.is_empty() { id } else { @@ -341,7 +338,7 @@ impl Type args.into_iter() .rev() .fold(ret, - |body, arg| Type::app(function.clone(), vec![arg, body])) + |body, arg| Type::app(function.clone(), collect![arg, body])) } pub fn generic(typ: Generic) -> T { @@ -1056,13 +1053,13 @@ pub fn walk_move_type_opt(typ: &Type, f: &mut F) -> Optio { match *typ { Type::App(ref id, ref args) => { - let new_args = walk_move_types(AppVec::new(), args, |t| f.visit(t)); + let new_args = walk_move_types(args, |t| f.visit(t)); merge(id, f.visit(id), args, new_args, Type::app) } Type::Record(ref row) => f.visit(row).map(|row| T::from(Type::Record(row))), Type::Variant(ref row) => f.visit(row).map(|row| T::from(Type::Variant(row))), Type::ExtendRow { ref types, ref fields, ref rest } => { - let new_fields = walk_move_types(Vec::new(), fields, |field| { + let new_fields = walk_move_types(fields, |field| { f.visit(&field.typ).map(|typ| { Field { name: field.name.clone(), @@ -1089,12 +1086,13 @@ pub fn walk_move_type_opt(typ: &Type, f: &mut F) -> Optio } // FIXME Add R: Default and remove the `out` parameter -pub fn walk_move_types<'a, I, F, T, R>(mut out: R, types: I, mut f: F) -> Option +pub fn walk_move_types<'a, I, F, T, R>(types: I, mut f: F) -> Option where I: IntoIterator, F: FnMut(&'a T) -> Option, T: Clone + 'a, - R: VecLike + DerefMut, + R: Default + VecLike + DerefMut, { + let mut out = R::default(); walk_move_types2(types.into_iter(), false, &mut out, &mut f); if out.is_empty() { None diff --git a/base/tests/types.rs b/base/tests/types.rs index 63a1b88b83..2e62d0fdf8 100644 --- a/base/tests/types.rs +++ b/base/tests/types.rs @@ -1,4 +1,6 @@ extern crate gluon_base as base; +#[macro_use] +extern crate collect_mac; use std::ops::Deref; diff --git a/check/Cargo.toml b/check/Cargo.toml index 3b22d10995..17b423514f 100644 --- a/check/Cargo.toml +++ b/check/Cargo.toml @@ -14,9 +14,12 @@ documentation = "https://docs.rs/gluon" env_logger = { version = "0.3.4", optional = true } log = "0.3.6" union-find = "0.3.1" -smallvec = "0.2.0" +smallvec = { git = "https://github.com/servo/rust-smallvec", rev = "cc04c67174dfcd1aa9e893cd55b13b583180f8a9" } gluon_base = { path = "../base", version = "0.2.2" } gluon_parser = { path = "../parser", version = "0.2.2", optional = true } +[dev-dependencies] +collect-mac = "0.1.0" + [features] test = ["gluon_parser", "env_logger"] diff --git a/check/src/kindcheck.rs b/check/src/kindcheck.rs index 96af6e58c2..e83d53ecaa 100644 --- a/check/src/kindcheck.rs +++ b/check/src/kindcheck.rs @@ -3,7 +3,7 @@ use std::fmt; use base::ast; use base::kind::{self, ArcKind, Kind, KindEnv}; use base::symbol::Symbol; -use base::types::{self, ArcType, BuiltinType, Field, Generic, Type, Walker}; +use base::types::{self, AppVec, ArcType, BuiltinType, Field, Generic, Type, Walker}; use substitution::{Substitution, Substitutable}; use unify; @@ -172,7 +172,7 @@ impl<'a> KindCheck<'a> { Type::Builtin(builtin_typ) => Ok((self.builtin_kind(builtin_typ), typ.clone())), Type::App(ref ctor, ref args) => { let (mut kind, ctor) = try!(self.kindcheck(ctor)); - let mut new_args = Vec::new(); + let mut new_args = AppVec::new(); for arg in args { let f = Kind::function(self.subs.new_var(), self.subs.new_var()); kind = try!(self.unify(&f, kind)); diff --git a/check/src/typecheck.rs b/check/src/typecheck.rs index fb8880454e..9b25cfa303 100644 --- a/check/src/typecheck.rs +++ b/check/src/typecheck.rs @@ -13,7 +13,7 @@ use base::instantiate::{self, Instantiator}; use base::kind::{Kind, KindEnv, ArcKind}; use base::pos::{BytePos, Span, Spanned}; use base::symbol::{Symbol, SymbolRef, SymbolModule, Symbols}; -use base::types::{self, Alias, AliasData, ArcType, Field, Generic}; +use base::types::{self, Alias, AliasData, AppVec, ArcType, Field, Generic}; use base::types::{PrimitiveEnv, Type, TypeEnv, TypeVariable}; use kindcheck::{self, KindCheck}; use substitution::Substitution; @@ -299,7 +299,7 @@ impl<'a> Typecheck<'a> { self.stack_var(field.name, field.typ); } } - let generic_args = alias.args.iter().cloned().map(Type::generic); + let generic_args = alias.args.iter().cloned().map(Type::generic).collect(); let typ = Type::<_, ArcType>::app(alias.as_ref().clone(), generic_args); { // FIXME: Workaround so that both the types name in this module and its global @@ -1112,7 +1112,7 @@ impl<'a> Typecheck<'a> { Some(gen) } Type::ExtendRow { ref types, ref fields, ref rest } => { - let new_fields = types::walk_move_types(Vec::new(), fields, |field| { + let new_fields = types::walk_move_types(fields, |field| { // Make a new name base for any unbound variables in the record field // Gives { id : a0 -> a0, const : b0 -> b1 -> b1 } // instead of { id : a0 -> a0, const : a1 -> a2 -> a2 } @@ -1445,6 +1445,8 @@ fn primitive_type(op_type: &str) -> ArcType { /// Example: /// /// ```rust +/// #[macro_use] +/// extern crate collect_mac; /// extern crate gluon_base; /// extern crate gluon_check; /// @@ -1454,17 +1456,17 @@ fn primitive_type(op_type: &str) -> ArcType { /// # fn main() { /// let i: ArcType = Type::int(); /// let s: ArcType = Type::string(); -/// assert_eq!(unroll_typ(&*Type::app(Type::app(i.clone(), vec![s.clone()]), vec![i.clone()])), -/// Some(Type::app(i.clone(), vec![s.clone(), i.clone()]))); -/// assert_eq!(unroll_typ(&*Type::app(Type::app(i.clone(), vec![i.clone()]), vec![s.clone()])), -/// Some(Type::app(i.clone(), vec![i.clone(), s.clone()]))); +/// assert_eq!(unroll_typ(&*Type::app(Type::app(i.clone(), collect![s.clone()]), collect![i.clone()])), +/// Some(Type::app(i.clone(), collect![s.clone(), i.clone()]))); +/// assert_eq!(unroll_typ(&*Type::app(Type::app(i.clone(), collect![i.clone()]), collect![s.clone()])), +/// Some(Type::app(i.clone(), collect![i.clone(), s.clone()]))); /// let f: ArcType = Type::builtin(BuiltinType::Function); -/// assert_eq!(unroll_typ(&*Type::app(Type::app(f.clone(), vec![i.clone()]), vec![s.clone()])), -/// Some(Type::function(vec![i.clone()], s.clone()))); +/// assert_eq!(unroll_typ(&*Type::app(Type::app(f.clone(), collect![i.clone()]), collect![s.clone()])), +/// Some(Type::function(collect![i.clone()], s.clone()))); /// # } /// ``` pub fn unroll_typ(typ: &Type) -> Option { - let mut args = Vec::new(); + let mut args = AppVec::new(); let mut current = match *typ { Type::App(ref l, ref rest) => { // No need to unroll if `l` is not an application as that will just result in returning diff --git a/check/src/unify_type.rs b/check/src/unify_type.rs index 2a8a591de7..4271609a99 100644 --- a/check/src/unify_type.rs +++ b/check/src/unify_type.rs @@ -4,7 +4,7 @@ use std::mem; use smallvec::VecLike; use base::error::Errors; -use base::types::{self, AppVec, ArcType, Field, Type, TypeVariable, TypeEnv, merge}; +use base::types::{self, ArcType, Field, Type, TypeVariable, TypeEnv, merge}; use base::symbol::{Symbol, SymbolRef}; use base::instantiate; use base::scoped_map::ScopedMap; @@ -176,26 +176,29 @@ fn do_zip_match<'a, U>(self_: &ArcType, match l_args.len().cmp(&r_args.len()) { Equal => { let new_type = unifier.try_match(l, r); - let new_args = walk_move_types(AppVec::new(), - l_args.iter().zip(r_args), + let new_args = walk_move_types(l_args.iter().zip(r_args), |l, r| unifier.try_match(l, r)); Ok(merge(l, new_type, l_args, new_args, Type::app)) } Less => { let offset = r_args.len() - l_args.len(); - let new_type = - unifier.try_match(l, &Type::app(r.clone(), r_args[..offset].iter().cloned())); - let new_args = walk_move_types(AppVec::new(), - l_args.iter().zip(&r_args[offset..]), + + let reduced_r = Type::app(r.clone(), + r_args[..offset].iter().cloned().collect()); + let new_type = unifier.try_match(l, &reduced_r); + + let new_args = walk_move_types(l_args.iter().zip(&r_args[offset..]), |l, r| unifier.try_match(l, r)); Ok(merge(l, new_type, l_args, new_args, Type::app)) } Greater => { let offset = l_args.len() - r_args.len(); - let new_type = - unifier.try_match(&Type::app(l.clone(), l_args[..offset].iter().cloned()), r); - let new_args = walk_move_types(AppVec::new(), - l_args[offset..].iter().zip(r_args), + + let reduced_l = Type::app(l.clone(), + l_args[..offset].iter().cloned().collect()); + let new_type = unifier.try_match(&reduced_l, r); + + let new_args = walk_move_types(l_args[offset..].iter().zip(r_args), |l, r| unifier.try_match(l, r)); Ok(merge(r, new_type, r_args, new_args, Type::app)) } @@ -217,7 +220,7 @@ fn do_zip_match<'a, U>(self_: &ArcType, if l_args.len() == r_args.len() && l_args.iter().zip(r_args).all(|(l, r)| l.name.name_eq(&r.name)) && l_types == r_types { - let new_args = walk_move_types(Vec::new(), l_args.iter().zip(r_args), |l, r| { + let new_args = walk_move_types(l_args.iter().zip(r_args), |l, r| { unifier.try_match(&l.typ, &r.typ) .map(|typ| { types::Field { @@ -242,22 +245,21 @@ fn do_zip_match<'a, U>(self_: &ArcType, // HACK For non polymorphic records we need to care about field order as the // compiler assumes the order the fields occur in the type determines how // to access them - let new_args = - walk_move_types(Vec::new(), l_args.iter().zip(r_args.iter()), |l, r| { - let opt_type = if !l.name.name_eq(&r.name) { - let err = TypeError::FieldMismatch(l.name.clone(), r.name.clone()); - unifier.report_error(UnifyError::Other(err)); - None - } else { - unifier.try_match(&l.typ, &r.typ) - }; - opt_type.map(|typ| { - types::Field { - name: l.name.clone(), - typ: typ, - } - }) - }); + let new_args = walk_move_types(l_args.iter().zip(r_args.iter()), |l, r| { + let opt_type = if !l.name.name_eq(&r.name) { + let err = TypeError::FieldMismatch(l.name.clone(), r.name.clone()); + unifier.report_error(UnifyError::Other(err)); + None + } else { + unifier.try_match(&l.typ, &r.typ) + }; + opt_type.map(|typ| { + types::Field { + name: l.name.clone(), + typ: typ, + } + }) + }); let new_rest = unifier.try_match(l_rest, r_rest); Ok(merge(l_args, new_args, @@ -333,7 +335,7 @@ fn unify_rows<'a, U>(unifier: &mut UnifierState<'a, U>, let mut types: Vec<_> = types_both.iter().map(|pair| pair.0.clone()).collect(); // Unify the fields that exists in both records - let new_both = walk_move_types(Vec::new(), both.iter().cloned(), |l, r| { + let new_both = walk_move_types(both.iter().cloned(), |l, r| { unifier.try_match(&l.typ, &r.typ) .map(|typ| { types::Field { @@ -344,7 +346,7 @@ fn unify_rows<'a, U>(unifier: &mut UnifierState<'a, U>, }); // Pack all fields from both records into a single `Type::ExtendRow` value - let mut fields = match new_both { + let mut fields: Vec<_> = match new_both { Some(fields) => fields, None => both.iter().map(|pair| pair.0.clone()).collect(), }; @@ -547,12 +549,13 @@ fn try_with_alias<'a, U>(unifier: &mut UnifierState<'a, U>, } } -fn walk_move_types<'a, I, F, T, R>(mut out: R, types: I, mut f: F) -> Option +fn walk_move_types<'a, I, F, T, R>(types: I, mut f: F) -> Option where I: Iterator, F: FnMut(&'a T, &'a T) -> Option, T: Clone + 'a, - R: VecLike, + R: Default + VecLike, { + let mut out = R::default(); walk_move_types2(types, false, &mut out, &mut f); if out[..].is_empty() { None diff --git a/check/tests/completion.rs b/check/tests/completion.rs index f6f83d488c..c71fff8986 100644 --- a/check/tests/completion.rs +++ b/check/tests/completion.rs @@ -1,3 +1,5 @@ +#[macro_use] +extern crate collect_mac; extern crate env_logger; extern crate gluon_base as base; diff --git a/check/tests/fail.rs b/check/tests/fail.rs index f2a7d9b865..e6b24b194f 100644 --- a/check/tests/fail.rs +++ b/check/tests/fail.rs @@ -1,3 +1,5 @@ +#[macro_use] +extern crate collect_mac; extern crate env_logger; extern crate gluon_base as base; diff --git a/check/tests/metadata.rs b/check/tests/metadata.rs index a681a7773a..b1e61ce1db 100644 --- a/check/tests/metadata.rs +++ b/check/tests/metadata.rs @@ -1,3 +1,5 @@ +#[macro_use] +extern crate collect_mac; extern crate env_logger; extern crate gluon_base as base; diff --git a/check/tests/pass.rs b/check/tests/pass.rs index b1d694c6a5..20a63ee04c 100644 --- a/check/tests/pass.rs +++ b/check/tests/pass.rs @@ -1,3 +1,5 @@ +#[macro_use] +extern crate collect_mac; extern crate env_logger; extern crate gluon_base as base; @@ -287,7 +289,7 @@ in eq_Int name: support::intern_unscoped("=="), typ: Type::function(vec![typ("a"), typ("a")], bool), }])); - let expected = Ok(Type::app(eq, vec![typ("Int")])); + let expected = Ok(Type::app(eq, collect![typ("Int")])); assert_eq!(result, expected); } @@ -320,7 +322,7 @@ in option_Functor.map (\x -> x #Int- 1) (Some 2) vec![typ("a")])), }]); let option = alias("Option", &["a"], variants); - let expected = Ok(Type::app(option, vec![typ("Int")])); + let expected = Ok(Type::app(option, collect![typ("Int")])); assert_eq!(result, expected); } @@ -359,7 +361,7 @@ test support::typ_a("Test", vec![typ("a")])), }]); - let expected = Ok(Type::app(alias("Test", &["a"], variants), vec![Type::unit()])); + let expected = Ok(Type::app(alias("Test", &["a"], variants), collect![Type::unit()])); assert_eq!(result, expected); } @@ -409,7 +411,7 @@ in f "; let result = support::typecheck(text); let function = alias("Fn", &["a", "b"], Type::function(vec![typ("a")], typ("b"))); - let args = vec![typ("String"), typ("Int")]; + let args = collect![typ("String"), typ("Int")]; let expected = Ok(Type::app(function, args)); assert_eq!(result, expected); @@ -539,7 +541,7 @@ return 1 Type::variant(vec![Field { name: intern(name), typ: Type::function(vec![typ("a")], - Type::app(typ(name), vec![typ("a")])), + Type::app(typ(name), collect![typ("a")])), }]) }; let test = alias("Test", &["a"], variant("Test")); @@ -557,8 +559,9 @@ return 1 id: intern("a"), }, ], - Type::app(Type::generic(m), vec![Type::app(id, vec![typ("a")])])); - let expected = Ok(Type::app(id_t, vec![test, typ("Int")])); + Type::app(Type::generic(m), + collect![Type::app(id, collect![typ("a")])])); + let expected = Ok(Type::app(id_t, collect![test, typ("Int")])); assert_eq!(result, expected); } diff --git a/check/tests/row_polymorphism.rs b/check/tests/row_polymorphism.rs index b34dcc5cf1..04744f3e1e 100644 --- a/check/tests/row_polymorphism.rs +++ b/check/tests/row_polymorphism.rs @@ -1,3 +1,5 @@ +#[macro_use] +extern crate collect_mac; extern crate env_logger; extern crate gluon_base as base; diff --git a/check/tests/stack_overflow.rs b/check/tests/stack_overflow.rs index 7b7a1b2327..6aeb5bf636 100644 --- a/check/tests/stack_overflow.rs +++ b/check/tests/stack_overflow.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate collect_mac; + extern crate gluon_base as base; extern crate gluon_parser as parser; extern crate gluon_check as check; diff --git a/check/tests/support/mod.rs b/check/tests/support/mod.rs index 8eb94473cf..308d1936ef 100644 --- a/check/tests/support/mod.rs +++ b/check/tests/support/mod.rs @@ -60,7 +60,7 @@ impl MockEnv { let mut interner = interner.borrow_mut(); let bool_sym = interner.symbol("Bool"); - let bool_ty = Type::app(Type::ident(bool_sym.clone()), vec![]); + let bool_ty = Type::app(Type::ident(bool_sym.clone()), collect![]); MockEnv { bool: Alias::new(bool_sym, vec![], bool_ty) } } @@ -182,7 +182,7 @@ pub fn typ_a(s: &str, args: Vec) -> T if args.len() == 0 { Type::ident(intern(s)) } else { - Type::app(Type::ident(intern(s)), args) + Type::app(Type::ident(intern(s)), args.into_iter().collect()) } } } diff --git a/parser/Cargo.toml b/parser/Cargo.toml index dc60f30a62..ecbc9b0b3e 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -17,5 +17,8 @@ env_logger = { version = "0.3.4", optional = true } log = "0.3.6" gluon_base = { path = "../base", version = "0.2.2" } +[dev-dependencies] +collect-mac = "0.1.0" + [features] test = ["env_logger"] diff --git a/parser/src/lib.rs b/parser/src/lib.rs index cc618a8453..822c3b113e 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -21,7 +21,7 @@ use base::kind::Kind; use base::error::Errors; use base::pos::{self, BytePos, Span, Spanned}; use base::symbol::{Name, Symbol}; -use base::types::{Alias, ArcType, Generic, Field, Type}; +use base::types::{Alias, AppVec, ArcType, Generic, Field, Type}; use combine::primitives::{Consumed, Stream, StreamOnce, Error as CombineError, Info, BufferedStream}; @@ -280,7 +280,7 @@ impl<'input, I, Id, F> ParserEnv fn parse_type(&self, input: I) -> ParseResult, I> { (many1(self.parser(ParserEnv::::type_arg)), optional(token(Token::RightArrow).with(self.typ()))) - .map(|(mut arg, ret): (Vec<_>, _)| { + .map(|(mut arg, ret): (AppVec<_>, _)| { let arg = if arg.len() == 1 { arg.pop().unwrap() } else { @@ -381,7 +381,7 @@ impl<'input, I, Id, F> ParserEnv fn type_binding(&self, input: I) -> ParseResult, I> { (self.ident(), many(self.ident())) - .then(|(name, args): (Id, Vec)| { + .then(|(name, args): (Id, AppVec)| { let return_type = if args.is_empty() { Type::ident(name.clone()) } else { @@ -391,7 +391,8 @@ impl<'input, I, Id, F> ParserEnv kind: Kind::variable(0), id: id.clone(), }) - }); + }) + .collect(); Type::app(Type::ident(name.clone()), arg_types) }; token(Token::Equal) diff --git a/parser/tests/basic.rs b/parser/tests/basic.rs index fac2f644f8..9d0963c094 100644 --- a/parser/tests/basic.rs +++ b/parser/tests/basic.rs @@ -3,6 +3,8 @@ extern crate gluon_parser as parser; extern crate env_logger; #[macro_use] extern crate log; +#[macro_use] +extern crate collect_mac; mod support; @@ -296,7 +298,7 @@ fn op_identifier() { fn variant_type() { let _ = ::env_logger::init(); let e = parse_new!("type Option a = | None | Some a in Some 1"); - let option = Type::app(typ("Option"), vec![typ("a")]); + let option = Type::app(typ("Option"), collect![typ("a")]); let none = Type::function(vec![], option.clone()); let some = Type::function(vec![typ("a")], option.clone()); assert_eq!(e, @@ -612,7 +614,7 @@ x comment: None, name: no_loc(Pattern::Ident(TypedIdent::new(intern("x")))), typ: Type::app(typ("->"), - vec![typ("Int"), typ("Int")]), + collect![typ("Int"), typ("Int")]), args: vec![], expr: id("x"), }], diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 22ac964ff7..0745da6d12 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -15,6 +15,7 @@ env_logger = { version = "0.3.4", optional = true } log = "0.3.6" quick-error = "1.1.0" mopa = "0.2.2" +collect-mac = "0.1.0" gluon_base = { path = "../base", version = "0.2.2" } [features] diff --git a/vm/src/api.rs b/vm/src/api.rs index 3c1bb3942e..b59b0b4c1f 100644 --- a/vm/src/api.rs +++ b/vm/src/api.rs @@ -557,7 +557,7 @@ impl VmType for Ordering { type Type = Self; fn make_type(vm: &Thread) -> ArcType { let symbol = vm.find_type_info("std.types.Ordering").unwrap().name.clone(); - Type::app(Type::ident(symbol), vec![]) + Type::app(Type::ident(symbol), collect![]) } } impl<'vm> Pushable<'vm> for Ordering { @@ -744,7 +744,7 @@ impl VmType for Option type Type = Option; fn make_type(vm: &Thread) -> ArcType { let symbol = vm.find_type_info("std.types.Option").unwrap().name.clone(); - Type::app(Type::ident(symbol), vec![T::make_type(vm)]) + Type::app(Type::ident(symbol), collect![T::make_type(vm)]) } } impl<'vm, T: Pushable<'vm>> Pushable<'vm> for Option { @@ -787,7 +787,7 @@ impl VmType for StdResult fn make_type(vm: &Thread) -> ArcType { let symbol = vm.find_type_info("std.types.Result").unwrap().name.clone(); Type::app(Type::ident(symbol), - vec![E::make_type(vm), T::make_type(vm)]) + collect![E::make_type(vm), T::make_type(vm)]) } } @@ -857,7 +857,7 @@ impl VmType for IO fn make_type(vm: &Thread) -> ArcType { let env = vm.global_env().get_env(); let alias = env.find_type_info("IO").unwrap().into_owned(); - Type::app(alias.into_type(), vec![T::make_type(vm)]) + Type::app(alias.into_type(), collect![T::make_type(vm)]) } fn extra_args() -> VmIndex { 1 @@ -1506,7 +1506,7 @@ impl <$($args: VmType,)* R: VmType> VmType for fn ($($args),*) -> R { type Type = fn ($($args::Type),*) -> R::Type; #[allow(non_snake_case)] fn make_type(vm: &Thread) -> ArcType { - let args = vec![$(make_type::<$args>(vm)),*]; + let args = collect![$(make_type::<$args>(vm)),*]; Type::function(args, make_type::(vm)) } } diff --git a/vm/src/channel.rs b/vm/src/channel.rs index 3781d50700..7a99e57015 100644 --- a/vm/src/channel.rs +++ b/vm/src/channel.rs @@ -81,7 +81,7 @@ impl VmType for Sender type Type = Sender; fn make_type(vm: &Thread) -> ArcType { let symbol = vm.global_env().get_env().find_type_info("Sender").unwrap().name.clone(); - Type::app(Type::ident(symbol), vec![T::make_type(vm)]) + Type::app(Type::ident(symbol), collect![T::make_type(vm)]) } } @@ -91,7 +91,7 @@ impl VmType for Receiver type Type = Receiver; fn make_type(vm: &Thread) -> ArcType { let symbol = vm.global_env().get_env().find_type_info("Receiver").unwrap().name.clone(); - Type::app(Type::ident(symbol), vec![T::make_type(vm)]) + Type::app(Type::ident(symbol), collect![T::make_type(vm)]) } } diff --git a/vm/src/lazy.rs b/vm/src/lazy.rs index 7954fa9e09..c2f5c531af 100644 --- a/vm/src/lazy.rs +++ b/vm/src/lazy.rs @@ -76,7 +76,7 @@ impl VmType for Lazy let env = vm.global_env().get_env(); let symbol = env.find_type_info("Lazy").unwrap().name.clone(); let ctor = Type::ident(symbol); - types::Type::app(ctor, vec![T::make_type(vm)]) + types::Type::app(ctor, collect![T::make_type(vm)]) } } diff --git a/vm/src/lib.rs b/vm/src/lib.rs index be67a24b9e..5af368e68d 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -8,6 +8,8 @@ extern crate env_logger; extern crate quick_error; #[macro_use] extern crate mopa; +#[macro_use] +extern crate collect_mac; extern crate gluon_base as base; diff --git a/vm/src/reference.rs b/vm/src/reference.rs index 751d7b4f5c..404888c2f0 100644 --- a/vm/src/reference.rs +++ b/vm/src/reference.rs @@ -60,7 +60,7 @@ impl VmType for Reference let env = vm.global_env().get_env(); let symbol = env.find_type_info("Ref").unwrap().name.clone(); let ctor = Type::ident(symbol); - Type::app(ctor, vec![T::make_type(vm)]) + Type::app(ctor, collect![T::make_type(vm)]) } } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 8a43cebdd2..ef4822fa49 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -9,7 +9,7 @@ use base::fnv::FnvMap; use base::kind::{ArcKind, Kind, KindEnv}; use base::metadata::{Metadata, MetadataEnv}; use base::symbol::{Name, Symbol, SymbolRef}; -use base::types::{Alias, AliasData, ArcType, Generic, PrimitiveEnv, Type, TypeEnv}; +use base::types::{Alias, AliasData, AppVec, ArcType, Generic, PrimitiveEnv, Type, TypeEnv}; use macros::MacroEnv; use {Error, Result}; @@ -422,7 +422,7 @@ impl GlobalVmState { Err(Error::TypeAlreadyExists(name.into())) } else { let id = TypeId::of::(); - let arg_types: Vec<_> = args.iter().map(|g| self.get_generic(g)).collect(); + let arg_types: AppVec<_> = args.iter().map(|g| self.get_generic(g)).collect(); let args = arg_types.iter() .map(|g| match **g { Type::Generic(ref g) => g.clone(),