mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
Merge pull request #1500 from rtfeldman/constrain_run_low_level
Constrain Expr2::RunLowLevel
This commit is contained in:
commit
62d9f1570f
2 changed files with 65 additions and 2 deletions
|
@ -57,7 +57,7 @@ pub fn constrain_expr<'a>(
|
||||||
Expr2::Blank => True,
|
Expr2::Blank => True,
|
||||||
Expr2::EmptyRecord => constrain_empty_record(expected, region),
|
Expr2::EmptyRecord => constrain_empty_record(expected, region),
|
||||||
Expr2::Var(symbol) => Lookup(*symbol, expected, region),
|
Expr2::Var(symbol) => Lookup(*symbol, expected, region),
|
||||||
Expr2::SmallInt { var, .. } => {
|
Expr2::SmallInt { var, .. } | Expr2::I128 { var, .. } | Expr2::U128 { var, .. } => {
|
||||||
let mut flex_vars = BumpVec::with_capacity_in(1, arena);
|
let mut flex_vars = BumpVec::with_capacity_in(1, arena);
|
||||||
|
|
||||||
flex_vars.push(*var);
|
flex_vars.push(*var);
|
||||||
|
@ -910,7 +910,57 @@ pub fn constrain_expr<'a>(
|
||||||
|
|
||||||
exists(arena, flex_vars, And(cons))
|
exists(arena, flex_vars, And(cons))
|
||||||
}
|
}
|
||||||
_ => todo!("implement constraints for {:?}", expr),
|
|
||||||
|
Expr2::RunLowLevel { op, args, ret_var } => {
|
||||||
|
// This is a modified version of what we do for function calls.
|
||||||
|
|
||||||
|
// The operation's return type
|
||||||
|
let ret_type = Type2::Variable(*ret_var);
|
||||||
|
|
||||||
|
// This will be used in the occurs check
|
||||||
|
let mut vars = BumpVec::with_capacity_in(1 + args.len(), arena);
|
||||||
|
|
||||||
|
vars.push(*ret_var);
|
||||||
|
|
||||||
|
let mut arg_types = BumpVec::with_capacity_in(args.len(), arena);
|
||||||
|
let mut arg_cons = BumpVec::with_capacity_in(args.len(), arena);
|
||||||
|
|
||||||
|
for (index, node_id) in args.iter_node_ids().enumerate() {
|
||||||
|
let (arg_var, arg_id) = env.pool.get(node_id);
|
||||||
|
|
||||||
|
vars.push(*arg_var);
|
||||||
|
|
||||||
|
let arg_type = Type2::Variable(*arg_var);
|
||||||
|
|
||||||
|
let reason = Reason::LowLevelOpArg {
|
||||||
|
op: *op,
|
||||||
|
arg_index: Index::zero_based(index),
|
||||||
|
};
|
||||||
|
let expected_arg =
|
||||||
|
Expected::ForReason(reason, arg_type.shallow_clone(), Region::zero());
|
||||||
|
let arg = env.pool.get(*arg_id);
|
||||||
|
|
||||||
|
let arg_con = constrain_expr(arena, env, arg, expected_arg, Region::zero());
|
||||||
|
|
||||||
|
arg_types.push(arg_type);
|
||||||
|
arg_cons.push(arg_con);
|
||||||
|
}
|
||||||
|
|
||||||
|
let category = Category::LowLevelOpResult(*op);
|
||||||
|
|
||||||
|
let mut and_constraints = BumpVec::with_capacity_in(2, arena);
|
||||||
|
|
||||||
|
and_constraints.push(And(arg_cons));
|
||||||
|
and_constraints.push(Eq(ret_type, expected, category, region));
|
||||||
|
|
||||||
|
exists(arena, vars, And(and_constraints))
|
||||||
|
}
|
||||||
|
Expr2::Closure { .. } => todo!(),
|
||||||
|
Expr2::PrivateTag { .. } => todo!(),
|
||||||
|
Expr2::RuntimeError() => todo!(),
|
||||||
|
Expr2::InvalidLookup(_) => todo!(),
|
||||||
|
Expr2::LetRec { .. } => todo!(),
|
||||||
|
Expr2::LetFunction { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,3 +328,16 @@ fn constrain_update() {
|
||||||
"{ name : Str }",
|
"{ name : Str }",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ignore = "TODO: implement builtins in the editor"]
|
||||||
|
#[test]
|
||||||
|
fn constrain_run_low_level() {
|
||||||
|
infer_eq(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
List.map [ { name: "roc" }, { name: "bird" } ] .name
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
"List Str",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue