diff --git a/base/src/types.rs b/base/src/types.rs index 933cdbcb71..ff1645405a 100644 --- a/base/src/types.rs +++ b/base/src/types.rs @@ -331,18 +331,18 @@ impl BuiltinType { /// Kind representation /// -/// All types in gluon has a kind. Most types encountered are of the `Star` (*) kind which +/// All types in gluon has a kind. Most types encountered are of the `Type` kind which /// includes things like `Int`, `String` and `Option Int`. There are however other types which /// are said to be "higher kinded" and these use the `Function` (a -> b) variant. -/// These types include `Option` and `->` which both have the kind `* -> *` as well as `Functor` -/// which has the kind `(* -> *) -> *`. +/// These types include `Option` and `(->)` which both have the kind `Type -> Type` as well as +/// `Functor` which has the kind `(Type -> Type) -> Type`. #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub enum Kind { - /// Representation for a kind which is yet to be infered + /// Representation for a kind which is yet to be inferred. Variable(u32), /// The simplest possible kind. All values in a program have this kind. - Star, - /// Constructor which takes two kinds, taking the first as argument and returning the second + Type, + /// Constructor which takes two kinds, taking the first as argument and returning the second. Function(RcKind, RcKind), } @@ -350,9 +350,11 @@ impl Kind { pub fn variable(v: u32) -> RcKind { RcKind::new(Kind::Variable(v)) } - pub fn star() -> RcKind { - RcKind::new(Kind::Star) + + pub fn typ() -> RcKind { + RcKind::new(Kind::Type) } + pub fn function(l: RcKind, r: RcKind) -> RcKind { RcKind::new(Kind::Function(l, r)) } @@ -658,8 +660,9 @@ impl ASTType { impl TypeVariable { pub fn new(var: u32) -> TypeVariable { - TypeVariable::with_kind(Kind::Star, var) + TypeVariable::with_kind(Kind::Type, var) } + pub fn with_kind(kind: Kind, var: u32) -> TypeVariable { TypeVariable { kind: RcKind::new(kind), @@ -675,11 +678,12 @@ impl fmt::Display for Kind { write!(f, "{}", DisplayKind(Prec::Top, self)) } } + impl<'a> fmt::Display for DisplayKind<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self.1 { Kind::Variable(i) => i.fmt(f), - Kind::Star => '*'.fmt(f), + Kind::Type => "Type".fmt(f), Kind::Function(ref arg, ref ret) => { match self.0 { Prec::Function => { diff --git a/base/tests/types.rs b/base/tests/types.rs index 63bcd44933..87f187c8bb 100644 --- a/base/tests/types.rs +++ b/base/tests/types.rs @@ -15,7 +15,7 @@ fn type_con(s: I, args: Vec) -> Type Ok(b) => Type::Builtin(b), Err(()) if is_var => { Type::Generic(Generic { - kind: RcKind::new(Kind::Star), + kind: RcKind::new(Kind::Type), id: s, }) } @@ -56,7 +56,7 @@ fn show_record() { typ: Alias::new( "Test", vec![Generic { - kind: Kind::star(), + kind: Kind::typ(), id: "a", }], f.clone(), @@ -72,7 +72,7 @@ fn show_record() { typ: Alias::new( "Test", vec![Generic { - kind: Kind::star(), + kind: Kind::typ(), id: "a", }], f.clone(), @@ -93,7 +93,7 @@ fn show_record() { typ: Alias::new( "Test", vec![Generic { - kind: Kind::star(), + kind: Kind::typ(), id: "a", }], f.clone(), @@ -112,8 +112,8 @@ fn variants() { #[test] fn show_kind() { - let two_args = Kind::function(Kind::star(), Kind::function(Kind::star(), Kind::star())); - assert_eq!(format!("{}", two_args), "* -> * -> *"); - let function_arg = Kind::function(Kind::function(Kind::star(), Kind::star()), Kind::star()); - assert_eq!(format!("{}", function_arg), "(* -> *) -> *"); + let two_args = Kind::function(Kind::typ(), Kind::function(Kind::typ(), Kind::typ())); + assert_eq!(format!("{}", two_args), "Type -> Type -> Type"); + let function_arg = Kind::function(Kind::function(Kind::typ(), Kind::typ()), Kind::typ()); + assert_eq!(format!("{}", function_arg), "(Type -> Type) -> Type"); } diff --git a/check/src/kindcheck.rs b/check/src/kindcheck.rs index 8ce2c2eb66..bd65f34b00 100644 --- a/check/src/kindcheck.rs +++ b/check/src/kindcheck.rs @@ -25,11 +25,11 @@ pub struct KindCheck<'a> { info: &'a (KindEnv + 'a), idents: &'a (ast::IdentEnv + 'a), pub subs: Substitution, - /// A cached star kind, `*` - star_kind: RcKind, - /// A cached one argument kind function, `* -> *` + /// A cached type kind, `Type` + type_kind: RcKind, + /// A cached one argument kind function, `Type -> Type` function1_kind: RcKind, - /// A cached two argument kind function, `* -> * -> *` + /// A cached two argument kind function, `Type -> Type -> Type` function2_kind: RcKind, } @@ -56,7 +56,7 @@ fn walk_move_kind2(kind: &RcKind, f: &mut F) -> Option (None, None) => None, } } - Kind::Star | + Kind::Type | Kind::Variable(_) => None, } }; @@ -68,16 +68,16 @@ impl<'a> KindCheck<'a> { idents: &'a (ast::IdentEnv + 'a), subs: Substitution) -> KindCheck<'a> { - let star = Kind::star(); + let typ = Kind::typ(); KindCheck { variables: Vec::new(), locals: Vec::new(), info: info, idents: idents, subs: subs, - star_kind: star.clone(), - function1_kind: Kind::function(star.clone(), star.clone()), - function2_kind: Kind::function(star.clone(), Kind::function(star.clone(), star)), + type_kind: typ.clone(), + function1_kind: Kind::function(typ.clone(), typ.clone()), + function2_kind: Kind::function(typ.clone(), Kind::function(typ.clone(), typ)), } } @@ -90,8 +90,8 @@ impl<'a> KindCheck<'a> { self.variables.extend(variables.iter().cloned()); } - pub fn star_kind(&self) -> RcKind { - self.star_kind.clone() + pub fn type_kind(&self) -> RcKind { + self.type_kind.clone() } pub fn function1_kind(&self) -> RcKind { @@ -133,12 +133,12 @@ impl<'a> KindCheck<'a> { kind } - // Kindhecks `typ`, infering it to be of kind `*` + // Kindhecks `typ`, infering it to be of kind `Type` pub fn kindcheck_type(&mut self, typ: &mut TcType) -> Result { debug!("Kindcheck {:?}", typ); let (kind, t) = try!(self.kindcheck(typ)); - let star = self.star_kind(); - let kind = try!(self.unify(&star, kind)); + let type_kind = self.type_kind(); + let kind = try!(self.unify(&type_kind, kind)); *typ = self.finalize_type(t); debug!("Done {:?}", typ); Ok(kind) @@ -151,7 +151,7 @@ impl<'a> KindCheck<'a> { BuiltinType::Char | BuiltinType::Int | BuiltinType::Float | - BuiltinType::Unit => self.star_kind(), + BuiltinType::Unit => self.type_kind(), BuiltinType::Array => self.function1_kind(), BuiltinType::Function => self.function2_kind(), } @@ -191,26 +191,26 @@ impl<'a> KindCheck<'a> { let variants = try!(variants.iter() .map(|variant| { let (kind, typ) = try!(self.kindcheck(&variant.1)); - let star = self.star_kind(); - try!(self.unify(&star, kind)); + let type_kind = self.type_kind(); + try!(self.unify(&type_kind, kind)); Ok((variant.0.clone(), typ)) }) .collect()); - Ok((self.star_kind(), Type::variants(variants))) + Ok((self.type_kind(), Type::variants(variants))) } Type::Record { ref types, ref fields } => { let fields = try!(fields.iter() .map(|field| { let (kind, typ) = try!(self.kindcheck(&field.typ)); - let star = self.star_kind(); - try!(self.unify(&star, kind)); + let type_kind = self.type_kind(); + try!(self.unify(&type_kind, kind)); Ok(types::Field { name: field.name.clone(), typ: typ, }) }) .collect()); - Ok((self.star_kind(), Type::record(types.clone(), fields))) + Ok((self.type_kind(), Type::record(types.clone(), fields))) } Type::Id(ref id) => self.find(id).map(|kind| (kind, typ.clone())), Type::Alias(ref alias) => self.find(&alias.name).map(|kind| (kind, typ.clone())), @@ -232,7 +232,7 @@ impl<'a> KindCheck<'a> { } pub fn finalize_type(&self, typ: TcType) -> TcType { - let default = Some(&self.star_kind); + let default = Some(&self.type_kind); types::walk_move_type(typ, &mut |typ| { match *typ { @@ -251,7 +251,7 @@ impl<'a> KindCheck<'a> { } pub fn finalize_generic(&self, var: &Generic) -> Generic { let mut kind = var.kind.clone(); - kind = update_kind(&self.subs, kind, Some(&self.star_kind)); + kind = update_kind(&self.subs, kind, Some(&self.type_kind)); types::Generic { id: var.id.clone(), kind: kind, @@ -321,7 +321,7 @@ impl Substitutable for RcKind { walk_kind(r, f); } Kind::Variable(_) | - Kind::Star => (), + Kind::Type => (), } } walk_kind(self, &mut f) diff --git a/check/src/typecheck.rs b/check/src/typecheck.rs index 51f0671f88..76c7b9f5ff 100644 --- a/check/src/typecheck.rs +++ b/check/src/typecheck.rs @@ -139,7 +139,7 @@ impl<'a> KindEnv for Environment<'a> { self.stack_types .get(type_name) .map(|&(_, ref alias)| { - let mut kind = Kind::star(); + let mut kind = Kind::typ(); for arg in alias.args.iter().rev() { kind = Kind::function(arg.kind.clone(), kind); } @@ -720,10 +720,10 @@ impl<'a> Typecheck<'a> { // this type expression into the kindcheck environment for bind in bindings.iter_mut() { // Create the kind for this binding - // Test a b: 2 -> 1 -> * + // Test a b: 2 -> 1 -> Type // and bind the same variables to the arguments of the type binding // ('a' and 'b' in the example) - let mut id_kind = check.star_kind(); + let mut id_kind = check.type_kind(); let alias = Alias::make_mut(&mut bind.alias); for gen in alias.args.iter_mut().rev() { gen.kind = check.subs.new_var(); diff --git a/check/tests/functions.rs b/check/tests/functions.rs index c75465134b..eb4d1f85f7 100644 --- a/check/tests/functions.rs +++ b/check/tests/functions.rs @@ -55,7 +55,7 @@ struct EmptyEnv(Alias); impl KindEnv for EmptyEnv { fn find_kind(&self, id: &SymbolRef) -> Option { match id.as_ref() { - "Bool" => Some(Kind::star()), + "Bool" => Some(Kind::typ()), _ => None, } } @@ -129,7 +129,7 @@ pub fn typ_a(s: &str, args: Vec) -> T Ok(b) => Type::builtin(b), Err(()) if is_var => { Type::generic(Generic { - kind: Kind::star(), + kind: Kind::typ(), id: intern(s), }) } @@ -150,7 +150,7 @@ pub fn alias(s: &str, args: &[&str], typ: TcType) -> TcType { args.iter() .map(|id| { Generic { - kind: Kind::star(), + kind: Kind::typ(), id: intern(id), } }) diff --git a/check/tests/pass.rs b/check/tests/pass.rs index 477756fc12..9f500f2f61 100644 --- a/check/tests/pass.rs +++ b/check/tests/pass.rs @@ -448,7 +448,7 @@ return 1 Type::variants(vec![(intern(name), Type::function(vec![typ("a")], Type::app(typ(name), vec![typ("a")])))]); let test = alias("Test", &["a"], variant("Test")); let m = Generic { - kind: Kind::function(Kind::star(), Kind::star()), + kind: Kind::function(Kind::typ(), Kind::typ()), id: intern("m"), }; @@ -456,7 +456,7 @@ return 1 let id_t = Type::alias(intern("IdT"), vec![ m.clone(), Generic { - kind: Kind::star(), + kind: Kind::typ(), id: intern("a"), }], Type::app(Type::generic(m), vec![Type::app(id, vec![typ("a")])])); assert_eq!(result, Ok(Type::app(id_t, vec![test, typ("Int")]))); diff --git a/parser/src/lib.rs b/parser/src/lib.rs index d623e0bcdb..82e4ea2d94 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -761,7 +761,7 @@ pub fn parse_tc let mut env = ast::TcIdentEnv { typ: Type::variable(TypeVariable { id: 0, - kind: Kind::star(), + kind: Kind::typ(), }), env: symbols, }; diff --git a/src/repl.rs b/src/repl.rs index 192424e3a0..6921cd6228 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -31,7 +31,7 @@ fn find_kind(args: WithVM) -> IO> { let args = args.value.trim(); IO::Value(match vm.find_type_info(args) { Ok(ref alias) => { - let kind = alias.args.iter().rev().fold(Kind::star(), |acc, arg| { + let kind = alias.args.iter().rev().fold(Kind::typ(), |acc, arg| { Kind::function(arg.kind.clone(), acc) }); Ok(format!("{}", kind)) @@ -183,7 +183,7 @@ mod tests { compile_repl(&vm).unwrap_or_else(|err| panic!("{}", err)); let mut find_kind: FunctionRef = vm.get_global("repl_prim.find_kind").unwrap(); assert_eq!(find_kind.call("std.prelude.Option"), - Ok(IO::Value(Ok("* -> *".into())))); + Ok(IO::Value(Ok("Type -> Type".into())))); } #[test] diff --git a/vm/src/types.rs b/vm/src/types.rs index 335bde622a..d78fa31635 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -149,7 +149,7 @@ impl KindEnv for TypeInfos { self.id_to_type .get(type_name) .map(|alias| { - alias.args.iter().rev().fold(types::Kind::star(), |acc, arg| { + alias.args.iter().rev().fold(types::Kind::typ(), |acc, arg| { types::Kind::function(arg.kind.clone(), acc) }) }) diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 80f6e0e5bb..f88b1e8a85 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -391,7 +391,7 @@ impl GlobalVMState { } let g: TcType = Type::generic(types::Generic { id: Symbol::new(name), - kind: types::Kind::star(), + kind: types::Kind::typ(), }); generics.insert(name.into(), g.clone()); g