From 203f7a8f55ee63b4a8026f5b9b067081cb3de810 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 25 Oct 2018 08:25:56 +0200 Subject: [PATCH] Row polymorphic variants --- check/src/typecheck.rs | 8 ++++++++ check/tests/pass.rs | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/check/src/typecheck.rs b/check/src/typecheck.rs index ae8f40aedf..03c62c7744 100644 --- a/check/src/typecheck.rs +++ b/check/src/typecheck.rs @@ -1984,6 +1984,13 @@ impl<'a> Typecheck<'a> { self.translate_ast_type(&type_cache, typ) }); + if let Type::Variant(ref row) = **alias.unresolved_type().remove_forall() { + for field in row.row_iter() { + let symbol = self.symbols.scoped_symbol(field.name.as_ref()); + self.original_symbols.insert(field.name.clone(), symbol); + } + } + // alias.unresolved_type() is a dummy in this context self.named_variables.extend( alias @@ -1994,6 +2001,7 @@ impl<'a> Typecheck<'a> { let replacement = self.create_unifiable_signature2(alias.unresolved_type()); + if let Some(typ) = replacement { *alias.unresolved_type_mut() = typ; } diff --git a/check/tests/pass.rs b/check/tests/pass.rs index fa8a35b85d..1eac439622 100644 --- a/check/tests/pass.rs +++ b/check/tests/pass.rs @@ -970,3 +970,23 @@ fn consider_the_type_of_the_splat_record() { assert_req!(result.map(|t| t.to_string()), Ok("{ x : Int, y : Int }")); } + +#[test] +fn polymorphic_variants() { + let _ = env_logger::try_init(); + + let text = r#" +type AA r = (| A Int .. r) +type BB r = (| B String .. r) +if True then + A 123 +else + B "abc" +"#; + let result = support::typecheck(text); + + assert_req!( + result.map(|t| t.to_string()), + Ok("forall a . | test.A Int | test.B String | a") + ); +}