Get low-level ops compiling

This commit is contained in:
Richard Feldman 2020-06-19 17:52:16 -04:00
parent b75f061f4f
commit dec5c3a062
19 changed files with 447 additions and 296 deletions

View file

@ -778,9 +778,45 @@ pub fn constrain_expr(
exists(vars, And(arg_cons))
}
RuntimeError(_) | RunLowLevel(_) => {
// RunLowLevel can only be added by the compiler, so it's safe
// to assume its constraints have already been accounted for.
RunLowLevel { args, ret_var, op } => {
// This is a modified version of what we do for function calls.
// The operation's return type
let ret_type = Variable(*ret_var);
// This will be used in the occurs check
let mut vars = Vec::with_capacity(1 + args.len());
vars.push(*ret_var);
let mut arg_types = Vec::with_capacity(args.len());
let mut arg_cons = Vec::with_capacity(args.len());
for (index, (arg_var, arg)) in args.iter().enumerate() {
let arg_type = Variable(*arg_var);
let reason = Reason::LowLevelOpArg {
op: *op,
arg_index: Index::zero_based(index),
};
let expected_arg = ForReason(reason, arg_type.clone(), Region::zero());
let arg_con = constrain_expr(env, Region::zero(), arg, expected_arg);
vars.push(*arg_var);
arg_types.push(arg_type);
arg_cons.push(arg_con);
}
let category = Category::LowLevelOpResult(*op);
exists(
vars,
And(vec![
And(arg_cons),
Eq(ret_type, expected, category, region),
]),
)
}
RuntimeError(_) => {
// Runtime Errors have no constraints because they're going to crash.
True
}