mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
extend solve
This commit is contained in:
parent
bffb9ab6fe
commit
c55c35e164
2 changed files with 80 additions and 77 deletions
|
@ -1,12 +1,14 @@
|
|||
#![allow(clippy::all)]
|
||||
#![allow(dead_code)]
|
||||
use crate::lang::constrain::Constraint::{self, *};
|
||||
use crate::lang::pool::Pool;
|
||||
use crate::lang::types::Type2;
|
||||
use roc_can::expected::{Expected, PExpected};
|
||||
use roc_collections::all::{ImMap, MutMap};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_types::solved_types::Solved;
|
||||
use roc_types::subs::{Content, Descriptor, FlatType, Mark, OptVariable, Rank, Subs, Variable};
|
||||
use roc_types::types::Type;
|
||||
use roc_types::types::{Alias, Category, ErrorType, PatternCategory, RecordField};
|
||||
use roc_unify::unify::unify;
|
||||
use roc_unify::unify::Unified::*;
|
||||
|
@ -132,18 +134,20 @@ struct State {
|
|||
}
|
||||
|
||||
pub fn run(
|
||||
mempool: &mut Pool,
|
||||
env: &Env,
|
||||
problems: &mut Vec<TypeError>,
|
||||
mut subs: Subs,
|
||||
constraint: &Constraint,
|
||||
) -> (Solved<Subs>, Env) {
|
||||
let env = run_in_place(env, problems, &mut subs, constraint);
|
||||
let env = run_in_place(mempool, env, problems, &mut subs, constraint);
|
||||
|
||||
(Solved(subs), env)
|
||||
}
|
||||
|
||||
/// Modify an existing subs in-place instead
|
||||
pub fn run_in_place(
|
||||
mempool: &mut Pool,
|
||||
env: &Env,
|
||||
problems: &mut Vec<TypeError>,
|
||||
subs: &mut Subs,
|
||||
|
@ -156,6 +160,7 @@ pub fn run_in_place(
|
|||
};
|
||||
let rank = Rank::toplevel();
|
||||
let state = solve(
|
||||
mempool,
|
||||
env,
|
||||
state,
|
||||
rank,
|
||||
|
@ -171,7 +176,8 @@ pub fn run_in_place(
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn solve(
|
||||
env: &Env,
|
||||
mempool: &mut Pool,
|
||||
_env: &Env,
|
||||
state: State,
|
||||
rank: Rank,
|
||||
pools: &mut Pools,
|
||||
|
@ -191,8 +197,9 @@ fn solve(
|
|||
// copy
|
||||
// }
|
||||
Eq(typ, expectation, category, region) => {
|
||||
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
||||
let actual = type_to_var(mempool, subs, rank, pools, cached_aliases, typ);
|
||||
let expected = type_to_var(
|
||||
mempool,
|
||||
subs,
|
||||
rank,
|
||||
pools,
|
||||
|
@ -613,26 +620,28 @@ fn solve(
|
|||
}
|
||||
|
||||
fn type_to_var(
|
||||
mempool: &mut Pool,
|
||||
subs: &mut Subs,
|
||||
rank: Rank,
|
||||
pools: &mut Pools,
|
||||
cached: &mut MutMap<Symbol, Variable>,
|
||||
typ: &Type2,
|
||||
) -> Variable {
|
||||
type_to_variable(subs, rank, pools, cached, typ)
|
||||
type_to_variable(mempool, subs, rank, pools, cached, typ)
|
||||
}
|
||||
|
||||
/// Abusing existing functions for our purposes
|
||||
/// this is to put a solved type back into subs
|
||||
pub fn insert_type_into_subs(subs: &mut Subs, typ: &Type2) -> Variable {
|
||||
pub fn insert_type_into_subs(mempool: &mut Pool, subs: &mut Subs, typ: &Type2) -> Variable {
|
||||
let rank = Rank::NONE;
|
||||
let mut pools = Pools::default();
|
||||
let mut cached = MutMap::default();
|
||||
|
||||
type_to_variable(subs, rank, &mut pools, &mut cached, typ)
|
||||
type_to_variable(mempool, subs, rank, &mut pools, &mut cached, typ)
|
||||
}
|
||||
|
||||
fn type_to_variable(
|
||||
mempool: &mut Pool,
|
||||
subs: &mut Subs,
|
||||
rank: Rank,
|
||||
pools: &mut Pools,
|
||||
|
@ -645,10 +654,10 @@ fn type_to_variable(
|
|||
Variable(var) => *var,
|
||||
Apply(symbol, args) => {
|
||||
let mut arg_vars = Vec::with_capacity(args.len());
|
||||
|
||||
// for arg in args {
|
||||
// arg_vars.push(type_to_variable(subs, rank, pools, cached, arg))
|
||||
// }
|
||||
for var_id in args.iter_node_ids() {
|
||||
let arg = mempool.get(var_id);
|
||||
arg_vars.push(type_to_variable(mempool, subs, rank, pools, cached, arg))
|
||||
}
|
||||
|
||||
let flat_type = FlatType::Apply(*symbol, arg_vars);
|
||||
let content = Content::Structure(flat_type);
|
||||
|
@ -656,9 +665,49 @@ fn type_to_variable(
|
|||
register(subs, rank, pools, content)
|
||||
}
|
||||
|
||||
EmptyRec => roc_types::subs::Variable::EMPTY_RECORD,
|
||||
EmptyTagUnion => roc_types::subs::Variable::EMPTY_TAG_UNION,
|
||||
|
||||
Record(fields, ext_id) => {
|
||||
let mut field_vars = MutMap::default();
|
||||
|
||||
for node_id in fields.iter_node_ids() {
|
||||
use RecordField::*;
|
||||
|
||||
let (field, field_type) = mempool.get(node_id);
|
||||
|
||||
let field_var = match field_type {
|
||||
Required(typ) => {
|
||||
Required(type_to_variable(mempool, subs, rank, pools, cached, typ))
|
||||
}
|
||||
Optional(typ) => {
|
||||
Optional(type_to_variable(mempool, subs, rank, pools, cached, typ))
|
||||
}
|
||||
Demanded(typ) => {
|
||||
Demanded(type_to_variable(mempool, subs, rank, pools, cached, typ))
|
||||
}
|
||||
};
|
||||
|
||||
field_vars.insert(field.as_str(mempool).into(), field_var);
|
||||
}
|
||||
|
||||
let ext = mempool.get(*ext_id);
|
||||
let temp_ext_var = type_to_variable(mempool, subs, rank, pools, cached, ext);
|
||||
let new_ext_var = match roc_types::pretty_print::chase_ext_record(
|
||||
subs,
|
||||
temp_ext_var,
|
||||
&mut field_vars,
|
||||
) {
|
||||
Ok(()) => roc_types::subs::Variable::EMPTY_RECORD,
|
||||
Err((new, _)) => new,
|
||||
};
|
||||
|
||||
let content = Content::Structure(FlatType::Record(field_vars, new_ext_var));
|
||||
|
||||
register(subs, rank, pools, content)
|
||||
}
|
||||
|
||||
other => todo!("not implemented {:?}", &other),
|
||||
// EmptyRec => Variable::EMPTY_RECORD,
|
||||
// EmptyTagUnion => Variable::EMPTY_TAG_UNION,
|
||||
//
|
||||
// // This case is important for the rank of boolean variables
|
||||
// Function(args, closure_type, ret_type) => {
|
||||
|
@ -674,35 +723,6 @@ fn type_to_variable(
|
|||
//
|
||||
// register(subs, rank, pools, content)
|
||||
// }
|
||||
// Record(fields, ext) => {
|
||||
// let mut field_vars = MutMap::default();
|
||||
//
|
||||
// for (field, field_type) in fields {
|
||||
// use RecordField::*;
|
||||
//
|
||||
// let field_var = match field_type {
|
||||
// Required(typ) => Required(type_to_variable(subs, rank, pools, cached, typ)),
|
||||
// Optional(typ) => Optional(type_to_variable(subs, rank, pools, cached, typ)),
|
||||
// Demanded(typ) => Demanded(type_to_variable(subs, rank, pools, cached, typ)),
|
||||
// };
|
||||
//
|
||||
// field_vars.insert(field.clone(), field_var);
|
||||
// }
|
||||
//
|
||||
// let temp_ext_var = type_to_variable(subs, rank, pools, cached, ext);
|
||||
// let new_ext_var = match roc_types::pretty_print::chase_ext_record(
|
||||
// subs,
|
||||
// temp_ext_var,
|
||||
// &mut field_vars,
|
||||
// ) {
|
||||
// Ok(()) => Variable::EMPTY_RECORD,
|
||||
// Err((new, _)) => new,
|
||||
// };
|
||||
//
|
||||
// let content = Content::Structure(FlatType::Record(field_vars, new_ext_var));
|
||||
//
|
||||
// register(subs, rank, pools, content)
|
||||
// }
|
||||
// TagUnion(tags, ext) => {
|
||||
// let mut tag_vars = MutMap::default();
|
||||
//
|
||||
|
|
|
@ -15,44 +15,16 @@ use roc_editor::lang::{
|
|||
scope::Scope,
|
||||
types::Type2,
|
||||
};
|
||||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_module::symbol::{IdentIds, ModuleIds};
|
||||
use roc_region::all::Region;
|
||||
use roc_types::solved_types::Solved;
|
||||
use roc_types::subs::{Subs, Variable};
|
||||
use roc_types::{pretty_print::content_to_string, subs::VarStore, types::Type};
|
||||
|
||||
fn ed_constraint_to_can_constraint(
|
||||
constraint: roc_editor::lang::constrain::Constraint,
|
||||
) -> roc_can::constraint::Constraint {
|
||||
match constraint {
|
||||
roc_editor::lang::constrain::Constraint::Eq(typ, expected, category, region) => {
|
||||
let new_typ = type2_to_type(&typ);
|
||||
let expected_typ = expected.get_type_ref();
|
||||
|
||||
let expected_typ = type2_to_type(expected_typ);
|
||||
|
||||
roc_can::constraint::Constraint::Eq(
|
||||
new_typ,
|
||||
expected.replace(expected_typ),
|
||||
category,
|
||||
region,
|
||||
)
|
||||
}
|
||||
_ => todo!("{:?}", constraint),
|
||||
}
|
||||
}
|
||||
|
||||
fn type2_to_type(typ: &Type2) -> Type {
|
||||
match typ {
|
||||
Type2::Apply(symbol, _) => Type::Apply(*symbol, Vec::new()),
|
||||
Type2::Variable(var) => Type::Variable(*var),
|
||||
_ => todo!("{:?}", typ),
|
||||
}
|
||||
}
|
||||
use roc_types::{pretty_print::content_to_string, subs::VarStore};
|
||||
|
||||
fn run_solve(
|
||||
mempool: &mut Pool,
|
||||
aliases: MutMap<Symbol, roc_types::types::Alias>,
|
||||
rigid_variables: MutMap<Variable, Lowercase>,
|
||||
constraint: Constraint,
|
||||
|
@ -74,7 +46,7 @@ fn run_solve(
|
|||
let mut problems = Vec::new();
|
||||
|
||||
// Run the solver to populate Subs.
|
||||
let (solved_subs, solved_env) = solve::run(&env, &mut problems, subs, &constraint);
|
||||
let (solved_subs, solved_env) = solve::run(mempool, &env, &mut problems, subs, &constraint);
|
||||
|
||||
(solved_subs, solved_env, problems)
|
||||
}
|
||||
|
@ -116,18 +88,29 @@ fn infer_eq(actual: &str, expected_str: &str) {
|
|||
Expected::NoExpectation(Type2::Variable(var)),
|
||||
);
|
||||
|
||||
let Env {
|
||||
pool,
|
||||
var_store: ref_var_store,
|
||||
..
|
||||
} = env;
|
||||
|
||||
// extract the var_store out of the env again
|
||||
let mut var_store = VarStore::default();
|
||||
std::mem::swap(ref_var_store, &mut var_store);
|
||||
|
||||
let (mut solved, _, _) = run_solve(
|
||||
pool,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
constraint,
|
||||
var_store,
|
||||
);
|
||||
|
||||
let mut subs = solved.inner_mut();
|
||||
let subs = solved.inner_mut();
|
||||
|
||||
let content = subs.get(var).content;
|
||||
|
||||
let actual_str = content_to_string(content, &mut subs, mod_id, &Default::default());
|
||||
let actual_str = content_to_string(content, &subs, mod_id, &Default::default());
|
||||
|
||||
assert_eq!(actual_str, expected_str);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue