mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
reintroduce multiple uniqueness vars in numbers
This commit is contained in:
parent
232e1aa1ee
commit
caaf8e76c1
6 changed files with 47 additions and 44 deletions
|
@ -166,25 +166,25 @@ fn constrain_pattern(
|
||||||
}
|
}
|
||||||
|
|
||||||
NumLiteral(inner_var, _) => {
|
NumLiteral(inner_var, _) => {
|
||||||
let (num_var, num_type) = unique_unbound_num(*inner_var, var_store);
|
let (inner_uvar, num_var, num_type) = unique_unbound_num(*inner_var, var_store);
|
||||||
state.constraints.push(exists(
|
state.constraints.push(exists(
|
||||||
vec![num_var, *inner_var],
|
vec![num_var, inner_uvar, *inner_var],
|
||||||
Constraint::Pattern(pattern.region, PatternCategory::Num, num_type, expected),
|
Constraint::Pattern(pattern.region, PatternCategory::Num, num_type, expected),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
IntLiteral(_) => {
|
IntLiteral(_) => {
|
||||||
let (num_uvar, num_type) = unique_int(var_store);
|
let (a, b, c, num_type) = unique_int(var_store);
|
||||||
state.constraints.push(exists(
|
state.constraints.push(exists(
|
||||||
vec![num_uvar],
|
vec![a, b, c],
|
||||||
Constraint::Pattern(pattern.region, PatternCategory::Int, num_type, expected),
|
Constraint::Pattern(pattern.region, PatternCategory::Int, num_type, expected),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
FloatLiteral(_) => {
|
FloatLiteral(_) => {
|
||||||
let (num_uvar, num_type) = unique_float(var_store);
|
let (a, b, c, num_type) = unique_float(var_store);
|
||||||
|
|
||||||
state.constraints.push(exists(
|
state.constraints.push(exists(
|
||||||
vec![num_uvar],
|
vec![a, b, c],
|
||||||
Constraint::Pattern(pattern.region, PatternCategory::Float, num_type, expected),
|
Constraint::Pattern(pattern.region, PatternCategory::Float, num_type, expected),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -406,42 +406,47 @@ fn constrain_pattern(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unique_unbound_num(inner_var: Variable, var_store: &mut VarStore) -> (Variable, Type) {
|
fn unique_unbound_num(inner_var: Variable, var_store: &mut VarStore) -> (Variable, Variable, Type) {
|
||||||
let num_var = var_store.fresh();
|
let num_uvar = var_store.fresh();
|
||||||
|
let inner_uvar = var_store.fresh();
|
||||||
|
|
||||||
let val_type = Type::Variable(inner_var);
|
let val_type = Type::Variable(inner_var);
|
||||||
let val_utype = attr_type(Bool::variable(num_var), val_type);
|
let val_utype = attr_type(Bool::variable(inner_uvar), val_type);
|
||||||
|
|
||||||
let num_utype = num_num(val_utype);
|
let num_utype = num_num(val_utype);
|
||||||
let num_type = attr_type(Bool::variable(num_var), num_utype);
|
let num_type = attr_type(Bool::variable(num_uvar), num_utype);
|
||||||
|
|
||||||
(num_var, num_type)
|
(inner_uvar, num_uvar, num_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unique_int(var_store: &mut VarStore) -> (Variable, Type) {
|
fn unique_int(var_store: &mut VarStore) -> (Variable, Variable, Variable, Type) {
|
||||||
let num_uvar = var_store.fresh();
|
let num_uvar1 = var_store.fresh();
|
||||||
|
let num_uvar2 = var_store.fresh();
|
||||||
|
let num_uvar3 = var_store.fresh();
|
||||||
|
|
||||||
let signed_64 = num_signed64();
|
let signed_64 = num_signed64();
|
||||||
let attr_signed_64 = attr_type(Bool::variable(num_uvar), signed_64);
|
let attr_signed_64 = attr_type(Bool::variable(num_uvar1), signed_64);
|
||||||
let integer = num_integer(attr_signed_64);
|
let integer = num_integer(attr_signed_64);
|
||||||
let attr_int = attr_type(Bool::variable(num_uvar), integer);
|
let attr_int = attr_type(Bool::variable(num_uvar2), integer);
|
||||||
let num = num_num(attr_int);
|
let num = num_num(attr_int);
|
||||||
let attr_num = attr_type(Bool::variable(num_uvar), num);
|
let attr_num = attr_type(Bool::variable(num_uvar3), num);
|
||||||
|
|
||||||
(num_uvar, attr_num)
|
(num_uvar1, num_uvar2, num_uvar3, attr_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unique_float(var_store: &mut VarStore) -> (Variable, Type) {
|
fn unique_float(var_store: &mut VarStore) -> (Variable, Variable, Variable, Type) {
|
||||||
let num_uvar = var_store.fresh();
|
let num_uvar1 = var_store.fresh();
|
||||||
|
let num_uvar2 = var_store.fresh();
|
||||||
|
let num_uvar3 = var_store.fresh();
|
||||||
|
|
||||||
let binary_64 = num_binary64();
|
let binary_64 = num_binary64();
|
||||||
let attr_binary_64 = attr_type(Bool::variable(num_uvar), binary_64);
|
let attr_binary_64 = attr_type(Bool::variable(num_uvar1), binary_64);
|
||||||
let fp = num_floatingpoint(attr_binary_64);
|
let fp = num_floatingpoint(attr_binary_64);
|
||||||
let attr_fp = attr_type(Bool::variable(num_uvar), fp);
|
let attr_fp = attr_type(Bool::variable(num_uvar2), fp);
|
||||||
let num = num_num(attr_fp);
|
let num = num_num(attr_fp);
|
||||||
let attr_num = attr_type(Bool::variable(num_uvar), num);
|
let attr_num = attr_type(Bool::variable(num_uvar3), num);
|
||||||
|
|
||||||
(num_uvar, attr_num)
|
(num_uvar1, num_uvar2, num_uvar3, attr_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constrain_expr(
|
pub fn constrain_expr(
|
||||||
|
@ -458,10 +463,10 @@ pub fn constrain_expr(
|
||||||
match expr {
|
match expr {
|
||||||
Num(inner_var, _) => {
|
Num(inner_var, _) => {
|
||||||
let var = var_store.fresh();
|
let var = var_store.fresh();
|
||||||
let (num_var, num_type) = unique_unbound_num(*inner_var, var_store);
|
let (inner_uvar, num_var, num_type) = unique_unbound_num(*inner_var, var_store);
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
vec![var, *inner_var, num_var],
|
vec![var, *inner_var, inner_uvar, num_var],
|
||||||
And(vec![
|
And(vec![
|
||||||
Eq(
|
Eq(
|
||||||
Type::Variable(var),
|
Type::Variable(var),
|
||||||
|
@ -474,10 +479,10 @@ pub fn constrain_expr(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Int(var, _) => {
|
Int(var, _) => {
|
||||||
let (num_uvar, num_type) = unique_int(var_store);
|
let (a, b, c, num_type) = unique_int(var_store);
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
vec![*var, num_uvar],
|
vec![*var, a, b, c],
|
||||||
And(vec![
|
And(vec![
|
||||||
Eq(
|
Eq(
|
||||||
Type::Variable(*var),
|
Type::Variable(*var),
|
||||||
|
@ -490,10 +495,10 @@ pub fn constrain_expr(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Float(var, _) => {
|
Float(var, _) => {
|
||||||
let (num_uvar, num_type) = unique_float(var_store);
|
let (a, b, c, num_type) = unique_float(var_store);
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
vec![*var, num_uvar],
|
vec![*var, a, b, c],
|
||||||
And(vec![
|
And(vec![
|
||||||
Eq(
|
Eq(
|
||||||
Type::Variable(*var),
|
Type::Variable(*var),
|
||||||
|
|
|
@ -1136,7 +1136,7 @@ mod gen_list {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_unique_list_oob() {
|
fn set_unique_list_oob() {
|
||||||
assert_non_opt_evals_to!(
|
assert_evals_to!(
|
||||||
"List.set [ 3, 17, 4.1 ] 1337 9.25",
|
"List.set [ 3, 17, 4.1 ] 1337 9.25",
|
||||||
RocList::from_slice(&[3.0, 17.0, 4.1]),
|
RocList::from_slice(&[3.0, 17.0, 4.1]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
|
|
|
@ -236,10 +236,10 @@ mod test_uniq_load {
|
||||||
"divisionFn" => "Attr Shared (Attr * F64, Attr * F64 -> Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*)))",
|
"divisionFn" => "Attr Shared (Attr * F64, Attr * F64 -> Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*)))",
|
||||||
"divisionTest" => "Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*))",
|
"divisionTest" => "Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*))",
|
||||||
"intTest" => "Attr * I64",
|
"intTest" => "Attr * I64",
|
||||||
"x" => "Attr a F64",
|
"x" => "Attr * F64",
|
||||||
"constantNum" => "Attr * (Num (Attr * *))",
|
"constantNum" => "Attr * (Num (Attr * *))",
|
||||||
"divDep1ByDep2" => "Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*))",
|
"divDep1ByDep2" => "Attr * (Result (Attr * F64) (Attr * [ DivByZero ]*))",
|
||||||
"fromDep2" => "Attr a F64",
|
"fromDep2" => "Attr * F64",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,8 +448,8 @@ mod test_reporting {
|
||||||
|
|
||||||
baz
|
baz
|
||||||
Str
|
Str
|
||||||
main
|
|
||||||
U8
|
U8
|
||||||
|
F64
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -620,9 +620,9 @@ mod test_reporting {
|
||||||
|
|
||||||
these names seem close though:
|
these names seem close though:
|
||||||
|
|
||||||
|
Result
|
||||||
Num
|
Num
|
||||||
Set
|
Set
|
||||||
Result
|
|
||||||
U8
|
U8
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1374,7 +1374,7 @@ mod test_reporting {
|
||||||
Bool
|
Bool
|
||||||
U8
|
U8
|
||||||
F64
|
F64
|
||||||
Num
|
Str
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -2094,7 +2094,7 @@ mod test_reporting {
|
||||||
|
|
||||||
But `add` needs the 2nd argument to be:
|
But `add` needs the 2nd argument to be:
|
||||||
|
|
||||||
Num Integer
|
Num (Integer Signed64)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -2123,7 +2123,7 @@ mod test_reporting {
|
||||||
|
|
||||||
But `add` needs the 2nd argument to be:
|
But `add` needs the 2nd argument to be:
|
||||||
|
|
||||||
Num Integer
|
Num (Integer Signed64)
|
||||||
|
|
||||||
Tip: You can convert between Int and Float using functions like
|
Tip: You can convert between Int and Float using functions like
|
||||||
`Num.toFloat` and `Num.round`.
|
`Num.toFloat` and `Num.round`.
|
||||||
|
|
|
@ -75,7 +75,7 @@ mod solve_uniq_expr {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn float_literal() {
|
fn float_literal() {
|
||||||
infer_eq("0.5", "Attr a F64");
|
infer_eq("0.5", "Attr * F64");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -640,7 +640,7 @@ mod solve_uniq_expr {
|
||||||
(\a -> a) 3.14
|
(\a -> a) 3.14
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Attr a F64",
|
"Attr * F64",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,7 +1211,7 @@ mod solve_uniq_expr {
|
||||||
{ numIdentity, p, q }
|
{ numIdentity, p, q }
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Attr * { numIdentity : Attr Shared (Attr b (Num (Attr a p)) -> Attr b (Num (Attr a p))), p : Attr * (Num (Attr * p)), q : Attr c F64 }"
|
"Attr * { numIdentity : Attr Shared (Attr b (Num (Attr a p)) -> Attr b (Num (Attr a p))), p : Attr * (Num (Attr * p)), q : Attr * F64 }"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3180,7 +3180,7 @@ mod solve_uniq_expr {
|
||||||
List.set [0x2] 1337 0
|
List.set [0x2] 1337 0
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Attr * (List (Attr a I64))",
|
"Attr * (List (Attr * I64))",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3192,7 +3192,7 @@ mod solve_uniq_expr {
|
||||||
List.set [0.2] 1337 0
|
List.set [0.2] 1337 0
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"Attr * (List (Attr a F64))",
|
"Attr * (List (Attr * F64))",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,6 @@ fn find_names_needed(
|
||||||
use crate::subs::Content::*;
|
use crate::subs::Content::*;
|
||||||
use crate::subs::FlatType::*;
|
use crate::subs::FlatType::*;
|
||||||
|
|
||||||
dbg!(variable);
|
|
||||||
|
|
||||||
while let Some((recursive, _chain)) = subs.occurs(variable) {
|
while let Some((recursive, _chain)) = subs.occurs(variable) {
|
||||||
let content = subs.get_without_compacting(recursive).content;
|
let content = subs.get_without_compacting(recursive).content;
|
||||||
match content {
|
match content {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue