mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-12 23:50:20 +03:00
add Store constraint that does not report errors
This commit is contained in:
parent
75d18eb8ba
commit
bde82c3bb6
@ -765,6 +765,13 @@ fn variable_usage_help(con: &Constraint, declared: &mut SeenVariables, used: &mu
|
||||
used.insert(v);
|
||||
}
|
||||
}
|
||||
Store(tipe, var, _, _) => {
|
||||
for v in tipe.variables() {
|
||||
used.insert(v);
|
||||
}
|
||||
|
||||
used.insert(*var);
|
||||
}
|
||||
Lookup(_, expectation, _) => {
|
||||
for v in expectation.get_type_ref().variables() {
|
||||
used.insert(v);
|
||||
|
@ -8,6 +8,7 @@ use roc_types::types::{Category, PatternCategory, Type};
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Constraint {
|
||||
Eq(Type, Expected<Type>, Category, Region),
|
||||
Store(Type, Variable, &'static str, u32),
|
||||
Lookup(Symbol, Expected<Type>, Region),
|
||||
Pattern(Region, PatternCategory, Type, PExpected<Type>),
|
||||
True, // Used for things that always unify, e.g. blanks and runtime errors
|
||||
|
@ -1221,19 +1221,9 @@ fn constrain_def(env: &Env, def: &Def, body_con: Constraint) -> Constraint {
|
||||
})),
|
||||
// "the closure's type is equal to expected type"
|
||||
Eq(fn_type.clone(), expected.clone(), Category::Lambda, region),
|
||||
// "fn_var is equal to the closure's type" - fn_var is used in code gen
|
||||
Eq(
|
||||
Type::Variable(*fn_var),
|
||||
NoExpectation(Type::Variable(expr_var)),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
),
|
||||
Eq(
|
||||
Type::Variable(expr_var),
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
),
|
||||
// Store type into AST vars. We use Store so errors aren't reported twice
|
||||
Store(signature.clone(), *fn_var, std::file!(), std::line!()),
|
||||
Store(signature, expr_var, std::file!(), std::line!()),
|
||||
closure_constraint,
|
||||
]),
|
||||
)
|
||||
@ -1579,18 +1569,9 @@ pub fn rec_defs_help(
|
||||
})),
|
||||
Eq(fn_type.clone(), expected.clone(), Category::Lambda, region),
|
||||
// "fn_var is equal to the closure's type" - fn_var is used in code gen
|
||||
Eq(
|
||||
Type::Variable(*fn_var),
|
||||
NoExpectation(fn_type),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
),
|
||||
Eq(
|
||||
Type::Variable(expr_var),
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
),
|
||||
// Store type into AST vars. We use Store so errors aren't reported twice
|
||||
Store(signature.clone(), *fn_var, std::file!(), std::line!()),
|
||||
Store(signature, expr_var, std::file!(), std::line!()),
|
||||
closure_constraint,
|
||||
]),
|
||||
);
|
||||
|
@ -389,6 +389,13 @@ fn variable_usage_help(con: &Constraint, declared: &mut SeenVariables, used: &mu
|
||||
used.insert(v);
|
||||
}
|
||||
}
|
||||
Store(tipe, var, _, _) => {
|
||||
for v in tipe.variables() {
|
||||
used.insert(v);
|
||||
}
|
||||
|
||||
used.insert(*var);
|
||||
}
|
||||
Lookup(_, expectation, _) => {
|
||||
for v in expectation.get_type_ref().variables() {
|
||||
used.insert(v);
|
||||
|
@ -402,6 +402,13 @@ fn variable_usage_help(con: &Constraint, declared: &mut SeenVariables, used: &mu
|
||||
used.insert(v);
|
||||
}
|
||||
}
|
||||
Store(tipe, var, _, _) => {
|
||||
for v in tipe.variables() {
|
||||
used.insert(v);
|
||||
}
|
||||
|
||||
used.insert(*var);
|
||||
}
|
||||
Lookup(_, expectation, _) => {
|
||||
for v in expectation.get_type_ref().variables() {
|
||||
used.insert(v);
|
||||
|
@ -244,6 +244,34 @@ fn solve(
|
||||
}
|
||||
}
|
||||
}
|
||||
Store(source, target, _filename, _linenr) => {
|
||||
// a special version of Eq that is used to store types in the AST.
|
||||
// IT DOES NOT REPORT ERRORS!
|
||||
let actual = type_to_var(subs, rank, pools, cached_aliases, source);
|
||||
let target = *target;
|
||||
|
||||
match unify(subs, actual, target) {
|
||||
Success(vars) => {
|
||||
introduce(subs, rank, pools, &vars);
|
||||
|
||||
state
|
||||
}
|
||||
Failure(vars, _actual_type, _expected_type) => {
|
||||
introduce(subs, rank, pools, &vars);
|
||||
|
||||
// ERROR NOT REPORTED
|
||||
|
||||
state
|
||||
}
|
||||
BadType(vars, _problem) => {
|
||||
introduce(subs, rank, pools, &vars);
|
||||
|
||||
// ERROR NOT REPORTED
|
||||
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
Lookup(symbol, expectation, region) => {
|
||||
let var = *env.vars_by_symbol.get(&symbol).unwrap_or_else(|| {
|
||||
// TODO Instead of panicking, solve this as True and record
|
||||
|
@ -417,6 +417,13 @@ fn variable_usage_help(con: &Constraint, declared: &mut SeenVariables, used: &mu
|
||||
used.insert(v);
|
||||
}
|
||||
}
|
||||
Store(tipe, var, _, _) => {
|
||||
for v in tipe.variables() {
|
||||
used.insert(v);
|
||||
}
|
||||
|
||||
used.insert(*var);
|
||||
}
|
||||
Lookup(_, expectation, _) => {
|
||||
for v in expectation.get_type_ref().variables() {
|
||||
used.insert(v);
|
||||
|
@ -3481,4 +3481,42 @@ mod solve_expr {
|
||||
"Dict Int Int",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quicksort_partition_help() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
app Test provides [ partitionHelp ] imports []
|
||||
|
||||
swap : Int, Int, List a -> List a
|
||||
swap = \i, j, list ->
|
||||
when Pair (List.get list i) (List.get list j) is
|
||||
Pair (Ok atI) (Ok atJ) ->
|
||||
list
|
||||
|> List.set i atJ
|
||||
|> List.set j atI
|
||||
|
||||
_ ->
|
||||
[]
|
||||
|
||||
partitionHelp : Int, Int, List (Num a), Int, (Num a) -> [ Pair Int (List (Num a)) ]
|
||||
partitionHelp = \i, j, list, high, pivot ->
|
||||
if j < high then
|
||||
when List.get list j is
|
||||
Ok value ->
|
||||
if value <= pivot then
|
||||
partitionHelp (i + 1) (j + 1) (swap (i + 1) j list) high pivot
|
||||
else
|
||||
partitionHelp i (j + 1) list high pivot
|
||||
|
||||
Err _ ->
|
||||
Pair i list
|
||||
else
|
||||
Pair i list
|
||||
"#
|
||||
),
|
||||
"Int, Int, List (Num a), Int, Num a -> [ Pair Int (List (Num a)) ]",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1089,7 +1089,7 @@ fn unify_rigid(subs: &mut Subs, ctx: &Context, name: &Lowercase, other: &Content
|
||||
RigidVar(_) | RecursionVar { .. } | Structure(_) | Alias(_, _, _) => {
|
||||
// Type mismatch! Rigid can only unify with flex, even if the
|
||||
// rigid names are the same.
|
||||
mismatch!("Rigid with {:?}", &other)
|
||||
mismatch!("Rigid {:?} with {:?}", ctx.first, &other)
|
||||
}
|
||||
Error => {
|
||||
// Error propagates.
|
||||
|
@ -414,6 +414,13 @@ fn variable_usage_help(con: &Constraint, declared: &mut SeenVariables, used: &mu
|
||||
used.insert(v);
|
||||
}
|
||||
}
|
||||
Store(tipe, var, _, _) => {
|
||||
for v in tipe.variables() {
|
||||
used.insert(v);
|
||||
}
|
||||
|
||||
used.insert(*var);
|
||||
}
|
||||
Lookup(_, expectation, _) => {
|
||||
for v in expectation.get_type_ref().variables() {
|
||||
used.insert(v);
|
||||
|
Loading…
Reference in New Issue
Block a user