mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Merge pull request #1295 from rtfeldman/constrain_global_tag
Constrain Expr2::GlobalTag
This commit is contained in:
commit
92f3a62cfa
3 changed files with 77 additions and 3 deletions
|
@ -9,7 +9,7 @@ use crate::lang::{
|
||||||
|
|
||||||
use roc_can::expected::Expected;
|
use roc_can::expected::Expected;
|
||||||
use roc_collections::all::{BumpMap, BumpMapDefault, Index};
|
use roc_collections::all::{BumpMap, BumpMapDefault, Index};
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::{ident::TagName, symbol::Symbol};
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_types::{
|
use roc_types::{
|
||||||
subs::Variable,
|
subs::Variable,
|
||||||
|
@ -216,6 +216,68 @@ pub fn constrain_expr<'a>(
|
||||||
exists(arena, field_vars, And(constraints))
|
exists(arena, field_vars, And(constraints))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Expr2::GlobalTag {
|
||||||
|
variant_var,
|
||||||
|
ext_var,
|
||||||
|
name,
|
||||||
|
arguments,
|
||||||
|
} => {
|
||||||
|
let mut flex_vars = BumpVec::with_capacity_in(arguments.len(), arena);
|
||||||
|
let types = PoolVec::with_capacity(arguments.len() as u32, env.pool);
|
||||||
|
let mut arg_cons = BumpVec::with_capacity_in(arguments.len(), arena);
|
||||||
|
|
||||||
|
for (argument_node_id, type_node_id) in
|
||||||
|
arguments.iter_node_ids().zip(types.iter_node_ids())
|
||||||
|
{
|
||||||
|
let (var, expr_node_id) = env.pool.get(argument_node_id);
|
||||||
|
|
||||||
|
let argument_expr = env.pool.get(*expr_node_id);
|
||||||
|
|
||||||
|
let arg_con = constrain_expr(
|
||||||
|
arena,
|
||||||
|
env,
|
||||||
|
argument_expr,
|
||||||
|
Expected::NoExpectation(Type2::Variable(*var)),
|
||||||
|
region,
|
||||||
|
);
|
||||||
|
|
||||||
|
arg_cons.push(arg_con);
|
||||||
|
flex_vars.push(*var);
|
||||||
|
|
||||||
|
env.pool[type_node_id] = Type2::Variable(*var);
|
||||||
|
}
|
||||||
|
|
||||||
|
let members = PoolVec::with_capacity(1, env.pool);
|
||||||
|
|
||||||
|
for (member_node_id, member) in members.iter_node_ids().zip(vec![(*name, types)]) {
|
||||||
|
env.pool[member_node_id] = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
let union_con = Eq(
|
||||||
|
Type2::TagUnion(members, env.pool.add(Type2::Variable(*ext_var))),
|
||||||
|
expected.shallow_clone(),
|
||||||
|
Category::TagApply {
|
||||||
|
tag_name: TagName::Global(name.as_str(env.pool).into()),
|
||||||
|
args_count: arguments.len(),
|
||||||
|
},
|
||||||
|
region,
|
||||||
|
);
|
||||||
|
|
||||||
|
let ast_con = Eq(
|
||||||
|
Type2::Variable(*variant_var),
|
||||||
|
expected,
|
||||||
|
Category::Storage(std::file!(), std::line!()),
|
||||||
|
region,
|
||||||
|
);
|
||||||
|
|
||||||
|
flex_vars.push(*variant_var);
|
||||||
|
flex_vars.push(*ext_var);
|
||||||
|
|
||||||
|
arg_cons.push(union_con);
|
||||||
|
arg_cons.push(ast_con);
|
||||||
|
|
||||||
|
exists(arena, flex_vars, And(arg_cons))
|
||||||
|
}
|
||||||
_ => todo!("implement constaints for {:?}", expr),
|
_ => todo!("implement constaints for {:?}", expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -826,7 +826,7 @@ fn type_to_variable<'a>(
|
||||||
let mut tag_vars = MutMap::default();
|
let mut tag_vars = MutMap::default();
|
||||||
let ext = mempool.get(*ext_id);
|
let ext = mempool.get(*ext_id);
|
||||||
|
|
||||||
for (_tag, tag_argument_types) in tags.iter(mempool) {
|
for (tag, tag_argument_types) in tags.iter(mempool) {
|
||||||
let mut tag_argument_vars = Vec::with_capacity(tag_argument_types.len());
|
let mut tag_argument_vars = Vec::with_capacity(tag_argument_types.len());
|
||||||
|
|
||||||
for arg_type in tag_argument_types.iter(mempool) {
|
for arg_type in tag_argument_types.iter(mempool) {
|
||||||
|
@ -836,7 +836,7 @@ fn type_to_variable<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_vars.insert(
|
tag_vars.insert(
|
||||||
roc_module::ident::TagName::Private(Symbol::NUM_NUM),
|
roc_module::ident::TagName::Global(tag.as_str(mempool).into()),
|
||||||
tag_argument_vars,
|
tag_argument_vars,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,3 +238,15 @@ fn constrain_list_of_records() {
|
||||||
"List { x : Num * }",
|
"List { x : Num * }",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn constrain_global_tag() {
|
||||||
|
infer_eq(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
Foo
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
"[ Foo ]*",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue