From f285e7ce930b3b79b63ee172c79d9c8b1d427425 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 18 May 2022 16:39:24 +0200 Subject: [PATCH] add a TypedHole node to Expr, for use in the editor --- compiler/can/src/expr.rs | 12 +++++++++--- compiler/can/src/module.rs | 1 + compiler/can/src/traverse.rs | 1 + compiler/constrain/src/expr.rs | 9 +++++++++ compiler/mono/src/copy.rs | 2 ++ compiler/mono/src/ir.rs | 1 + 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/compiler/can/src/expr.rs b/compiler/can/src/expr.rs index ec1c8080bb..e2db985092 100644 --- a/compiler/can/src/expr.rs +++ b/compiler/can/src/expr.rs @@ -204,10 +204,13 @@ pub enum Expr { lambda_set_variables: Vec, }, - // Test + /// Test Expect(Box>, Box>), - // Compiles, but will crash if reached + /// Rendered as empty box in editor + TypedHole(Variable), + + /// Compiles, but will crash if reached RuntimeError(RuntimeError), } @@ -247,7 +250,9 @@ impl Expr { }, &Self::OpaqueRef { name, .. } => Category::OpaqueWrap(name), Self::Expect(..) => Category::Expect, - Self::RuntimeError(..) => Category::Unknown, + + // these nodes place no constraints on the expression's type + Self::TypedHole(_) | Self::RuntimeError(..) => Category::Unknown, } } } @@ -1391,6 +1396,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) -> | other @ Var(_) | other @ AbilityMember(..) | other @ RunLowLevel { .. } + | other @ TypedHole { .. } | other @ ForeignCall { .. } => other, List { diff --git a/compiler/can/src/module.rs b/compiler/can/src/module.rs index 4abd93c703..e93e17b7c7 100644 --- a/compiler/can/src/module.rs +++ b/compiler/can/src/module.rs @@ -710,6 +710,7 @@ fn fix_values_captured_in_closure_expr( | Var(_) | AbilityMember(..) | EmptyRecord + | TypedHole { .. } | RuntimeError(_) | ZeroArgumentTag { .. } | Accessor { .. } => {} diff --git a/compiler/can/src/traverse.rs b/compiler/can/src/traverse.rs index 5938c2fc3a..71f61f7f82 100644 --- a/compiler/can/src/traverse.rs +++ b/compiler/can/src/traverse.rs @@ -168,6 +168,7 @@ pub fn walk_expr(visitor: &mut V, expr: &Expr, var: Variable) { visitor.visit_expr(&e1.value, e1.region, Variable::NULL); visitor.visit_expr(&e2.value, e2.region, Variable::NULL); } + Expr::TypedHole(_) => { /* terminal */ } Expr::RuntimeError(..) => { /* terminal */ } } } diff --git a/compiler/constrain/src/expr.rs b/compiler/constrain/src/expr.rs index 83abcc8f71..5a106697cc 100644 --- a/compiler/constrain/src/expr.rs +++ b/compiler/constrain/src/expr.rs @@ -1144,6 +1144,15 @@ pub fn constrain_expr( arg_cons.push(eq); constraints.exists_many(vars, arg_cons) } + TypedHole(var) => { + // store the expected type for this position + constraints.equal_types_var( + *var, + expected, + Category::Storage(std::file!(), std::line!()), + region, + ) + } RuntimeError(_) => { // Runtime Errors have no constraints because they're going to crash. Constraint::True diff --git a/compiler/mono/src/copy.rs b/compiler/mono/src/copy.rs index 35c94df620..b4dc4348d7 100644 --- a/compiler/mono/src/copy.rs +++ b/compiler/mono/src/copy.rs @@ -366,6 +366,8 @@ pub fn deep_copy_type_vars_into_expr<'a>( Expect(e1, e2) => Expect(Box::new(e1.map(go_help)), Box::new(e2.map(go_help))), + TypedHole(v) => TypedHole(sub!(*v)), + RuntimeError(err) => RuntimeError(err.clone()), } } diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index e57a76a69a..cb5aa3115e 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -5235,6 +5235,7 @@ pub fn with_hole<'a>( } } } + TypedHole(_) => Stmt::RuntimeError("Hit a blank"), RuntimeError(e) => Stmt::RuntimeError(env.arena.alloc(format!("{:?}", e))), } }