mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
remove Output from uniq infer
This commit is contained in:
parent
ab54e8ad29
commit
c665eccf11
3 changed files with 72 additions and 136 deletions
|
@ -1,11 +1,10 @@
|
||||||
use crate::can::def::Def;
|
use crate::can::def::Def;
|
||||||
use crate::can::expr::Expr;
|
use crate::can::expr::Expr;
|
||||||
use crate::can::expr::Field;
|
use crate::can::expr::Field;
|
||||||
use crate::can::expr::Output;
|
|
||||||
use crate::can::ident::Lowercase;
|
use crate::can::ident::Lowercase;
|
||||||
use crate::can::pattern;
|
use crate::can::pattern;
|
||||||
use crate::can::pattern::{Pattern, RecordDestruct};
|
use crate::can::pattern::{Pattern, RecordDestruct};
|
||||||
use crate::can::procedure::{Procedure, References};
|
use crate::can::procedure::Procedure;
|
||||||
use crate::can::symbol::Symbol;
|
use crate::can::symbol::Symbol;
|
||||||
use crate::collections::{ImMap, SendMap};
|
use crate::collections::{ImMap, SendMap};
|
||||||
use crate::constrain::expr::{Info, Rigids};
|
use crate::constrain::expr::{Info, Rigids};
|
||||||
|
@ -41,7 +40,7 @@ pub fn constrain_declaration(
|
||||||
loc_expr: Located<Expr>,
|
loc_expr: Located<Expr>,
|
||||||
_declared_idents: &ImMap<Ident, (Symbol, Region)>,
|
_declared_idents: &ImMap<Ident, (Symbol, Region)>,
|
||||||
expected: Expected<Type>,
|
expected: Expected<Type>,
|
||||||
) -> (Output, Constraint) {
|
) -> Constraint {
|
||||||
let rigids = ImMap::default();
|
let rigids = ImMap::default();
|
||||||
let mut var_usage = VarUsage::default();
|
let mut var_usage = VarUsage::default();
|
||||||
|
|
||||||
|
@ -172,44 +171,32 @@ pub fn constrain_expr(
|
||||||
region: Region,
|
region: Region,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
expected: Expected<Type>,
|
expected: Expected<Type>,
|
||||||
) -> (Output, Constraint) {
|
) -> Constraint {
|
||||||
pub use crate::can::expr::Expr::*;
|
pub use crate::can::expr::Expr::*;
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
Int(_, _) => {
|
Int(_, _) => constrain::int_literal(var_store, expected, region),
|
||||||
let constraint = constrain::int_literal(var_store, expected, region);
|
Float(_, _) => constrain::float_literal(var_store, expected, region),
|
||||||
(Output::default(), constraint)
|
|
||||||
}
|
|
||||||
Float(_, _) => {
|
|
||||||
let constraint = constrain::float_literal(var_store, expected, region);
|
|
||||||
(Output::default(), constraint)
|
|
||||||
}
|
|
||||||
BlockStr(_) | Str(_) => {
|
BlockStr(_) | Str(_) => {
|
||||||
let inferred = constrain::lift(var_store, constrain::str_type());
|
let inferred = constrain::lift(var_store, constrain::str_type());
|
||||||
let constraint = Eq(inferred, expected, region);
|
Eq(inferred, expected, region)
|
||||||
(Output::default(), constraint)
|
|
||||||
}
|
|
||||||
EmptyRecord => {
|
|
||||||
let constraint = Eq(constrain::lift(var_store, EmptyRec), expected, region);
|
|
||||||
|
|
||||||
(Output::default(), constraint)
|
|
||||||
}
|
}
|
||||||
|
EmptyRecord => Eq(constrain::lift(var_store, EmptyRec), expected, region),
|
||||||
Record(variable, fields) => {
|
Record(variable, fields) => {
|
||||||
// NOTE: canonicalization guarantees at least one field
|
// NOTE: canonicalization guarantees at least one field
|
||||||
// zero fields generates an EmptyRecord
|
// zero fields generates an EmptyRecord
|
||||||
let mut field_types = SendMap::default();
|
let mut field_types = SendMap::default();
|
||||||
let mut field_vars = Vec::with_capacity(fields.len());
|
let mut field_vars = Vec::with_capacity(fields.len());
|
||||||
|
|
||||||
// Constraints need capacity for each field + 1 for the record itself.
|
// Constraints need capacity for each field + 1 for the record itself + 1 for ext
|
||||||
let mut constraints = Vec::with_capacity(1 + fields.len());
|
let mut constraints = Vec::with_capacity(2 + fields.len());
|
||||||
let mut output = Output::default();
|
|
||||||
|
|
||||||
for (label, ref field) in fields.iter() {
|
for (label, ref field) in fields.iter() {
|
||||||
let field_var = var_store.fresh();
|
let field_var = var_store.fresh();
|
||||||
let field_type = Variable(field_var);
|
let field_type = Variable(field_var);
|
||||||
let field_expected = Expected::NoExpectation(field_type.clone());
|
let field_expected = Expected::NoExpectation(field_type.clone());
|
||||||
let loc_expr = &*field.loc_expr;
|
let loc_expr = &*field.loc_expr;
|
||||||
let (field_out, field_con) = constrain_expr(
|
let field_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -222,7 +209,6 @@ pub fn constrain_expr(
|
||||||
field_types.insert(label.clone(), field_type);
|
field_types.insert(label.clone(), field_type);
|
||||||
|
|
||||||
constraints.push(field_con);
|
constraints.push(field_con);
|
||||||
output.references = output.references.union(field_out.references);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let record_type = constrain::lift(
|
let record_type = constrain::lift(
|
||||||
|
@ -243,7 +229,7 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
let constraint = exists(field_vars, And(constraints));
|
let constraint = exists(field_vars, And(constraints));
|
||||||
|
|
||||||
(output, constraint)
|
(constraint)
|
||||||
}
|
}
|
||||||
Tag { .. } => {
|
Tag { .. } => {
|
||||||
panic!("TODO implement tag");
|
panic!("TODO implement tag");
|
||||||
|
@ -252,14 +238,12 @@ pub fn constrain_expr(
|
||||||
if loc_elems.is_empty() {
|
if loc_elems.is_empty() {
|
||||||
let list_var = *variable;
|
let list_var = *variable;
|
||||||
let inferred = constrain::lift(var_store, constrain::empty_list_type(list_var));
|
let inferred = constrain::lift(var_store, constrain::empty_list_type(list_var));
|
||||||
let constraint = Eq(inferred, expected, region);
|
Eq(inferred, expected, region)
|
||||||
(Output::default(), constraint)
|
|
||||||
} else {
|
} else {
|
||||||
// constrain `expected ~ List a` and that all elements `~ a`.
|
// constrain `expected ~ List a` and that all elements `~ a`.
|
||||||
let list_var = *variable; // `v` in the type (List v)
|
let list_var = *variable; // `v` in the type (List v)
|
||||||
let list_type = Type::Variable(list_var);
|
let list_type = Type::Variable(list_var);
|
||||||
let mut constraints = Vec::with_capacity(1 + (loc_elems.len() * 2));
|
let mut constraints = Vec::with_capacity(1 + (loc_elems.len() * 2));
|
||||||
let mut references = References::new();
|
|
||||||
|
|
||||||
for (elem_var, loc_elem) in loc_elems.iter() {
|
for (elem_var, loc_elem) in loc_elems.iter() {
|
||||||
let elem_type = Variable(*elem_var);
|
let elem_type = Variable(*elem_var);
|
||||||
|
@ -269,7 +253,7 @@ pub fn constrain_expr(
|
||||||
Expected::ForReason(Reason::ElemInList, elem_type, region),
|
Expected::ForReason(Reason::ElemInList, elem_type, region),
|
||||||
region,
|
region,
|
||||||
);
|
);
|
||||||
let (elem_out, constraint) = constrain_expr(
|
let constraint = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -280,20 +264,11 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
constraints.push(list_elem_constraint);
|
constraints.push(list_elem_constraint);
|
||||||
constraints.push(constraint);
|
constraints.push(constraint);
|
||||||
|
|
||||||
references = references.union(elem_out.references);
|
|
||||||
}
|
}
|
||||||
let inferred = constrain::lift(var_store, constrain::list_type(list_type));
|
let inferred = constrain::lift(var_store, constrain::list_type(list_type));
|
||||||
constraints.push(Eq(inferred, expected, region));
|
constraints.push(Eq(inferred, expected, region));
|
||||||
|
|
||||||
let mut output = Output::default();
|
And(constraints)
|
||||||
|
|
||||||
output.references = references;
|
|
||||||
|
|
||||||
// A list literal is never a tail call!
|
|
||||||
output.tail_call = None;
|
|
||||||
|
|
||||||
(output, And(constraints))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Var {
|
Var {
|
||||||
|
@ -311,30 +286,24 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
let attr_type = constrain::attr_type(uniq_type.clone(), val_type);
|
let attr_type = constrain::attr_type(uniq_type.clone(), val_type);
|
||||||
|
|
||||||
(
|
And(vec![
|
||||||
Output::default(),
|
Lookup(symbol_for_lookup.clone(), expected.clone(), region),
|
||||||
And(vec![
|
Eq(attr_type, expected, region),
|
||||||
Lookup(symbol_for_lookup.clone(), expected.clone(), region),
|
Eq(
|
||||||
Eq(attr_type, expected, region),
|
uniq_type,
|
||||||
Eq(
|
Expected::NoExpectation(constrain::shared_type()),
|
||||||
uniq_type,
|
region,
|
||||||
Expected::NoExpectation(constrain::shared_type()),
|
),
|
||||||
region,
|
])
|
||||||
),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Some(sharing::ReferenceCount::Unique) => {
|
Some(sharing::ReferenceCount::Unique) => {
|
||||||
// no additional constraints, keep uniqueness unbound
|
// no additional constraints, keep uniqueness unbound
|
||||||
(
|
Lookup(symbol_for_lookup.clone(), expected.clone(), region)
|
||||||
Output::default(),
|
|
||||||
Lookup(symbol_for_lookup.clone(), expected.clone(), region),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
None => panic!("symbol not analyzed"),
|
None => panic!("symbol not analyzed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Closure(_fn_var, _symbol, _recursion, args, boxed_body) => {
|
Closure(fn_var, _symbol, _recursion, args, boxed_body) => {
|
||||||
let (body, ret_var) = &**boxed_body;
|
let (body, ret_var) = &**boxed_body;
|
||||||
|
|
||||||
// first, generate constraints for the arguments
|
// first, generate constraints for the arguments
|
||||||
|
@ -371,7 +340,7 @@ pub fn constrain_expr(
|
||||||
Type::Function(arg_types, Box::new(ret_type.clone())),
|
Type::Function(arg_types, Box::new(ret_type.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (output, ret_constraint) = constrain_expr(
|
let ret_constraint = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -388,7 +357,7 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
|
|
||||||
let defs_constraint = And(state.constraints);
|
let defs_constraint = And(state.constraints);
|
||||||
let constraint = exists(
|
exists(
|
||||||
vars,
|
vars,
|
||||||
And(vec![
|
And(vec![
|
||||||
Let(Box::new(LetConstraint {
|
Let(Box::new(LetConstraint {
|
||||||
|
@ -399,11 +368,10 @@ pub fn constrain_expr(
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
// "the closure's type is equal to expected type"
|
// "the closure's type is equal to expected type"
|
||||||
Eq(fn_typ, expected, region),
|
Eq(fn_typ, expected.clone(), region),
|
||||||
|
Eq(Type::Variable(*fn_var), expected, region),
|
||||||
]),
|
]),
|
||||||
);
|
)
|
||||||
|
|
||||||
(output, constraint)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Call(boxed, loc_args, _) => {
|
Call(boxed, loc_args, _) => {
|
||||||
|
@ -416,7 +384,7 @@ pub fn constrain_expr(
|
||||||
let mut vars = Vec::with_capacity(2 + loc_args.len());
|
let mut vars = Vec::with_capacity(2 + loc_args.len());
|
||||||
|
|
||||||
// Canonicalize the function expression and its arguments
|
// Canonicalize the function expression and its arguments
|
||||||
let (_, fn_con) = constrain_expr(
|
let fn_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -442,7 +410,7 @@ pub fn constrain_expr(
|
||||||
};
|
};
|
||||||
|
|
||||||
let expected_arg = Expected::ForReason(reason, arg_type.clone(), region);
|
let expected_arg = Expected::ForReason(reason, arg_type.clone(), region);
|
||||||
let (_, arg_con) = constrain_expr(
|
let arg_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -462,23 +430,20 @@ pub fn constrain_expr(
|
||||||
region,
|
region,
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
exists(
|
||||||
Output::default(),
|
vars,
|
||||||
exists(
|
And(vec![
|
||||||
vars,
|
fn_con,
|
||||||
And(vec![
|
Eq(fn_type, expected_fn_type, fn_region),
|
||||||
fn_con,
|
And(arg_cons),
|
||||||
Eq(fn_type, expected_fn_type, fn_region),
|
Eq(ret_type, expected, region),
|
||||||
And(arg_cons),
|
]),
|
||||||
Eq(ret_type, expected, region),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LetRec(defs, loc_ret, _) => {
|
LetRec(defs, loc_ret, _) => {
|
||||||
// NOTE doesn't currently unregister bound symbols
|
// NOTE doesn't currently unregister bound symbols
|
||||||
// may be a problem when symbols are not globally unique
|
// may be a problem when symbols are not globally unique
|
||||||
let (_, body_con) = constrain_expr(
|
let body_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -486,15 +451,12 @@ pub fn constrain_expr(
|
||||||
&loc_ret.value,
|
&loc_ret.value,
|
||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
(
|
constrain_recursive_defs(rigids, var_store, var_usage, defs, body_con)
|
||||||
Output::default(),
|
|
||||||
constrain_recursive_defs(rigids, var_store, var_usage, defs, body_con),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
LetNonRec(def, loc_ret, _) => {
|
LetNonRec(def, loc_ret, _) => {
|
||||||
// NOTE doesn't currently unregister bound symbols
|
// NOTE doesn't currently unregister bound symbols
|
||||||
// may be a problem when symbols are not globally unique
|
// may be a problem when symbols are not globally unique
|
||||||
let (_, body_con) = constrain_expr(
|
let body_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -503,10 +465,7 @@ pub fn constrain_expr(
|
||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
constrain_def(rigids, var_store, var_usage, def, body_con)
|
||||||
Output::default(),
|
|
||||||
constrain_def(rigids, var_store, var_usage, def, body_con),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
When {
|
When {
|
||||||
cond_var,
|
cond_var,
|
||||||
|
@ -516,7 +475,7 @@ pub fn constrain_expr(
|
||||||
} => {
|
} => {
|
||||||
let cond_var = *cond_var;
|
let cond_var = *cond_var;
|
||||||
let cond_type = Variable(cond_var);
|
let cond_type = Variable(cond_var);
|
||||||
let (mut output, expr_con) = constrain_expr(
|
let expr_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -551,7 +510,6 @@ pub fn constrain_expr(
|
||||||
TypedWhenBranch(index),
|
TypedWhenBranch(index),
|
||||||
typ.clone(),
|
typ.clone(),
|
||||||
),
|
),
|
||||||
&mut output,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// required for a case like
|
// required for a case like
|
||||||
|
@ -600,7 +558,6 @@ pub fn constrain_expr(
|
||||||
branch_type.clone(),
|
branch_type.clone(),
|
||||||
region,
|
region,
|
||||||
),
|
),
|
||||||
&mut output,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// required for a case like
|
// required for a case like
|
||||||
|
@ -635,7 +592,7 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(output, And(constraints))
|
And(constraints)
|
||||||
}
|
}
|
||||||
|
|
||||||
Update {
|
Update {
|
||||||
|
@ -647,7 +604,7 @@ pub fn constrain_expr(
|
||||||
} => {
|
} => {
|
||||||
let mut fields: SendMap<Lowercase, Type> = SendMap::default();
|
let mut fields: SendMap<Lowercase, Type> = SendMap::default();
|
||||||
let mut vars = Vec::with_capacity(updates.len() + 2);
|
let mut vars = Vec::with_capacity(updates.len() + 2);
|
||||||
let mut cons = Vec::with_capacity(updates.len() + 1);
|
let mut cons = Vec::with_capacity(updates.len() + 3);
|
||||||
for (field_name, Field { var, loc_expr, .. }) in updates.clone() {
|
for (field_name, Field { var, loc_expr, .. }) in updates.clone() {
|
||||||
let (var, tipe, con) = constrain_field_update(
|
let (var, tipe, con) = constrain_field_update(
|
||||||
rigids,
|
rigids,
|
||||||
|
@ -694,7 +651,7 @@ pub fn constrain_expr(
|
||||||
cons.push(fields_con);
|
cons.push(fields_con);
|
||||||
cons.push(record_con);
|
cons.push(record_con);
|
||||||
|
|
||||||
(Output::default(), exists(vars, And(cons)))
|
exists(vars, And(cons))
|
||||||
}
|
}
|
||||||
|
|
||||||
Access {
|
Access {
|
||||||
|
@ -714,7 +671,7 @@ pub fn constrain_expr(
|
||||||
constrain::lift(var_store, Type::Record(rec_field_types, Box::new(ext_type)));
|
constrain::lift(var_store, Type::Record(rec_field_types, Box::new(ext_type)));
|
||||||
let record_expected = Expected::NoExpectation(record_type);
|
let record_expected = Expected::NoExpectation(record_type);
|
||||||
|
|
||||||
let (output, mut constraint) = constrain_expr(
|
let mut constraint = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -728,7 +685,7 @@ pub fn constrain_expr(
|
||||||
And(vec![constraint, Eq(field_type, expected, region)]),
|
And(vec![constraint, Eq(field_type, expected, region)]),
|
||||||
);
|
);
|
||||||
|
|
||||||
(output, constraint)
|
constraint
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessor {
|
Accessor {
|
||||||
|
@ -745,20 +702,16 @@ pub fn constrain_expr(
|
||||||
let record_type =
|
let record_type =
|
||||||
constrain::lift(var_store, Type::Record(field_types, Box::new(ext_type)));
|
constrain::lift(var_store, Type::Record(field_types, Box::new(ext_type)));
|
||||||
|
|
||||||
(
|
exists(
|
||||||
Output::default(),
|
vec![*field_var, *ext_var],
|
||||||
exists(
|
Eq(
|
||||||
vec![*field_var, *ext_var],
|
Type::Function(vec![record_type], Box::new(field_type)),
|
||||||
Eq(
|
expected,
|
||||||
Type::Function(vec![record_type], Box::new(field_type)),
|
region,
|
||||||
expected,
|
|
||||||
region,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
RuntimeError(_) => (Output::default(), True),
|
RuntimeError(_) => True,
|
||||||
// _ => panic!("{:?}", expr),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,9 +727,8 @@ fn constrain_when_branch(
|
||||||
loc_expr: &Located<Expr>,
|
loc_expr: &Located<Expr>,
|
||||||
pattern_expected: PExpected<Type>,
|
pattern_expected: PExpected<Type>,
|
||||||
expr_expected: Expected<Type>,
|
expr_expected: Expected<Type>,
|
||||||
_output: &mut Output,
|
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let (_, ret_constraint) = constrain_expr(
|
let ret_constraint = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -877,19 +829,15 @@ pub fn constrain_def(
|
||||||
&def.loc_expr.value,
|
&def.loc_expr.value,
|
||||||
annotation_expected,
|
annotation_expected,
|
||||||
)
|
)
|
||||||
.1
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
constrain_expr(
|
|
||||||
rigids,
|
|
||||||
var_store,
|
|
||||||
var_usage,
|
|
||||||
def.loc_expr.region,
|
|
||||||
&def.loc_expr.value,
|
|
||||||
Expected::NoExpectation(expr_type),
|
|
||||||
)
|
|
||||||
.1
|
|
||||||
}
|
}
|
||||||
|
None => constrain_expr(
|
||||||
|
rigids,
|
||||||
|
var_store,
|
||||||
|
var_usage,
|
||||||
|
def.loc_expr.region,
|
||||||
|
&def.loc_expr.value,
|
||||||
|
Expected::NoExpectation(expr_type),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
Let(Box::new(LetConstraint {
|
Let(Box::new(LetConstraint {
|
||||||
|
@ -959,7 +907,7 @@ pub fn rec_defs_help(
|
||||||
let mut new_rigids = Vec::new();
|
let mut new_rigids = Vec::new();
|
||||||
match &def.annotation {
|
match &def.annotation {
|
||||||
None => {
|
None => {
|
||||||
let (_, expr_con) = constrain_expr(
|
let expr_con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -1002,7 +950,7 @@ pub fn rec_defs_help(
|
||||||
AnnotationSource::TypedBody,
|
AnnotationSource::TypedBody,
|
||||||
annotation.clone(),
|
annotation.clone(),
|
||||||
);
|
);
|
||||||
let (_, expr_con) = constrain_expr(
|
let expr_con = constrain_expr(
|
||||||
&ftv,
|
&ftv,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
@ -1074,7 +1022,7 @@ fn constrain_field_update(
|
||||||
let field_type = Type::Variable(var);
|
let field_type = Type::Variable(var);
|
||||||
let reason = Reason::RecordUpdateValue(field);
|
let reason = Reason::RecordUpdateValue(field);
|
||||||
let expected = Expected::ForReason(reason, field_type.clone(), region);
|
let expected = Expected::ForReason(reason, field_type.clone(), region);
|
||||||
let (_, con) = constrain_expr(
|
let con = constrain_expr(
|
||||||
rigids,
|
rigids,
|
||||||
var_store,
|
var_store,
|
||||||
var_usage,
|
var_usage,
|
||||||
|
|
|
@ -89,7 +89,6 @@ pub fn can_expr(expr_str: &str) -> (Expr, Output, Vec<Problem>, VarStore, Variab
|
||||||
pub fn uniq_expr(
|
pub fn uniq_expr(
|
||||||
expr_str: &str,
|
expr_str: &str,
|
||||||
) -> (
|
) -> (
|
||||||
Output,
|
|
||||||
Output,
|
Output,
|
||||||
Vec<Problem>,
|
Vec<Problem>,
|
||||||
Subs,
|
Subs,
|
||||||
|
@ -108,7 +107,6 @@ pub fn uniq_expr_with(
|
||||||
expr_str: &str,
|
expr_str: &str,
|
||||||
declared_idents: &ImMap<Ident, (Symbol, Region)>,
|
declared_idents: &ImMap<Ident, (Symbol, Region)>,
|
||||||
) -> (
|
) -> (
|
||||||
Output,
|
|
||||||
Output,
|
Output,
|
||||||
Vec<Problem>,
|
Vec<Problem>,
|
||||||
Subs,
|
Subs,
|
||||||
|
@ -129,7 +127,7 @@ pub fn uniq_expr_with(
|
||||||
|
|
||||||
let variable2 = var_store2.fresh();
|
let variable2 = var_store2.fresh();
|
||||||
let expected2 = Expected::NoExpectation(Type::Variable(variable2));
|
let expected2 = Expected::NoExpectation(Type::Variable(variable2));
|
||||||
let (output2, constraint2) = roc::uniqueness::constrain_declaration(
|
let constraint2 = roc::uniqueness::constrain_declaration(
|
||||||
&var_store2,
|
&var_store2,
|
||||||
Region::zero(),
|
Region::zero(),
|
||||||
loc_expr,
|
loc_expr,
|
||||||
|
@ -140,7 +138,6 @@ pub fn uniq_expr_with(
|
||||||
let subs2 = Subs::new(var_store2.into());
|
let subs2 = Subs::new(var_store2.into());
|
||||||
|
|
||||||
(
|
(
|
||||||
output2,
|
|
||||||
output,
|
output,
|
||||||
problems,
|
problems,
|
||||||
subs1,
|
subs1,
|
||||||
|
|
|
@ -17,17 +17,8 @@ mod test_infer_uniq {
|
||||||
// HELPERS
|
// HELPERS
|
||||||
|
|
||||||
fn infer_eq(src: &str, expected: &str) {
|
fn infer_eq(src: &str, expected: &str) {
|
||||||
let (
|
let (_output1, _, mut subs1, variable1, mut subs2, variable2, constraint1, constraint2) =
|
||||||
_output2,
|
uniq_expr(src);
|
||||||
_output1,
|
|
||||||
_,
|
|
||||||
mut subs1,
|
|
||||||
variable1,
|
|
||||||
mut subs2,
|
|
||||||
variable2,
|
|
||||||
constraint1,
|
|
||||||
constraint2,
|
|
||||||
) = uniq_expr(src);
|
|
||||||
|
|
||||||
let mut unify_problems = Vec::new();
|
let mut unify_problems = Vec::new();
|
||||||
let content1 = infer_expr(&mut subs1, &mut unify_problems, &constraint1, variable1);
|
let content1 = infer_expr(&mut subs1, &mut unify_problems, &constraint1, variable1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue