From 4862409b1d71f8268dfb5174cf534b789279190e Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 20 Dec 2019 19:44:19 +0100 Subject: [PATCH] add .foo record accessors --- src/can/expr.rs | 31 +++++++++++++++++++++++++++++-- tests/test_infer.rs | 5 +++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/can/expr.rs b/src/can/expr.rs index b2c959bf40..061ab1ad4a 100644 --- a/src/can/expr.rs +++ b/src/can/expr.rs @@ -60,6 +60,8 @@ pub enum Expr { /// Look up exactly one field on a record, e.g. (expr).foo. Access(Box>, Box), + /// field accessor as a function, e.g. (.foo) expr + Accessor(Box), Tag(Box, Vec), @@ -714,8 +716,33 @@ pub fn canonicalize_expr( constraint, ) } - ast::Expr::AccessorFunction(_) - | ast::Expr::If(_) + ast::Expr::AccessorFunction(field) => { + let ext_var = var_store.fresh(); + let ext_type = Variable(ext_var); + + let field_var = var_store.fresh(); + let field_type = Variable(field_var); + + let mut field_types = SendMap::default(); + let field_name: Lowercase = (*field).into(); + field_types.insert(field_name.clone(), field_type.clone()); + let record_type = Type::Record(field_types, Box::new(ext_type)); + + ( + Accessor(field_name.into()), + Output::default(), + exists( + vec![field_var, ext_var], + Eq( + Type::Function(vec![record_type], Box::new(field_type)), + expected, + region, + ), + ), + ) + } + + ast::Expr::If(_) | ast::Expr::GlobalTag(_) | ast::Expr::PrivateTag(_) | ast::Expr::MalformedIdent(_) diff --git a/tests/test_infer.rs b/tests/test_infer.rs index 9bac9d0c1a..a5f245cc2c 100644 --- a/tests/test_infer.rs +++ b/tests/test_infer.rs @@ -869,4 +869,9 @@ mod test_infer { "custom -> custom", ); } + + #[test] + fn accessor_function() { + infer_eq(".foo", "{ foo : a }* -> a"); + } }