From aee2389c06850703b37db197925bffee825b275a Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 1 Nov 2018 00:20:19 +0100 Subject: [PATCH] fix(check): Distionguish forall in the top of aliases These should be distinct but weren't due to weird quirk of how types were encoded ``` type Test a = | Test a type Test = forall a . | Test a ``` --- base/src/ast.rs | 10 +--- base/src/resolve.rs | 50 +++++++++++++++--- base/src/types/mod.rs | 54 +++++++------------- base/tests/types.rs | 28 ++++------ check/src/kindcheck.rs | 90 ++++++++++++++++++++++----------- check/src/typecheck.rs | 45 ++++++++--------- check/tests/forall.rs | 22 +++++++- check/tests/pass.rs | 13 +++-- check/tests/support/mod.rs | 12 ++--- completion/tests/support/mod.rs | 2 +- parser/src/grammar.lalrpop | 2 + parser/tests/basic.rs | 2 +- std/free.glu | 6 --- tests/api.rs | 2 +- vm/src/value.rs | 2 +- 15 files changed, 192 insertions(+), 148 deletions(-) diff --git a/base/src/ast.rs b/base/src/ast.rs index 7a9c0b34ec..972a019404 100644 --- a/base/src/ast.rs +++ b/base/src/ast.rs @@ -14,7 +14,7 @@ use ordered_float::NotNan; use pos::{self, BytePos, HasSpan, Span, Spanned}; use resolve::remove_aliases_cow; use symbol::Symbol; -use types::{self, Alias, AliasData, ArcType, ArgType, Generic, Type, TypeEnv}; +use types::{self, Alias, AliasData, ArcType, ArgType, Type, TypeEnv}; pub trait DisplayEnv { type Ident; @@ -148,14 +148,6 @@ impl AstType { self._typ.typ.value } - pub fn params_mut(&mut self) -> &mut [Generic] { - match self._typ.typ.value { - Type::Forall(ref mut params, _, _) => params, - Type::App(ref mut id, _) => id.params_mut(), - _ => &mut [], - } - } - pub fn remove_single_forall(&mut self) -> &mut AstType { match self._typ.typ.value { Type::Forall(_, ref mut typ, _) => typ, diff --git a/base/src/resolve.rs b/base/src/resolve.rs index 668fb132fc..a9337d1d58 100644 --- a/base/src/resolve.rs +++ b/base/src/resolve.rs @@ -5,7 +5,7 @@ use symbol::Symbol; use types::{AliasRef, ArcType, Type, TypeEnv}; quick_error! { - #[derive(Debug)] + #[derive(Debug, PartialEq)] pub enum Error { UndefinedType(id: Symbol) { description("undefined type") @@ -40,6 +40,40 @@ impl AliasRemover { self.reduced_aliases.truncate(to) } + pub fn canonical_alias<'t, F>( + &mut self, + env: &TypeEnv, + typ: &'t ArcType, + mut canonical: F, + ) -> Result, Error> + where + F: FnMut(&AliasRef) -> bool, + { + Ok(match peek_alias(env, typ) { + Ok(Some(alias)) => { + if self.reduced_aliases.contains(&alias.name) { + return Err(Error::SelfRecursiveAlias(alias.name.clone())); + } + self.reduced_aliases.push(alias.name.clone()); + + if canonical(alias) { + Cow::Borrowed(typ) + } else { + match alias + .typ() + .apply_args(alias.params(), &typ.unapplied_args()) + { + Some(typ) => { + Cow::Owned(self.canonical_alias(env, &typ, canonical)?.into_owned()) + } + None => Cow::Borrowed(typ), + } + } + } + _ => Cow::Borrowed(typ), + }) + } + pub fn remove_aliases(&mut self, env: &TypeEnv, mut typ: ArcType) -> Result { loop { typ = match self.remove_alias(env, &typ)? { @@ -58,10 +92,12 @@ impl AliasRemover { } self.reduced_aliases.push(alias.name.clone()); // Opaque types should only exist as the alias itself - if **alias.unresolved_type().remove_forall() == Type::Opaque { + if **alias.unresolved_type() == Type::Opaque { return Ok(None); } - Ok(alias.typ().apply_args(&typ.unapplied_args())) + Ok(alias + .typ() + .apply_args(alias.params(), &typ.unapplied_args())) } None => Ok(None), } @@ -96,7 +132,7 @@ where } else { alias .typ() - .apply_args(&typ.unapplied_args()) + .apply_args(alias.params(), &typ.unapplied_args()) .map(|typ| Cow::Owned(canonical_alias(env, &typ, canonical).into_owned())) .unwrap_or_else(|| Cow::Borrowed(typ)) } @@ -111,10 +147,12 @@ pub fn remove_alias(env: &TypeEnv, typ: &ArcType) -> Result, Err let typ = typ.skolemize(&mut FnvMap::default()); Ok(peek_alias(env, &typ)?.and_then(|alias| { // Opaque types should only exist as the alias itself - if **alias.unresolved_type().remove_forall() == Type::Opaque { + if **alias.unresolved_type() == Type::Opaque { return None; } - alias.typ().apply_args(&typ.unapplied_args()) + alias + .typ() + .apply_args(alias.params(), &typ.unapplied_args()) })) } diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs index 178a92d93d..24006c2b6e 100644 --- a/base/src/types/mod.rs +++ b/base/src/types/mod.rs @@ -330,7 +330,7 @@ where { fn from(data: AliasData) -> Alias { Alias { - _typ: Type::alias(data.name, data.typ), + _typ: Type::alias(data.name, data.args, data.typ), _marker: PhantomData, } } @@ -346,9 +346,9 @@ impl Alias where T: From>, { - pub fn new(name: Id, typ: T) -> Alias { + pub fn new(name: Id, args: Vec>, typ: T) -> Alias { Alias { - _typ: Type::alias(name, typ), + _typ: Type::alias(name, args, typ), _marker: PhantomData, } } @@ -496,6 +496,8 @@ where pub struct AliasData { #[cfg_attr(feature = "serde_derive", serde(state))] pub name: Id, + #[cfg_attr(feature = "serde_derive", serde(state))] + args: Vec>, /// The type that is being aliased #[cfg_attr(feature = "serde_derive", serde(state))] typ: T, @@ -518,10 +520,7 @@ where T: From>, { pub fn new(name: Id, args: Vec>, typ: T) -> AliasData { - AliasData { - name, - typ: Type::forall(args, typ), - } + AliasData { name, args, typ } } } @@ -530,14 +529,15 @@ where T: Deref>, { pub fn params(&self) -> &[Generic] { - self.typ.params() + &self.args + } + + pub fn params_mut(&mut self) -> &mut [Generic] { + &mut self.args } pub fn aliased_type(&self) -> &T { - match *self.typ { - Type::Forall(_, ref typ, _) => typ, - _ => &self.typ, - } + &self.typ } } @@ -862,10 +862,10 @@ where T::from(Type::Variable(typ)) } - pub fn alias(name: Id, typ: T) -> T { + pub fn alias(name: Id, args: Vec>, typ: T) -> T { T::from(Type::Alias(AliasRef { index: 0, - group: Arc::new(vec![AliasData { name, typ }]), + group: Arc::new(vec![AliasData { name, args, typ }]), })) } @@ -1363,22 +1363,6 @@ impl<'a, Id> Iterator for ForallScopeIter<'a, Id> { } impl ArcType { - pub fn params_mut(&mut self) -> &mut [Generic] { - use std::sync::Arc; - - match *Arc::make_mut(&mut self.typ) { - /* - // TODO - Type::Alias(ref mut alias) => { - Arc::make_mut(alias.unresolved_type_mut().typ).params_mut() - } - */ - Type::Forall(ref mut params, _, _) => params, - Type::App(ref mut id, _) => id.params_mut(), - _ => &mut [], - } - } - /// Applies a list of arguments to a parameterised type, returning `Some` /// if the substitution was successful. /// @@ -1389,9 +1373,8 @@ impl ArcType { /// args = [Error, Option a] /// result = | Err Error | Ok (Option a) /// ``` - pub fn apply_args(&self, args: &[ArcType]) -> Option { - let params = self.params(); - let typ = self.remove_forall().clone(); + pub fn apply_args(&self, params: &[Generic], args: &[ArcType]) -> Option { + let typ = self.clone(); // It is ok to take the type only if it is fully applied or if it // the missing argument only appears in order at the end, i.e: @@ -1424,7 +1407,7 @@ impl ArcType { return None; }; - Some(walk_move_type(typ.remove_forall().clone(), &mut |typ| { + Some(walk_move_type(typ.clone(), &mut |typ| { match **typ { Type::Generic(ref generic) => { // Replace the generic variable with the type from the list @@ -2101,7 +2084,7 @@ where if filter == Filter::RetainKey { arena.text("...") } else { - top(remove_forall(&field.typ.typ)).pretty(printer) + top(&field.typ.typ).pretty(printer) }, if i + 1 != types.len() || print_any_field { arena.text(",") @@ -2551,6 +2534,7 @@ where { AliasData { name: alias.name.clone(), + args: alias.args.clone(), typ: translate(&alias.typ), } } diff --git a/base/tests/types.rs b/base/tests/types.rs index 29d6cebed8..42479bf303 100644 --- a/base/tests/types.rs +++ b/base/tests/types.rs @@ -76,10 +76,7 @@ fn show_record_singleton_polymorphic() { let typ = Type::record( vec![Field::new( "Test", - Alias::new( - "Test", - Type::forall(vec![Generic::new("a", Kind::typ())], fun.clone()), - ), + Alias::new("Test", vec![Generic::new("a", Kind::typ())], fun.clone()), )], vec![], ); @@ -93,10 +90,7 @@ fn show_record_multifield() { let typ = Type::record( vec![Field::new( "Test", - Alias::new( - "Test", - Type::forall(vec![Generic::new("a", Kind::typ())], fun.clone()), - ), + Alias::new("Test", vec![Generic::new("a", Kind::typ())], fun.clone()), )], vec![Field::new("x", Type::int())], ); @@ -145,7 +139,10 @@ fn show_record_filtered() { let data = |s, a| ArcType::from(type_con(s, a)); let test = data("Test", vec![data("a", vec![])]); let record = Type::record( - vec![Field::new("Test", Alias::new("Test", Type::int()))], + vec![Field::new( + "Test", + Alias::new("Test", Vec::new(), Type::int()), + )], vec![ Field::new("x", Type::int()), Field::new("y", Type::int()), @@ -198,10 +195,7 @@ fn show_record_multi_line_nested() { let inner_record = Type::record( vec![Field::new( "Test", - Alias::new( - "Test", - Type::forall(vec![Generic::new("a", Kind::typ())], fun.clone()), - ), + Alias::new("Test", vec![Generic::new("a", Kind::typ())], fun.clone()), )], vec![ Field::new("x", Type::int()), @@ -215,10 +209,7 @@ fn show_record_multi_line_nested() { let record = Type::record( vec![Field::new( "Test", - Alias::new( - "Test", - Type::forall(vec![Generic::new("a", Kind::typ())], fun.clone()), - ), + Alias::new("Test", vec![Generic::new("a", Kind::typ())], fun.clone()), )], vec![ Field::new("x", Type::int()), @@ -292,7 +283,8 @@ fn show_polymorphic_record_associated_type() { "Test", Alias::new( "Test", - Type::forall(vec![Generic::new("a", Kind::typ())], Type::ident("a")), + vec![Generic::new("a", Kind::typ())], + Type::ident("a"), ), )]; let typ: ArcType<&str> = Type::poly_record(type_fields, vec![], Type::ident("r")); diff --git a/check/src/kindcheck.rs b/check/src/kindcheck.rs index 78d3210e11..f2038ff15e 100644 --- a/check/src/kindcheck.rs +++ b/check/src/kindcheck.rs @@ -171,6 +171,7 @@ impl<'a> KindCheck<'a> { typ: &mut AstType, expected: &ArcKind, ) -> Result { + info!("Kindchecking {}", typ); let kind = self.kindcheck(typ)?; let kind = self.unify(typ.span(), expected, kind)?; self.finalize_type(typ); @@ -272,10 +273,20 @@ impl<'a> KindCheck<'a> { } => { for field in types { if let Some(alias) = field.typ.try_get_alias_mut() { - let field_type = alias.unresolved_type_mut(); - let kind = self.kindcheck(field_type)?; - let type_kind = self.type_kind(); - self.unify(field_type.span(), &type_kind, kind)?; + for param in alias.params_mut() { + param.kind = self.subs.new_var(); + self.locals.push((param.id.clone(), param.kind.clone())); + } + + { + let field_type = alias.unresolved_type_mut(); + let kind = self.kindcheck(field_type)?; + let type_kind = self.type_kind(); + self.unify(field_type.span(), &type_kind, kind)?; + } + + let offset = self.locals.len() - alias.params().len(); + self.locals.drain(offset..); } } for field in fields { @@ -321,38 +332,57 @@ impl<'a> KindCheck<'a> { } pub fn finalize_type(&mut self, typ: &mut AstType) { + self.finalize_type_(typ); types::walk_type_mut(typ, &mut |typ: &mut AstType| { - if let Type::Ident(_) = **typ { - let id = match **typ { - Type::Ident(ref id) => id.clone(), - _ => unreachable!(), - }; - if let Ok(kind) = self.find(typ.span(), &id) { - // HACK Use a "generic" type as the rhs of the alias to make the type have the - // correct kind - **typ = Type::<_, AstType<_>>::alias( - id.clone(), - Type::generic(Generic::new(id, kind)), - ) - .into_inner(); - } - return; + self.finalize_type_(typ); + }); + } + fn finalize_type_(&mut self, typ: &mut AstType) { + if let Type::Ident(_) = **typ { + let id = match **typ { + Type::Ident(ref id) => id.clone(), + _ => unreachable!(), + }; + if let Ok(kind) = self.find(typ.span(), &id) { + // HACK Use a "generic" type as the rhs of the alias to make the type have the + // correct kind + **typ = Type::<_, AstType<_>>::alias( + id.clone(), + Vec::new(), + Type::generic(Generic::new(id, kind)), + ) + .into_inner(); } + return; + } - match **typ { - Type::Variable(ref mut var) => { - let default = Some(&self.kind_cache.typ); - var.kind = update_kind(&self.subs, var.kind.clone(), default); + match **typ { + Type::ExtendRow { ref mut types, .. } => types.iter_mut().for_each(|field| { + if let Some(alias) = field.typ.try_get_alias_mut() { + alias + .params_mut() + .iter_mut() + .for_each(|var| *var = self.finalize_generic(var)) } - Type::Generic(ref mut var) => *var = self.finalize_generic(var), - Type::Forall(ref mut params, _, _) => { - for param in params { - *param = self.finalize_generic(¶m); - } + }), + Type::Variable(ref mut var) => { + let default = Some(&self.kind_cache.typ); + var.kind = update_kind(&self.subs, var.kind.clone(), default); + } + Type::Generic(ref mut var) => *var = self.finalize_generic(var), + Type::Alias(ref mut alias) => alias + .try_get_alias_mut() + .expect("ICE: AstType did not provide mutable alias") + .params_mut() + .iter_mut() + .for_each(|var| *var = self.finalize_generic(var)), + Type::Forall(ref mut params, _, _) => { + for param in params { + *param = self.finalize_generic(¶m); } - _ => (), } - }); + _ => (), + } } pub fn finalize_generic(&self, var: &Generic) -> Generic { let mut kind = var.kind.clone(); diff --git a/check/src/typecheck.rs b/check/src/typecheck.rs index 90bdb08ad3..803a0008f8 100644 --- a/check/src/typecheck.rs +++ b/check/src/typecheck.rs @@ -437,7 +437,7 @@ impl<'a> Typecheck<'a> { span: span, value: err.into(), }); - Alias::new(id.clone(), self.type_cache.hole()) + Alias::new(id.clone(), Vec::new(), self.type_cache.hole()) } } } @@ -478,14 +478,17 @@ impl<'a> Typecheck<'a> { // Some "" // ``` let aliased_type = alias.typ(); - let canonical_alias_type = - resolve::canonical_alias(&self.environment, &aliased_type, |alias| { - match **alias.unresolved_type().remove_forall() { + let canonical_alias_type = resolve::AliasRemover::new() + .canonical_alias(&self.environment, &aliased_type, |alias| { + match **alias.unresolved_type() { Type::Variant(_) => true, _ => false, } + }) + .unwrap_or_else(|_err| { + // The error is reported in unification + aliased_type.clone() }); - fn unpack_canonical_alias<'a>( alias: &'a Alias, canonical_alias_type: &'a ArcType, @@ -529,8 +532,8 @@ impl<'a> Typecheck<'a> { .map(|f| f.typ.clone()) .collect::>(), Type::app( - alias.clone().into_type(), - alias + Type::Alias(canonical_alias.clone()).into(), + canonical_alias .params() .iter() .map(|g| Type::generic(g.clone())) @@ -1683,7 +1686,7 @@ impl<'a> Typecheck<'a> { ); // We still define the type so that any uses later on in the program // won't error on UndefinedType - alias = Alias::new(name.clone(), self.type_cache.hole()); + alias = Alias::new(name.clone(), Vec::new(), self.type_cache.hole()); &alias } }; @@ -1940,14 +1943,7 @@ impl<'a> Typecheck<'a> { // and bind the same variables to the arguments of the type binding // ('a' and 'b' in the example) let mut id_kind = check.type_kind(); - for generic in bind - .alias - .value - .unresolved_type_mut() - .params_mut() - .iter_mut() - .rev() - { + for generic in bind.alias.value.params_mut().iter_mut().rev() { check.instantiate_kinds(&mut generic.kind); id_kind = Kind::function(generic.kind.clone(), id_kind); } @@ -1971,9 +1967,11 @@ impl<'a> Typecheck<'a> { // All kinds are now inferred so replace the kinds store in the AST for bind in &mut *bindings { - let typ = bind.alias.value.unresolved_type_mut(); - check.finalize_type(typ); - for arg in typ.params_mut() { + { + let typ = bind.alias.value.unresolved_type_mut(); + check.finalize_type(typ); + } + for arg in bind.alias.value.params_mut() { *arg = check.finalize_generic(arg); } } @@ -1994,11 +1992,10 @@ impl<'a> Typecheck<'a> { .map(|param| (param.id.clone(), alias.unresolved_type().clone())), ); - let replacement = - self.create_unifiable_signature2(alias.unresolved_type().remove_forall()); + let replacement = self.create_unifiable_signature2(alias.unresolved_type()); if let Some(typ) = replacement { - *alias.unresolved_type_mut() = Type::forall(alias.params().to_owned(), typ); + *alias.unresolved_type_mut() = typ; } resolved_aliases.push(alias); } @@ -2284,7 +2281,7 @@ impl<'a> Typecheck<'a> { .unwrap_or_else(|| field.typ.unresolved_type().clone()); Some(Field::new( field.name.clone(), - Alias::new(field.typ.name.clone(), typ), + Alias::new(field.typ.name.clone(), field.typ.params().to_owned(), typ), )) }); let new_fields = types::walk_move_types(fields, |field| { @@ -2730,7 +2727,7 @@ impl<'a, 'b> Iterator for FunctionArgIter<'a, 'b> { return None; } last_alias = Some(alias.name.clone()); - match alias.typ().apply_args(&args) { + match alias.typ().apply_args(alias.params(), &args) { Some(typ) => (None, typ.clone()), None => return None, } diff --git a/check/tests/forall.rs b/check/tests/forall.rs index f963bd673e..dec8742e7a 100644 --- a/check/tests/forall.rs +++ b/check/tests/forall.rs @@ -655,11 +655,13 @@ make 1 assert_eq!( result.map(|x| x.to_string()), Ok("{ x : Int, cons : forall a . a -> test.List a }".to_string()) - ); + ) } #[test] fn resolve_app_app() { + let _ = env_logger::try_init(); + use base::resolve; let record = Type::record( @@ -1115,7 +1117,6 @@ let foo : (forall i . Proxy i -> ()) -> Proxy i -> () = assert!(result.is_ok(), "{}", result.unwrap_err()); } - #[test] fn forall_in_alias() { let _ = ::env_logger::try_init(); @@ -1133,3 +1134,20 @@ let z io : IO a -> Lift IO _ = Lift io assert!(result.is_ok(), "{}", result.unwrap_err()); } + +#[test] +#[ignore] +fn forall_in_alias() { + let _ = ::env_logger::try_init(); + + let text = r#" +type IO a = | IO a + +type Lift m v = forall a . { monad : m a } +let lift_io io : IO a -> _ = let z : Lift IO _ = { monad = io } in z +() +"#; + let result = support::typecheck(text); + + assert!(result.is_ok(), "{}", result.unwrap_err()); +} diff --git a/check/tests/pass.rs b/check/tests/pass.rs index 68eff7fc4e..fa8a35b85d 100644 --- a/check/tests/pass.rs +++ b/check/tests/pass.rs @@ -311,6 +311,7 @@ in eq_Int let result = support::typecheck(text); let bool = Type::alias( support::intern_unscoped("Bool"), + Vec::new(), Type::ident(support::intern_unscoped("Bool")), ); let eq = alias( @@ -530,7 +531,7 @@ type Test = | Test String Int in { Test, x = 1 } let test = Type::variant(vec![support::variant("Test", &[typ("String"), typ("Int")])]); let types = vec![Field { name: support::intern_unscoped("Test"), - typ: Alias::new(intern("Test"), test), + typ: Alias::new(intern("Test"), Vec::new(), test), }]; let fields = vec![Field { name: intern("x"), @@ -573,12 +574,10 @@ return 1 let id = support::alias_variant("Id", &["a"], &[("Id", &[typ("a")])]); let id_t = Type::alias( intern("IdT"), - Type::forall( - vec![m.clone(), Generic::new(intern("a"), Kind::typ())], - Type::app( - Type::generic(m), - collect![Type::app(id, collect![typ("a")])], - ), + vec![m.clone(), Generic::new(intern("a"), Kind::typ())], + Type::app( + Type::generic(m), + collect![Type::app(id, collect![typ("a")])], ), ); let expected = Ok(Type::app(id_t, collect![test, typ("Int")])); diff --git a/check/tests/support/mod.rs b/check/tests/support/mod.rs index 97775e5a20..e788d21a71 100644 --- a/check/tests/support/mod.rs +++ b/check/tests/support/mod.rs @@ -97,7 +97,7 @@ impl MockEnv { let bool_ty = Type::app(Type::ident(bool_sym.clone()), collect![]); MockEnv { - bool: Alias::new(bool_sym, bool_ty), + bool: Alias::new(bool_sym, Vec::new(), bool_ty), } } } @@ -291,12 +291,10 @@ pub fn alias(s: &str, args: &[&str], typ: ArcType) -> ArcType { assert!(s.len() != 0); Type::alias( intern(s), - Type::forall( - args.iter() - .map(|id| Generic::new(intern(id), Kind::typ())) - .collect(), - typ, - ), + args.iter() + .map(|id| Generic::new(intern(id), Kind::typ())) + .collect(), + typ, ) } diff --git a/completion/tests/support/mod.rs b/completion/tests/support/mod.rs index 9269f3be2d..1297610e3f 100644 --- a/completion/tests/support/mod.rs +++ b/completion/tests/support/mod.rs @@ -66,7 +66,7 @@ impl MockEnv { let bool_ty = Type::app(Type::ident(bool_sym.clone()), collect![]); MockEnv { - bool: Alias::new(bool_sym, bool_ty), + bool: Alias::new(bool_sym, Vec::new(), bool_ty), int: Type::int(), } } diff --git a/parser/src/grammar.lalrpop b/parser/src/grammar.lalrpop index 1239dee04f..410b8a7e45 100644 --- a/parser/src/grammar.lalrpop +++ b/parser/src/grammar.lalrpop @@ -216,6 +216,7 @@ RecordField: Either>>, Field>> = id.value.clone(), Alias::new( id.value, + Vec::new(), AstType::with_comment(comment, pos::spanned(span, Type::Hole)), ), )) @@ -229,6 +230,7 @@ RecordField: Either>>, Field>> = id.clone(), Alias::new( id, + Vec::new(), AstType::with_comment(comment, typ), ), )) diff --git a/parser/tests/basic.rs b/parser/tests/basic.rs index 48ab58a9b3..02270c7819 100644 --- a/parser/tests/basic.rs +++ b/parser/tests/basic.rs @@ -881,7 +881,7 @@ fn alias_in_record_type() { Type::record( vec![Field { name: intern("MyInt"), - typ: Alias::new(intern("MyInt"), Type::hole()), + typ: Alias::new(intern("MyInt"), Vec::new(), Type::hole()), }], vec![], ), diff --git a/std/free.glu b/std/free.glu index f599dfc555..b65fa6dd91 100644 --- a/std/free.glu +++ b/std/free.glu @@ -8,10 +8,4 @@ type FreeView f a b = | Return a | Bind (f b) (b -> Free f a) type ExpF f = Val -> Free f Val -let functor : Functor (Free f) = { - map = \f xs -> - match xs with - | Free -} - { Free } diff --git a/tests/api.rs b/tests/api.rs index 970ec9e1d8..a768653edc 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -317,7 +317,7 @@ fn use_type_from_type_field() { let (name, typ) = gluon::vm::api::typ::from_rust::(vm).unwrap(); vm.register_type_as( name.clone(), - Alias::new(name, typ), + Alias::new(name, Vec::new(), typ), ::std::any::TypeId::of::(), ) .unwrap() diff --git a/vm/src/value.rs b/vm/src/value.rs index 13b6e47aef..347ffcd742 100644 --- a/vm/src/value.rs +++ b/vm/src/value.rs @@ -1604,7 +1604,7 @@ mod tests { }, ]); - let env = MockEnv(Some(Alias::new(list.clone(), typ.clone()))); + let env = MockEnv(Some(Alias::new(list.clone(), Vec::new(), typ.clone()))); let nil = Value::tag(1); assert_eq!(