Fix some constraint gen

This commit is contained in:
Richard Feldman 2020-06-21 16:46:44 -04:00
parent 32b9b1ea60
commit 56c637e399
6 changed files with 93 additions and 70 deletions

View file

@ -778,8 +778,43 @@ pub fn constrain_expr(
exists(vars, And(arg_cons))
}
RunLowLevel { .. } => {
unreachable!("RunLowLevel should never participate in constraint generation.");
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.