mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Merge branch 'trunk' into fuzz
This commit is contained in:
commit
2f2e67059b
22 changed files with 56 additions and 593 deletions
|
@ -584,7 +584,6 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_bytes: &[u8]) -> Result<
|
||||||
value: with_builtins,
|
value: with_builtins,
|
||||||
}),
|
}),
|
||||||
var_store.fresh(),
|
var_store.fresh(),
|
||||||
SendMap::default(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,12 +324,7 @@ fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
annotation: None,
|
annotation: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = LetNonRec(
|
let body = LetNonRec(Box::new(def), Box::new(no_region(cont)), ret_var);
|
||||||
Box::new(def),
|
|
||||||
Box::new(no_region(cont)),
|
|
||||||
ret_var,
|
|
||||||
SendMap::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
symbol,
|
symbol,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::expected::{Expected, PExpected};
|
use crate::expected::{Expected, PExpected};
|
||||||
use roc_collections::all::{ImMap, ImSet, SendMap};
|
use roc_collections::all::SendMap;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_types::subs::{VarStore, Variable};
|
use roc_types::subs::Variable;
|
||||||
use roc_types::types::{Alias, Category, PatternCategory, Type};
|
use roc_types::types::{Category, PatternCategory, Type};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Constraint {
|
pub enum Constraint {
|
||||||
|
@ -16,90 +16,11 @@ pub enum Constraint {
|
||||||
And(Vec<Constraint>),
|
And(Vec<Constraint>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Constraint {
|
|
||||||
pub fn instantiate_aliases(&mut self, var_store: &mut VarStore) {
|
|
||||||
Self::instantiate_aliases_help(self, &ImMap::default(), var_store, &mut ImSet::default())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn instantiate_aliases_help(
|
|
||||||
&mut self,
|
|
||||||
aliases: &ImMap<Symbol, Alias>,
|
|
||||||
var_store: &mut VarStore,
|
|
||||||
introduced: &mut ImSet<Variable>,
|
|
||||||
) {
|
|
||||||
use Constraint::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
True | SaveTheEnvironment => {}
|
|
||||||
|
|
||||||
Eq(typ, expected, _, region) => {
|
|
||||||
let expected_region = expected.get_annotation_region().unwrap_or(*region);
|
|
||||||
expected.get_type_mut_ref().instantiate_aliases(
|
|
||||||
expected_region,
|
|
||||||
aliases,
|
|
||||||
var_store,
|
|
||||||
introduced,
|
|
||||||
);
|
|
||||||
typ.instantiate_aliases(*region, aliases, var_store, introduced);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lookup(_, expected, region) => {
|
|
||||||
let expected_region = expected.get_annotation_region().unwrap_or(*region);
|
|
||||||
expected.get_type_mut_ref().instantiate_aliases(
|
|
||||||
expected_region,
|
|
||||||
aliases,
|
|
||||||
var_store,
|
|
||||||
introduced,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pattern(region, _, typ, pexpected) => {
|
|
||||||
pexpected
|
|
||||||
.get_type_mut_ref()
|
|
||||||
.instantiate_aliases(*region, aliases, var_store, introduced);
|
|
||||||
typ.instantiate_aliases(*region, aliases, var_store, introduced);
|
|
||||||
}
|
|
||||||
|
|
||||||
And(nested) => {
|
|
||||||
for c in nested.iter_mut() {
|
|
||||||
c.instantiate_aliases_help(aliases, var_store, introduced);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Let(letcon) => {
|
|
||||||
let mut new_aliases = aliases.clone();
|
|
||||||
for (k, v) in letcon.def_aliases.iter() {
|
|
||||||
new_aliases.insert(*k, v.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut introduced = ImSet::default();
|
|
||||||
for Located { region, value: typ } in letcon.def_types.iter_mut() {
|
|
||||||
typ.instantiate_aliases(*region, &new_aliases, var_store, &mut introduced);
|
|
||||||
}
|
|
||||||
|
|
||||||
letcon.defs_constraint.instantiate_aliases_help(
|
|
||||||
&new_aliases,
|
|
||||||
var_store,
|
|
||||||
&mut introduced,
|
|
||||||
);
|
|
||||||
letcon.ret_constraint.instantiate_aliases_help(
|
|
||||||
&new_aliases,
|
|
||||||
var_store,
|
|
||||||
&mut introduced,
|
|
||||||
);
|
|
||||||
|
|
||||||
letcon.flex_vars.extend(introduced);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct LetConstraint {
|
pub struct LetConstraint {
|
||||||
pub rigid_vars: Vec<Variable>,
|
pub rigid_vars: Vec<Variable>,
|
||||||
pub flex_vars: Vec<Variable>,
|
pub flex_vars: Vec<Variable>,
|
||||||
pub def_types: SendMap<Symbol, Located<Type>>,
|
pub def_types: SendMap<Symbol, Located<Type>>,
|
||||||
pub def_aliases: SendMap<Symbol, Alias>,
|
|
||||||
pub defs_constraint: Constraint,
|
pub defs_constraint: Constraint,
|
||||||
pub ret_constraint: Constraint,
|
pub ret_constraint: Constraint,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1278,7 +1278,7 @@ pub fn can_defs_with_return<'a>(
|
||||||
for declaration in decls.into_iter().rev() {
|
for declaration in decls.into_iter().rev() {
|
||||||
loc_expr = Located {
|
loc_expr = Located {
|
||||||
region: Region::zero(),
|
region: Region::zero(),
|
||||||
value: decl_to_let(var_store, declaration, loc_expr, output.aliases.clone()),
|
value: decl_to_let(var_store, declaration, loc_expr),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,19 +1288,12 @@ pub fn can_defs_with_return<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decl_to_let(
|
fn decl_to_let(var_store: &mut VarStore, decl: Declaration, loc_ret: Located<Expr>) -> Expr {
|
||||||
var_store: &mut VarStore,
|
|
||||||
decl: Declaration,
|
|
||||||
loc_ret: Located<Expr>,
|
|
||||||
aliases: SendMap<Symbol, Alias>,
|
|
||||||
) -> Expr {
|
|
||||||
match decl {
|
match decl {
|
||||||
Declaration::Declare(def) => {
|
Declaration::Declare(def) => {
|
||||||
Expr::LetNonRec(Box::new(def), Box::new(loc_ret), var_store.fresh(), aliases)
|
Expr::LetNonRec(Box::new(def), Box::new(loc_ret), var_store.fresh())
|
||||||
}
|
|
||||||
Declaration::DeclareRec(defs) => {
|
|
||||||
Expr::LetRec(defs, Box::new(loc_ret), var_store.fresh(), aliases)
|
|
||||||
}
|
}
|
||||||
|
Declaration::DeclareRec(defs) => Expr::LetRec(defs, Box::new(loc_ret), var_store.fresh()),
|
||||||
Declaration::InvalidCycle(symbols, regions) => {
|
Declaration::InvalidCycle(symbols, regions) => {
|
||||||
Expr::RuntimeError(RuntimeError::CircularDef(symbols, regions))
|
Expr::RuntimeError(RuntimeError::CircularDef(symbols, regions))
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Let
|
// Let
|
||||||
LetRec(Vec<Def>, Box<Located<Expr>>, Variable, Aliases),
|
LetRec(Vec<Def>, Box<Located<Expr>>, Variable),
|
||||||
LetNonRec(Box<Def>, Box<Located<Expr>>, Variable, Aliases),
|
LetNonRec(Box<Def>, Box<Located<Expr>>, Variable),
|
||||||
|
|
||||||
/// This is *only* for calling functions, not for tag application.
|
/// This is *only* for calling functions, not for tag application.
|
||||||
/// The Tag variant contains any applied values inside it.
|
/// The Tag variant contains any applied values inside it.
|
||||||
|
@ -157,8 +157,6 @@ pub enum Expr {
|
||||||
RuntimeError(RuntimeError),
|
RuntimeError(RuntimeError),
|
||||||
}
|
}
|
||||||
|
|
||||||
type Aliases = SendMap<Symbol, Alias>;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
pub var: Variable,
|
pub var: Variable,
|
||||||
|
@ -1221,7 +1219,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LetRec(defs, loc_expr, var, aliases) => {
|
LetRec(defs, loc_expr, var) => {
|
||||||
let mut new_defs = Vec::with_capacity(defs.len());
|
let mut new_defs = Vec::with_capacity(defs.len());
|
||||||
|
|
||||||
for def in defs {
|
for def in defs {
|
||||||
|
@ -1242,10 +1240,10 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
value: inline_calls(var_store, scope, loc_expr.value),
|
value: inline_calls(var_store, scope, loc_expr.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
LetRec(new_defs, Box::new(loc_expr), var, aliases)
|
LetRec(new_defs, Box::new(loc_expr), var)
|
||||||
}
|
}
|
||||||
|
|
||||||
LetNonRec(def, loc_expr, var, aliases) => {
|
LetNonRec(def, loc_expr, var) => {
|
||||||
let def = Def {
|
let def = Def {
|
||||||
loc_pattern: def.loc_pattern,
|
loc_pattern: def.loc_pattern,
|
||||||
loc_expr: Located {
|
loc_expr: Located {
|
||||||
|
@ -1262,7 +1260,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
value: inline_calls(var_store, scope, loc_expr.value),
|
value: inline_calls(var_store, scope, loc_expr.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
LetNonRec(Box::new(def), Box::new(loc_expr), var, aliases)
|
LetNonRec(Box::new(def), Box::new(loc_expr), var)
|
||||||
}
|
}
|
||||||
|
|
||||||
Closure {
|
Closure {
|
||||||
|
@ -1367,9 +1365,6 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
// Not sure if param_var should be involved.
|
// Not sure if param_var should be involved.
|
||||||
let pattern_vars = SendMap::default();
|
let pattern_vars = SendMap::default();
|
||||||
|
|
||||||
// TODO get the actual correct aliases
|
|
||||||
let aliases = SendMap::default();
|
|
||||||
|
|
||||||
let def = Def {
|
let def = Def {
|
||||||
loc_pattern,
|
loc_pattern,
|
||||||
loc_expr,
|
loc_expr,
|
||||||
|
@ -1384,7 +1379,6 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
Box::new(def),
|
Box::new(def),
|
||||||
Box::new(loc_answer),
|
Box::new(loc_answer),
|
||||||
var_store.fresh(),
|
var_store.fresh(),
|
||||||
aliases,
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,12 +358,12 @@ fn fix_values_captured_in_closure_expr(
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
LetNonRec(def, loc_expr, _, _) => {
|
LetNonRec(def, loc_expr, _) => {
|
||||||
// LetNonRec(Box<Def>, Box<Located<Expr>>, Variable, Aliases),
|
// LetNonRec(Box<Def>, Box<Located<Expr>>, Variable, Aliases),
|
||||||
fix_values_captured_in_closure_def(def, no_capture_symbols);
|
fix_values_captured_in_closure_def(def, no_capture_symbols);
|
||||||
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
||||||
}
|
}
|
||||||
LetRec(defs, loc_expr, _, _) => {
|
LetRec(defs, loc_expr, _) => {
|
||||||
// LetRec(Vec<Def>, Box<Located<Expr>>, Variable, Aliases),
|
// LetRec(Vec<Def>, Box<Located<Expr>>, Variable, Aliases),
|
||||||
fix_values_captured_in_closure_defs(defs, no_capture_symbols);
|
fix_values_captured_in_closure_defs(defs, no_capture_symbols);
|
||||||
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
||||||
|
|
|
@ -307,7 +307,7 @@ mod test_can {
|
||||||
|
|
||||||
fn get_closure(expr: &Expr, i: usize) -> roc_can::expr::Recursive {
|
fn get_closure(expr: &Expr, i: usize) -> roc_can::expr::Recursive {
|
||||||
match expr {
|
match expr {
|
||||||
LetRec(assignments, body, _, _) => {
|
LetRec(assignments, body, _) => {
|
||||||
match &assignments.get(i).map(|def| &def.loc_expr.value) {
|
match &assignments.get(i).map(|def| &def.loc_expr.value) {
|
||||||
Some(Closure {
|
Some(Closure {
|
||||||
recursive: recursion,
|
recursive: recursion,
|
||||||
|
@ -325,7 +325,7 @@ mod test_can {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LetNonRec(def, body, _, _) => {
|
LetNonRec(def, body, _) => {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
// recurse in the body (not the def!)
|
// recurse in the body (not the def!)
|
||||||
get_closure(&body.value, i - 1)
|
get_closure(&body.value, i - 1)
|
||||||
|
|
|
@ -46,7 +46,6 @@ pub fn exists(flex_vars: Vec<Variable>, constraint: Constraint) -> Constraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars,
|
flex_vars,
|
||||||
def_types: SendMap::default(),
|
def_types: SendMap::default(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: constraint,
|
defs_constraint: constraint,
|
||||||
ret_constraint: Constraint::True,
|
ret_constraint: Constraint::True,
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -16,7 +16,7 @@ use roc_region::all::{Located, Region};
|
||||||
use roc_types::subs::Variable;
|
use roc_types::subs::Variable;
|
||||||
use roc_types::types::AnnotationSource::{self, *};
|
use roc_types::types::AnnotationSource::{self, *};
|
||||||
use roc_types::types::Type::{self, *};
|
use roc_types::types::Type::{self, *};
|
||||||
use roc_types::types::{Alias, Category, PReason, Reason, RecordField};
|
use roc_types::types::{Category, PReason, Reason, RecordField};
|
||||||
|
|
||||||
/// This is for constraining Defs
|
/// This is for constraining Defs
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
@ -42,23 +42,6 @@ pub fn exists(flex_vars: Vec<Variable>, constraint: Constraint) -> Constraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars,
|
flex_vars,
|
||||||
def_types: SendMap::default(),
|
def_types: SendMap::default(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: constraint,
|
|
||||||
ret_constraint: Constraint::True,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn exists_with_aliases(
|
|
||||||
def_aliases: SendMap<Symbol, Alias>,
|
|
||||||
flex_vars: Vec<Variable>,
|
|
||||||
constraint: Constraint,
|
|
||||||
) -> Constraint {
|
|
||||||
Let(Box::new(LetConstraint {
|
|
||||||
rigid_vars: Vec::new(),
|
|
||||||
flex_vars,
|
|
||||||
def_types: SendMap::default(),
|
|
||||||
def_aliases,
|
|
||||||
defs_constraint: constraint,
|
defs_constraint: constraint,
|
||||||
ret_constraint: Constraint::True,
|
ret_constraint: Constraint::True,
|
||||||
}))
|
}))
|
||||||
|
@ -399,7 +382,6 @@ pub fn constrain_expr(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint,
|
defs_constraint,
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
|
@ -749,7 +731,7 @@ pub fn constrain_expr(
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LetRec(defs, loc_ret, var, _aliases) => {
|
LetRec(defs, loc_ret, var) => {
|
||||||
let body_con = constrain_expr(env, loc_ret.region, &loc_ret.value, expected.clone());
|
let body_con = constrain_expr(env, loc_ret.region, &loc_ret.value, expected.clone());
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
|
@ -767,7 +749,7 @@ pub fn constrain_expr(
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LetNonRec(def, loc_ret, var, _aliases) => {
|
LetNonRec(def, loc_ret, var) => {
|
||||||
let body_con = constrain_expr(env, loc_ret.region, &loc_ret.value, expected.clone());
|
let body_con = constrain_expr(env, loc_ret.region, &loc_ret.value, expected.clone());
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
|
@ -928,13 +910,11 @@ fn constrain_when_branch(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Constraint::And(state.constraints),
|
defs_constraint: Constraint::And(state.constraints),
|
||||||
ret_constraint: Constraint::Let(Box::new(LetConstraint {
|
ret_constraint: Constraint::Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types: SendMap::default(),
|
def_types: SendMap::default(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: guard_constraint,
|
defs_constraint: guard_constraint,
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
|
@ -944,7 +924,6 @@ fn constrain_when_branch(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Constraint::And(state.constraints),
|
defs_constraint: Constraint::And(state.constraints),
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
}))
|
}))
|
||||||
|
@ -966,11 +945,7 @@ fn constrain_empty_record(region: Region, expected: Expected<Type>) -> Constrain
|
||||||
|
|
||||||
/// Constrain top-level module declarations
|
/// Constrain top-level module declarations
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn constrain_decls(
|
pub fn constrain_decls(home: ModuleId, decls: &[Declaration]) -> Constraint {
|
||||||
home: ModuleId,
|
|
||||||
decls: &[Declaration],
|
|
||||||
_aliases: SendMap<Symbol, Alias>,
|
|
||||||
) -> Constraint {
|
|
||||||
let mut constraint = Constraint::SaveTheEnvironment;
|
let mut constraint = Constraint::SaveTheEnvironment;
|
||||||
|
|
||||||
let mut env = Env {
|
let mut env = Env {
|
||||||
|
@ -1035,13 +1010,10 @@ fn constrain_def(env: &Env, def: &Def, body_con: Constraint) -> Constraint {
|
||||||
|
|
||||||
pattern_state.vars.push(expr_var);
|
pattern_state.vars.push(expr_var);
|
||||||
|
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
let mut new_rigids = Vec::new();
|
let mut new_rigids = Vec::new();
|
||||||
|
|
||||||
let expr_con = match &def.annotation {
|
let expr_con = match &def.annotation {
|
||||||
Some(annotation) => {
|
Some(annotation) => {
|
||||||
def_aliases = annotation.aliases.clone();
|
|
||||||
|
|
||||||
let arity = annotation.signature.arity();
|
let arity = annotation.signature.arity();
|
||||||
let rigids = &env.rigids;
|
let rigids = &env.rigids;
|
||||||
let mut ftv = rigids.clone();
|
let mut ftv = rigids.clone();
|
||||||
|
@ -1191,7 +1163,6 @@ fn constrain_def(env: &Env, def: &Def, body_con: Constraint) -> Constraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint,
|
defs_constraint,
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
|
@ -1233,12 +1204,10 @@ fn constrain_def(env: &Env, def: &Def, body_con: Constraint) -> Constraint {
|
||||||
rigid_vars: new_rigids,
|
rigid_vars: new_rigids,
|
||||||
flex_vars: pattern_state.vars,
|
flex_vars: pattern_state.vars,
|
||||||
def_types: pattern_state.headers,
|
def_types: pattern_state.headers,
|
||||||
def_aliases,
|
|
||||||
defs_constraint: Let(Box::new(LetConstraint {
|
defs_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(), // always empty
|
rigid_vars: Vec::new(), // always empty
|
||||||
flex_vars: Vec::new(), // empty, because our functions have no arguments
|
flex_vars: Vec::new(), // empty, because our functions have no arguments
|
||||||
def_types: SendMap::default(), // empty, because our functions have no arguments!
|
def_types: SendMap::default(), // empty, because our functions have no arguments!
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: And(pattern_state.constraints),
|
defs_constraint: And(pattern_state.constraints),
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
})),
|
})),
|
||||||
|
@ -1350,8 +1319,6 @@ pub fn rec_defs_help(
|
||||||
mut rigid_info: Info,
|
mut rigid_info: Info,
|
||||||
mut flex_info: Info,
|
mut flex_info: Info,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
|
|
||||||
for def in defs {
|
for def in defs {
|
||||||
let expr_var = def.expr_var;
|
let expr_var = def.expr_var;
|
||||||
let expr_type = Type::Variable(expr_var);
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
@ -1389,7 +1356,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
||||||
def_types: SendMap::default(), // empty because Roc function defs have no args
|
def_types: SendMap::default(), // empty because Roc function defs have no args
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True, // I think this is correct, once again because there are no args
|
defs_constraint: True, // I think this is correct, once again because there are no args
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
}));
|
}));
|
||||||
|
@ -1400,10 +1366,6 @@ pub fn rec_defs_help(
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(annotation) => {
|
Some(annotation) => {
|
||||||
for (symbol, alias) in annotation.aliases.clone() {
|
|
||||||
def_aliases.insert(symbol, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
let arity = annotation.signature.arity();
|
let arity = annotation.signature.arity();
|
||||||
let mut ftv = env.rigids.clone();
|
let mut ftv = env.rigids.clone();
|
||||||
|
|
||||||
|
@ -1448,7 +1410,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
||||||
def_types: SendMap::default(), // empty because Roc function defs have no args
|
def_types: SendMap::default(), // empty because Roc function defs have no args
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True, // I think this is correct, once again because there are no args
|
defs_constraint: True, // I think this is correct, once again because there are no args
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
}));
|
}));
|
||||||
|
@ -1460,7 +1421,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: new_rigids,
|
rigid_vars: new_rigids,
|
||||||
flex_vars: Vec::new(), // no flex vars introduced
|
flex_vars: Vec::new(), // no flex vars introduced
|
||||||
def_types: SendMap::default(), // no headers introduced (at this level)
|
def_types: SendMap::default(), // no headers introduced (at this level)
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: def_con,
|
defs_constraint: def_con,
|
||||||
ret_constraint: True,
|
ret_constraint: True,
|
||||||
})));
|
})));
|
||||||
|
@ -1473,18 +1433,15 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: rigid_info.vars,
|
rigid_vars: rigid_info.vars,
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types: rigid_info.def_types,
|
def_types: rigid_info.def_types,
|
||||||
def_aliases,
|
|
||||||
defs_constraint: True,
|
defs_constraint: True,
|
||||||
ret_constraint: Let(Box::new(LetConstraint {
|
ret_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: flex_info.vars,
|
flex_vars: flex_info.vars,
|
||||||
def_types: flex_info.def_types.clone(),
|
def_types: flex_info.def_types.clone(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Let(Box::new(LetConstraint {
|
defs_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types: flex_info.def_types,
|
def_types: flex_info.def_types,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True,
|
defs_constraint: True,
|
||||||
ret_constraint: And(flex_info.constraints),
|
ret_constraint: And(flex_info.constraints),
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -2,12 +2,12 @@ use crate::expr::constrain_decls;
|
||||||
use roc_builtins::std::{Mode, StdLib};
|
use roc_builtins::std::{Mode, StdLib};
|
||||||
use roc_can::constraint::{Constraint, LetConstraint};
|
use roc_can::constraint::{Constraint, LetConstraint};
|
||||||
use roc_can::module::ModuleOutput;
|
use roc_can::module::ModuleOutput;
|
||||||
use roc_collections::all::{ImMap, MutMap, MutSet, SendMap};
|
use roc_collections::all::{MutMap, MutSet, SendMap};
|
||||||
use roc_module::symbol::{ModuleId, Symbol};
|
use roc_module::symbol::{ModuleId, Symbol};
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_types::solved_types::{BuiltinAlias, FreeVars, SolvedType};
|
use roc_types::solved_types::{FreeVars, SolvedType};
|
||||||
use roc_types::subs::{VarId, VarStore, Variable};
|
use roc_types::subs::{VarStore, Variable};
|
||||||
use roc_types::types::{Alias, Problem, Type};
|
use roc_types::types::{Alias, Problem};
|
||||||
|
|
||||||
pub type SubsByModule = MutMap<ModuleId, ExposedModuleTypes>;
|
pub type SubsByModule = MutMap<ModuleId, ExposedModuleTypes>;
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ pub fn constrain_module(
|
||||||
let decls = &module.declarations;
|
let decls = &module.declarations;
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Standard => constrain_decls(home, decls, send_aliases),
|
Standard => constrain_decls(home, decls),
|
||||||
Uniqueness => crate::uniq::constrain_decls(home, decls, send_aliases, var_store),
|
Uniqueness => crate::uniq::constrain_decls(home, decls, var_store),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,136 +106,15 @@ pub fn constrain_imported_values(
|
||||||
rigid_vars,
|
rigid_vars,
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types,
|
def_types,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True,
|
defs_constraint: True,
|
||||||
ret_constraint: body_con,
|
ret_constraint: body_con,
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_builtin_aliases<I>(
|
|
||||||
aliases: I,
|
|
||||||
body_con: Constraint,
|
|
||||||
var_store: &mut VarStore,
|
|
||||||
) -> Constraint
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = (Symbol, BuiltinAlias)>,
|
|
||||||
{
|
|
||||||
use Constraint::*;
|
|
||||||
|
|
||||||
// Load all the given builtin aliases.
|
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
|
|
||||||
for (symbol, builtin_alias) in aliases {
|
|
||||||
let mut free_vars = FreeVars::default();
|
|
||||||
|
|
||||||
let actual =
|
|
||||||
roc_types::solved_types::to_type(&builtin_alias.typ, &mut free_vars, var_store);
|
|
||||||
|
|
||||||
let mut vars = Vec::with_capacity(builtin_alias.vars.len());
|
|
||||||
|
|
||||||
for (loc_lowercase, index) in builtin_alias.vars.iter().zip(1..) {
|
|
||||||
let var = if let Some(result) = free_vars.unnamed_vars.get(&VarId::from_u32(index)) {
|
|
||||||
result
|
|
||||||
} else {
|
|
||||||
panic!(
|
|
||||||
"var_id {:?} was not instantiated in the body of {:?} : {:?} (is it phantom?)",
|
|
||||||
index, symbol, &builtin_alias
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.push(Located::at(
|
|
||||||
loc_lowercase.region,
|
|
||||||
(loc_lowercase.value.clone(), *var),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut hidden_variables = MutSet::default();
|
|
||||||
hidden_variables.extend(actual.variables());
|
|
||||||
|
|
||||||
for loc_var in vars.iter() {
|
|
||||||
hidden_variables.remove(&loc_var.value.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let alias = Alias {
|
|
||||||
vars,
|
|
||||||
hidden_variables,
|
|
||||||
region: builtin_alias.region,
|
|
||||||
uniqueness: None,
|
|
||||||
typ: actual,
|
|
||||||
};
|
|
||||||
|
|
||||||
def_aliases.insert(symbol, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
Let(Box::new(LetConstraint {
|
|
||||||
rigid_vars: Vec::new(),
|
|
||||||
flex_vars: Vec::new(),
|
|
||||||
def_types: SendMap::default(),
|
|
||||||
def_aliases,
|
|
||||||
defs_constraint: True,
|
|
||||||
ret_constraint: body_con,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn constrain_imported_aliases(
|
|
||||||
aliases: MutMap<Symbol, Alias>,
|
|
||||||
body_con: Constraint,
|
|
||||||
var_store: &mut VarStore,
|
|
||||||
) -> Constraint {
|
|
||||||
use Constraint::*;
|
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
|
|
||||||
for (symbol, imported_alias) in aliases {
|
|
||||||
let mut vars = Vec::with_capacity(imported_alias.vars.len());
|
|
||||||
let mut substitution = ImMap::default();
|
|
||||||
|
|
||||||
for Located {
|
|
||||||
region,
|
|
||||||
value: (lowercase, old_var),
|
|
||||||
} in &imported_alias.vars
|
|
||||||
{
|
|
||||||
let new_var = var_store.fresh();
|
|
||||||
vars.push(Located::at(*region, (lowercase.clone(), new_var)));
|
|
||||||
substitution.insert(*old_var, Type::Variable(new_var));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut actual = imported_alias.typ.clone();
|
|
||||||
|
|
||||||
actual.substitute(&substitution);
|
|
||||||
|
|
||||||
let mut hidden_variables = MutSet::default();
|
|
||||||
hidden_variables.extend(actual.variables());
|
|
||||||
|
|
||||||
for loc_var in vars.iter() {
|
|
||||||
hidden_variables.remove(&loc_var.value.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let alias = Alias {
|
|
||||||
vars,
|
|
||||||
hidden_variables,
|
|
||||||
region: imported_alias.region,
|
|
||||||
uniqueness: imported_alias.uniqueness,
|
|
||||||
typ: actual,
|
|
||||||
};
|
|
||||||
|
|
||||||
def_aliases.insert(symbol, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
Let(Box::new(LetConstraint {
|
|
||||||
rigid_vars: Vec::new(),
|
|
||||||
flex_vars: Vec::new(),
|
|
||||||
def_types: SendMap::default(),
|
|
||||||
def_aliases,
|
|
||||||
defs_constraint: True,
|
|
||||||
ret_constraint: body_con,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run pre_constrain_imports to get imported_symbols and imported_aliases.
|
/// Run pre_constrain_imports to get imported_symbols and imported_aliases.
|
||||||
pub fn constrain_imports(
|
pub fn constrain_imports(
|
||||||
imported_symbols: Vec<Import>,
|
imported_symbols: Vec<Import>,
|
||||||
imported_aliases: MutMap<Symbol, Alias>,
|
|
||||||
constraint: Constraint,
|
constraint: Constraint,
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
|
@ -247,7 +126,7 @@ pub fn constrain_imports(
|
||||||
// output.ftv.insert(var, format!("internal_{:?}", var).into());
|
// output.ftv.insert(var, format!("internal_{:?}", var).into());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
constrain_imported_aliases(imported_aliases, constraint, var_store)
|
constraint
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConstrainableImports {
|
pub struct ConstrainableImports {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::builtins::{num_floatingpoint, num_integer, num_num};
|
use crate::builtins::{num_floatingpoint, num_integer, num_num};
|
||||||
use crate::expr::{exists, exists_with_aliases, Info};
|
use crate::expr::{exists, Info};
|
||||||
use roc_can::annotation::IntroducedVariables;
|
use roc_can::annotation::IntroducedVariables;
|
||||||
use roc_can::constraint::Constraint::{self, *};
|
use roc_can::constraint::Constraint::{self, *};
|
||||||
use roc_can::constraint::LetConstraint;
|
use roc_can::constraint::LetConstraint;
|
||||||
|
@ -15,7 +15,7 @@ use roc_types::boolean_algebra::Bool;
|
||||||
use roc_types::subs::{VarStore, Variable};
|
use roc_types::subs::{VarStore, Variable};
|
||||||
use roc_types::types::AnnotationSource::{self, *};
|
use roc_types::types::AnnotationSource::{self, *};
|
||||||
use roc_types::types::Type::{self, *};
|
use roc_types::types::Type::{self, *};
|
||||||
use roc_types::types::{Alias, Category, PReason, Reason, RecordField};
|
use roc_types::types::{Category, PReason, Reason, RecordField};
|
||||||
use roc_uniq::builtins::{attr_type, empty_list_type, list_type, str_type};
|
use roc_uniq::builtins::{attr_type, empty_list_type, list_type, str_type};
|
||||||
use roc_uniq::sharing::{self, FieldAccess, Mark, Usage, VarUsage};
|
use roc_uniq::sharing::{self, FieldAccess, Mark, Usage, VarUsage};
|
||||||
|
|
||||||
|
@ -61,7 +61,6 @@ pub fn constrain_declaration(
|
||||||
pub fn constrain_decls(
|
pub fn constrain_decls(
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
decls: &[Declaration],
|
decls: &[Declaration],
|
||||||
mut aliases: SendMap<Symbol, Alias>,
|
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let mut constraint = Constraint::SaveTheEnvironment;
|
let mut constraint = Constraint::SaveTheEnvironment;
|
||||||
|
@ -88,8 +87,6 @@ pub fn constrain_decls(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aliases_to_attr_type(var_store, &mut aliases);
|
|
||||||
|
|
||||||
let mut env = Env {
|
let mut env = Env {
|
||||||
home,
|
home,
|
||||||
rigids: ImMap::default(),
|
rigids: ImMap::default(),
|
||||||
|
@ -102,8 +99,7 @@ pub fn constrain_decls(
|
||||||
|
|
||||||
match decl {
|
match decl {
|
||||||
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
||||||
constraint = exists_with_aliases(
|
constraint = exists(
|
||||||
aliases.clone(),
|
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
constrain_def(
|
constrain_def(
|
||||||
&env,
|
&env,
|
||||||
|
@ -116,8 +112,7 @@ pub fn constrain_decls(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Declaration::DeclareRec(defs) => {
|
Declaration::DeclareRec(defs) => {
|
||||||
constraint = exists_with_aliases(
|
constraint = exists(
|
||||||
aliases.clone(),
|
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
constrain_recursive_defs(
|
constrain_recursive_defs(
|
||||||
&env,
|
&env,
|
||||||
|
@ -807,7 +802,6 @@ pub fn constrain_expr(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint,
|
defs_constraint,
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
|
@ -967,7 +961,7 @@ pub fn constrain_expr(
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LetRec(defs, loc_ret, var, unlifted_aliases) => {
|
LetRec(defs, loc_ret, var) => {
|
||||||
// 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(
|
||||||
|
@ -980,11 +974,7 @@ pub fn constrain_expr(
|
||||||
expected.clone(),
|
expected.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut aliases = unlifted_aliases.clone();
|
exists(
|
||||||
aliases_to_attr_type(var_store, &mut aliases);
|
|
||||||
|
|
||||||
exists_with_aliases(
|
|
||||||
aliases,
|
|
||||||
vec![*var],
|
vec![*var],
|
||||||
And(vec![
|
And(vec![
|
||||||
constrain_recursive_defs(
|
constrain_recursive_defs(
|
||||||
|
@ -1006,7 +996,7 @@ pub fn constrain_expr(
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LetNonRec(def, loc_ret, var, unlifted_aliases) => {
|
LetNonRec(def, loc_ret, var) => {
|
||||||
// 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(
|
||||||
|
@ -1019,11 +1009,7 @@ pub fn constrain_expr(
|
||||||
expected.clone(),
|
expected.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut aliases = unlifted_aliases.clone();
|
exists(
|
||||||
aliases_to_attr_type(var_store, &mut aliases);
|
|
||||||
|
|
||||||
exists_with_aliases(
|
|
||||||
aliases,
|
|
||||||
vec![*var],
|
vec![*var],
|
||||||
And(vec![
|
And(vec![
|
||||||
constrain_def(
|
constrain_def(
|
||||||
|
@ -1842,13 +1828,11 @@ fn constrain_when_branch(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Constraint::And(state.constraints),
|
defs_constraint: Constraint::And(state.constraints),
|
||||||
ret_constraint: Constraint::Let(Box::new(LetConstraint {
|
ret_constraint: Constraint::Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: vec![guard_uniq_var],
|
flex_vars: vec![guard_uniq_var],
|
||||||
def_types: SendMap::default(),
|
def_types: SendMap::default(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: guard_constraint,
|
defs_constraint: guard_constraint,
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
})),
|
})),
|
||||||
|
@ -1858,7 +1842,6 @@ fn constrain_when_branch(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: state.vars,
|
flex_vars: state.vars,
|
||||||
def_types: state.headers,
|
def_types: state.headers,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Constraint::And(state.constraints),
|
defs_constraint: Constraint::And(state.constraints),
|
||||||
ret_constraint,
|
ret_constraint,
|
||||||
}))
|
}))
|
||||||
|
@ -2150,39 +2133,6 @@ fn annotation_to_attr_type_many(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aliases_to_attr_type(var_store: &mut VarStore, aliases: &mut SendMap<Symbol, Alias>) {
|
|
||||||
for alias in aliases.iter_mut() {
|
|
||||||
// ensure
|
|
||||||
//
|
|
||||||
// Identity a : [ Identity a ]
|
|
||||||
//
|
|
||||||
// does not turn into
|
|
||||||
//
|
|
||||||
// Identity a : [ Identity (Attr u a) ]
|
|
||||||
//
|
|
||||||
// That would give a double attr wrapper on the type arguments.
|
|
||||||
// The `change_var_kind` flag set to false ensures type variables remain of kind *
|
|
||||||
let (_, new) = annotation_to_attr_type(var_store, &alias.typ, &mut ImSet::default(), false);
|
|
||||||
// remove the outer Attr, because when this occurs in a signature it'll already be wrapped in one
|
|
||||||
match new {
|
|
||||||
Type::Apply(Symbol::ATTR_ATTR, args) => {
|
|
||||||
alias.typ = args[1].clone();
|
|
||||||
if let Type::Boolean(b) = args[0].clone() {
|
|
||||||
alias.uniqueness = Some(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!("`annotation_to_attr_type` always gives back an Attr"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that if the alias is a recursive tag union, all structures containing the
|
|
||||||
// recursion variable get the same uniqueness as the recursion variable (and thus as the
|
|
||||||
// recursive tag union itself)
|
|
||||||
if let Some(b) = &alias.uniqueness {
|
|
||||||
fix_mutual_recursive_alias(&mut alias.typ, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn constrain_def(
|
fn constrain_def(
|
||||||
env: &Env,
|
env: &Env,
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
|
@ -2205,12 +2155,10 @@ fn constrain_def(
|
||||||
|
|
||||||
pattern_state.vars.push(expr_var);
|
pattern_state.vars.push(expr_var);
|
||||||
|
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
let mut new_rigids = Vec::new();
|
let mut new_rigids = Vec::new();
|
||||||
|
|
||||||
let expr_con = match &def.annotation {
|
let expr_con = match &def.annotation {
|
||||||
Some(annotation) => {
|
Some(annotation) => {
|
||||||
def_aliases = annotation.aliases.clone();
|
|
||||||
let arity = annotation.signature.arity();
|
let arity = annotation.signature.arity();
|
||||||
let mut ftv = env.rigids.clone();
|
let mut ftv = env.rigids.clone();
|
||||||
|
|
||||||
|
@ -2264,19 +2212,14 @@ fn constrain_def(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lift aliases to Attr types
|
|
||||||
aliases_to_attr_type(var_store, &mut def_aliases);
|
|
||||||
|
|
||||||
Let(Box::new(LetConstraint {
|
Let(Box::new(LetConstraint {
|
||||||
rigid_vars: new_rigids,
|
rigid_vars: new_rigids,
|
||||||
flex_vars: pattern_state.vars,
|
flex_vars: pattern_state.vars,
|
||||||
def_types: pattern_state.headers,
|
def_types: pattern_state.headers,
|
||||||
def_aliases,
|
|
||||||
defs_constraint: Let(Box::new(LetConstraint {
|
defs_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(), // always empty
|
rigid_vars: Vec::new(), // always empty
|
||||||
flex_vars: Vec::new(), // empty, because our functions have no arguments
|
flex_vars: Vec::new(), // empty, because our functions have no arguments
|
||||||
def_types: SendMap::default(), // empty, because our functions have no arguments!
|
def_types: SendMap::default(), // empty, because our functions have no arguments!
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: And(pattern_state.constraints),
|
defs_constraint: And(pattern_state.constraints),
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
})),
|
})),
|
||||||
|
@ -2426,7 +2369,6 @@ pub fn rec_defs_help(
|
||||||
mut rigid_info: Info,
|
mut rigid_info: Info,
|
||||||
mut flex_info: Info,
|
mut flex_info: Info,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let mut def_aliases = SendMap::default();
|
|
||||||
for def in defs {
|
for def in defs {
|
||||||
let expr_var = def.expr_var;
|
let expr_var = def.expr_var;
|
||||||
let expr_type = Type::Variable(expr_var);
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
@ -2470,7 +2412,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
||||||
def_types: SendMap::default(), // empty because Roc function defs have no args
|
def_types: SendMap::default(), // empty because Roc function defs have no args
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True, // I think this is correct, once again because there are no args
|
defs_constraint: True, // I think this is correct, once again because there are no args
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
}));
|
}));
|
||||||
|
@ -2481,9 +2422,6 @@ pub fn rec_defs_help(
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(annotation) => {
|
Some(annotation) => {
|
||||||
for (symbol, alias) in annotation.aliases.clone() {
|
|
||||||
def_aliases.insert(symbol, alias);
|
|
||||||
}
|
|
||||||
let arity = annotation.signature.arity();
|
let arity = annotation.signature.arity();
|
||||||
let mut ftv = env.rigids.clone();
|
let mut ftv = env.rigids.clone();
|
||||||
let signature = instantiate_rigids(
|
let signature = instantiate_rigids(
|
||||||
|
@ -2529,7 +2467,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
flex_vars: Vec::new(), // empty because Roc function defs have no args
|
||||||
def_types: SendMap::default(), // empty because Roc function defs have no args
|
def_types: SendMap::default(), // empty because Roc function defs have no args
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True, // I think this is correct, once again because there are no args
|
defs_constraint: True, // I think this is correct, once again because there are no args
|
||||||
ret_constraint: expr_con,
|
ret_constraint: expr_con,
|
||||||
}));
|
}));
|
||||||
|
@ -2541,7 +2478,6 @@ pub fn rec_defs_help(
|
||||||
rigid_vars: new_rigids,
|
rigid_vars: new_rigids,
|
||||||
flex_vars: Vec::new(), // no flex vars introduced
|
flex_vars: Vec::new(), // no flex vars introduced
|
||||||
def_types: SendMap::default(), // no headers introduced (at this level)
|
def_types: SendMap::default(), // no headers introduced (at this level)
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: def_con,
|
defs_constraint: def_con,
|
||||||
ret_constraint: True,
|
ret_constraint: True,
|
||||||
})));
|
})));
|
||||||
|
@ -2550,25 +2486,19 @@ pub fn rec_defs_help(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// list aliases to Attr types
|
|
||||||
aliases_to_attr_type(var_store, &mut def_aliases);
|
|
||||||
|
|
||||||
Let(Box::new(LetConstraint {
|
Let(Box::new(LetConstraint {
|
||||||
rigid_vars: rigid_info.vars,
|
rigid_vars: rigid_info.vars,
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types: rigid_info.def_types,
|
def_types: rigid_info.def_types,
|
||||||
def_aliases,
|
|
||||||
defs_constraint: True,
|
defs_constraint: True,
|
||||||
ret_constraint: Let(Box::new(LetConstraint {
|
ret_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: flex_info.vars,
|
flex_vars: flex_info.vars,
|
||||||
def_types: flex_info.def_types.clone(),
|
def_types: flex_info.def_types.clone(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: Let(Box::new(LetConstraint {
|
defs_constraint: Let(Box::new(LetConstraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars: Vec::new(),
|
flex_vars: Vec::new(),
|
||||||
def_types: flex_info.def_types,
|
def_types: flex_info.def_types,
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: True,
|
defs_constraint: True,
|
||||||
ret_constraint: And(flex_info.constraints),
|
ret_constraint: And(flex_info.constraints),
|
||||||
})),
|
})),
|
||||||
|
@ -2604,93 +2534,3 @@ fn constrain_field_update(
|
||||||
|
|
||||||
(var, field_type, con)
|
(var, field_type, con)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fix uniqueness attributes on mutually recursive type aliases.
|
|
||||||
/// Given aliases
|
|
||||||
///
|
|
||||||
/// > ListA a b : [ Cons a (ListB b a), Nil ]
|
|
||||||
/// > ListB a b : [ Cons a (ListA b a), Nil ]
|
|
||||||
///
|
|
||||||
/// We get the lifted alias:
|
|
||||||
///
|
|
||||||
/// > `Test.ListB`: Alias {
|
|
||||||
/// > ...,
|
|
||||||
/// > uniqueness: Some(
|
|
||||||
/// > Container(
|
|
||||||
/// > 118,
|
|
||||||
/// > {},
|
|
||||||
/// > ),
|
|
||||||
/// > ),
|
|
||||||
/// > typ: [ Global('Cons') <9> (`#Attr.Attr` Container(119, {}) Alias `Test.ListA` <10> <9>[ but actually [ Global('Cons') <10> (`#Attr.Attr` Container(118, {}) <13>), Global('Nil') ] ]), Global('Nil') ] as <13>,
|
|
||||||
/// > },
|
|
||||||
///
|
|
||||||
/// Note that the alias will get uniqueness variable <118>, but the contained `ListA` gets variable
|
|
||||||
/// <119>. But, 119 is contained in 118, and 118 in 119, so we need <119> >= <118> >= <119> >= <118> ...
|
|
||||||
/// That can only be true if they are the same. Type inference will not find that, so we must do it
|
|
||||||
/// ourselves in user-defined aliases.
|
|
||||||
fn fix_mutual_recursive_alias(typ: &mut Type, attribute: &Bool) {
|
|
||||||
use Type::*;
|
|
||||||
if let RecursiveTagUnion(rec, tags, _ext) = typ {
|
|
||||||
for (_, args) in tags {
|
|
||||||
for mut arg in args {
|
|
||||||
fix_mutual_recursive_alias_help(*rec, &Type::Boolean(attribute.clone()), &mut arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fix_mutual_recursive_alias_help(rec_var: Variable, attribute: &Type, into_type: &mut Type) {
|
|
||||||
if into_type.contains_variable(rec_var) {
|
|
||||||
if let Type::Apply(Symbol::ATTR_ATTR, args) = into_type {
|
|
||||||
args[0] = attribute.clone();
|
|
||||||
|
|
||||||
fix_mutual_recursive_alias_help_help(rec_var, attribute, &mut args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn fix_mutual_recursive_alias_help_help(rec_var: Variable, attribute: &Type, into_type: &mut Type) {
|
|
||||||
use Type::*;
|
|
||||||
|
|
||||||
match into_type {
|
|
||||||
Function(args, closure, ret) => {
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, ret);
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, closure);
|
|
||||||
args.iter_mut()
|
|
||||||
.for_each(|arg| fix_mutual_recursive_alias_help(rec_var, attribute, arg));
|
|
||||||
}
|
|
||||||
RecursiveTagUnion(_, tags, ext) | TagUnion(tags, ext) => {
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, ext);
|
|
||||||
|
|
||||||
for (_tag, args) in tags.iter_mut() {
|
|
||||||
for arg in args.iter_mut() {
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Record(fields, ext) => {
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, ext);
|
|
||||||
|
|
||||||
for field in fields.iter_mut() {
|
|
||||||
let arg = match field {
|
|
||||||
RecordField::Required(arg) => arg,
|
|
||||||
RecordField::Optional(arg) => arg,
|
|
||||||
RecordField::Demanded(arg) => arg,
|
|
||||||
};
|
|
||||||
|
|
||||||
fix_mutual_recursive_alias_help(rec_var, attribute, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Alias(_, _, actual_type) => {
|
|
||||||
// call help_help, because actual_type is not wrapped in ATTR
|
|
||||||
fix_mutual_recursive_alias_help_help(rec_var, attribute, actual_type);
|
|
||||||
}
|
|
||||||
Apply(_, args) => {
|
|
||||||
args.iter_mut()
|
|
||||||
.for_each(|arg| fix_mutual_recursive_alias_help(rec_var, attribute, arg));
|
|
||||||
}
|
|
||||||
EmptyRec | EmptyTagUnion | Erroneous(_) | Variable(_) | Boolean(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -276,11 +276,6 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||||
let module_ids = Arc::clone(&state.arc_modules);
|
let module_ids = Arc::clone(&state.arc_modules);
|
||||||
let module_ids = { (*module_ids).lock().clone() };
|
let module_ids = { (*module_ids).lock().clone() };
|
||||||
|
|
||||||
// debug_assert!(parse
|
|
||||||
// .imported_modules
|
|
||||||
// .iter()
|
|
||||||
// .all(|id| module_ids.get_name(*id).is_some()));
|
|
||||||
|
|
||||||
let exposed_symbols = state
|
let exposed_symbols = state
|
||||||
.exposed_symbols_by_module
|
.exposed_symbols_by_module
|
||||||
.remove(&module_id)
|
.remove(&module_id)
|
||||||
|
@ -312,63 +307,6 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase::ParseAndGenerateConstraints => {
|
|
||||||
// let header = state.module_cache.headers.remove(&module_id).unwrap();
|
|
||||||
// let module_id = header.module_id;
|
|
||||||
// let deps_by_name = &header.deps_by_name;
|
|
||||||
// let num_deps = deps_by_name.len();
|
|
||||||
// let mut dep_idents: IdentIdsByModule = IdentIds::exposed_builtins(num_deps);
|
|
||||||
//
|
|
||||||
// let State {
|
|
||||||
// ident_ids_by_module,
|
|
||||||
// ..
|
|
||||||
// } = &state;
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// let ident_ids_by_module = (*ident_ids_by_module).lock();
|
|
||||||
//
|
|
||||||
// // Populate dep_idents with each of their IdentIds,
|
|
||||||
// // which we'll need during canonicalization to translate
|
|
||||||
// // identifier strings into IdentIds, which we need to build Symbols.
|
|
||||||
// // We only include the modules we care about (the ones we import).
|
|
||||||
// //
|
|
||||||
// // At the end of this loop, dep_idents contains all the information to
|
|
||||||
// // resolve a symbol from another module: if it's in here, that means
|
|
||||||
// // we have both imported the module and the ident was exported by that mdoule.
|
|
||||||
// for dep_id in header.deps_by_name.values() {
|
|
||||||
// // We already verified that these are all present,
|
|
||||||
// // so unwrapping should always succeed here.
|
|
||||||
// let idents = ident_ids_by_module.get(&dep_id).unwrap();
|
|
||||||
//
|
|
||||||
// dep_idents.insert(*dep_id, idents.clone());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Clone the module_ids we'll need for canonicalization.
|
|
||||||
// // This should be small, and cloning it should be quick.
|
|
||||||
// // We release the lock as soon as we're done cloning, so we don't have
|
|
||||||
// // to lock the global module_ids while canonicalizing any given module.
|
|
||||||
// let module_ids = Arc::clone(&state.arc_modules);
|
|
||||||
// let module_ids = { (*module_ids).lock().clone() };
|
|
||||||
//
|
|
||||||
// debug_assert!(header
|
|
||||||
// .imported_modules
|
|
||||||
// .iter()
|
|
||||||
// .all(|id| module_ids.get_name(*id).is_some()));
|
|
||||||
//
|
|
||||||
// let exposed_symbols = state
|
|
||||||
// .exposed_symbols_by_module
|
|
||||||
// .remove(&module_id)
|
|
||||||
// .expect("Could not find listener ID in exposed_symbols_by_module");
|
|
||||||
//
|
|
||||||
// BuildTask::ParseAndConstrain {
|
|
||||||
// header,
|
|
||||||
// mode: state.stdlib.mode,
|
|
||||||
// module_ids,
|
|
||||||
// dep_idents,
|
|
||||||
// exposed_symbols,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
Phase::SolveTypes => {
|
Phase::SolveTypes => {
|
||||||
let constrained = state.module_cache.constrained.remove(&module_id).unwrap();
|
let constrained = state.module_cache.constrained.remove(&module_id).unwrap();
|
||||||
|
|
||||||
|
@ -564,18 +502,6 @@ enum Msg<'a> {
|
||||||
canonicalization_problems: Vec<roc_problem::can::Problem>,
|
canonicalization_problems: Vec<roc_problem::can::Problem>,
|
||||||
module_docs: ModuleDocumentation,
|
module_docs: ModuleDocumentation,
|
||||||
},
|
},
|
||||||
// Constrained {
|
|
||||||
// module: Module,
|
|
||||||
// declarations: Vec<Declaration>,
|
|
||||||
// imported_modules: MutSet<ModuleId>,
|
|
||||||
// src: &'a str,
|
|
||||||
// constraint: Constraint,
|
|
||||||
// ident_ids: IdentIds,
|
|
||||||
// problems: Vec<roc_problem::can::Problem>,
|
|
||||||
// var_store: VarStore,
|
|
||||||
// module_timing: ModuleTiming,
|
|
||||||
// module_docs: ModuleDocumentation,
|
|
||||||
// },
|
|
||||||
SolvedTypes {
|
SolvedTypes {
|
||||||
src: &'a str,
|
src: &'a str,
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
|
@ -772,7 +698,6 @@ enum BuildTask<'a> {
|
||||||
module: Module,
|
module: Module,
|
||||||
ident_ids: IdentIds,
|
ident_ids: IdentIds,
|
||||||
imported_symbols: Vec<Import>,
|
imported_symbols: Vec<Import>,
|
||||||
imported_aliases: MutMap<Symbol, Alias>,
|
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
constraint: Constraint,
|
constraint: Constraint,
|
||||||
var_store: VarStore,
|
var_store: VarStore,
|
||||||
|
@ -2004,7 +1929,7 @@ impl<'a> BuildTask<'a> {
|
||||||
// (which would be more expensive for the main thread).
|
// (which would be more expensive for the main thread).
|
||||||
let ConstrainableImports {
|
let ConstrainableImports {
|
||||||
imported_symbols,
|
imported_symbols,
|
||||||
imported_aliases,
|
imported_aliases: _,
|
||||||
unused_imports,
|
unused_imports,
|
||||||
} = pre_constrain_imports(
|
} = pre_constrain_imports(
|
||||||
home,
|
home,
|
||||||
|
@ -2027,7 +1952,6 @@ impl<'a> BuildTask<'a> {
|
||||||
module,
|
module,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
imported_symbols,
|
imported_symbols,
|
||||||
imported_aliases,
|
|
||||||
constraint,
|
constraint,
|
||||||
var_store,
|
var_store,
|
||||||
src,
|
src,
|
||||||
|
@ -2043,7 +1967,6 @@ fn run_solve<'a>(
|
||||||
ident_ids: IdentIds,
|
ident_ids: IdentIds,
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
imported_symbols: Vec<Import>,
|
imported_symbols: Vec<Import>,
|
||||||
imported_aliases: MutMap<Symbol, Alias>,
|
|
||||||
constraint: Constraint,
|
constraint: Constraint,
|
||||||
mut var_store: VarStore,
|
mut var_store: VarStore,
|
||||||
decls: Vec<Declaration>,
|
decls: Vec<Declaration>,
|
||||||
|
@ -2054,12 +1977,7 @@ fn run_solve<'a>(
|
||||||
|
|
||||||
// Finish constraining the module by wrapping the existing Constraint
|
// Finish constraining the module by wrapping the existing Constraint
|
||||||
// in the ones we just computed. We can do this off the main thread.
|
// in the ones we just computed. We can do this off the main thread.
|
||||||
let constraint = constrain_imports(
|
let constraint = constrain_imports(imported_symbols, constraint, &mut var_store);
|
||||||
imported_symbols,
|
|
||||||
imported_aliases,
|
|
||||||
constraint,
|
|
||||||
&mut var_store,
|
|
||||||
);
|
|
||||||
|
|
||||||
let constrain_end = SystemTime::now();
|
let constrain_end = SystemTime::now();
|
||||||
|
|
||||||
|
@ -2535,7 +2453,6 @@ fn run_task<'a>(
|
||||||
module,
|
module,
|
||||||
module_timing,
|
module_timing,
|
||||||
imported_symbols,
|
imported_symbols,
|
||||||
imported_aliases,
|
|
||||||
constraint,
|
constraint,
|
||||||
var_store,
|
var_store,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -2546,7 +2463,6 @@ fn run_task<'a>(
|
||||||
ident_ids,
|
ident_ids,
|
||||||
module_timing,
|
module_timing,
|
||||||
imported_symbols,
|
imported_symbols,
|
||||||
imported_aliases,
|
|
||||||
constraint,
|
constraint,
|
||||||
var_store,
|
var_store,
|
||||||
declarations,
|
declarations,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use roc_can::operator;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
||||||
use roc_constrain::expr::constrain_expr;
|
use roc_constrain::expr::constrain_expr;
|
||||||
use roc_constrain::module::{constrain_imported_values, load_builtin_aliases, Import};
|
use roc_constrain::module::{constrain_imported_values, Import};
|
||||||
use roc_module::ident::Ident;
|
use roc_module::ident::Ident;
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
||||||
use roc_parse::ast::{self, Attempting};
|
use roc_parse::ast::{self, Attempting};
|
||||||
|
@ -19,7 +19,6 @@ use roc_parse::parser::{loc, Fail, Parser, State};
|
||||||
use roc_problem::can::Problem;
|
use roc_problem::can::Problem;
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_solve::solve;
|
use roc_solve::solve;
|
||||||
use roc_types::solved_types::BuiltinAlias;
|
|
||||||
use roc_types::subs::{Content, Subs, VarStore, Variable};
|
use roc_types::subs::{Content, Subs, VarStore, Variable};
|
||||||
use roc_types::types::Type;
|
use roc_types::types::Type;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
|
@ -1834,7 +1834,7 @@ pub fn with_hole<'a>(
|
||||||
hole,
|
hole,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
LetNonRec(def, cont, _, _) => {
|
LetNonRec(def, cont, _) => {
|
||||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||||
if let Closure {
|
if let Closure {
|
||||||
function_type,
|
function_type,
|
||||||
|
@ -1944,7 +1944,7 @@ pub fn with_hole<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LetRec(defs, cont, _, _) => {
|
LetRec(defs, cont, _) => {
|
||||||
// because Roc is strict, only functions can be recursive!
|
// because Roc is strict, only functions can be recursive!
|
||||||
for def in defs.into_iter() {
|
for def in defs.into_iter() {
|
||||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||||
|
@ -3085,7 +3085,7 @@ pub fn from_can<'a>(
|
||||||
|
|
||||||
stmt
|
stmt
|
||||||
}
|
}
|
||||||
LetRec(defs, cont, _, _) => {
|
LetRec(defs, cont, _) => {
|
||||||
// because Roc is strict, only functions can be recursive!
|
// because Roc is strict, only functions can be recursive!
|
||||||
for def in defs.into_iter() {
|
for def in defs.into_iter() {
|
||||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||||
|
@ -3130,7 +3130,7 @@ pub fn from_can<'a>(
|
||||||
|
|
||||||
from_can(env, cont.value, procs, layout_cache)
|
from_can(env, cont.value, procs, layout_cache)
|
||||||
}
|
}
|
||||||
LetNonRec(def, cont, outer_pattern_vars, outer_annotation) => {
|
LetNonRec(def, cont, outer_annotation) => {
|
||||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||||
if let Closure { .. } = &def.loc_expr.value {
|
if let Closure { .. } = &def.loc_expr.value {
|
||||||
// Now that we know for sure it's a closure, get an owned
|
// Now that we know for sure it's a closure, get an owned
|
||||||
|
@ -3192,12 +3192,7 @@ pub fn from_can<'a>(
|
||||||
|
|
||||||
return rest;
|
return rest;
|
||||||
}
|
}
|
||||||
roc_can::expr::Expr::LetNonRec(
|
roc_can::expr::Expr::LetNonRec(nested_def, nested_cont, nested_annotation) => {
|
||||||
nested_def,
|
|
||||||
nested_cont,
|
|
||||||
nested_pattern_vars,
|
|
||||||
nested_annotation,
|
|
||||||
) => {
|
|
||||||
use roc_can::expr::Expr::*;
|
use roc_can::expr::Expr::*;
|
||||||
// We must transform
|
// We must transform
|
||||||
//
|
//
|
||||||
|
@ -3228,28 +3223,17 @@ pub fn from_can<'a>(
|
||||||
expr_var: def.expr_var,
|
expr_var: def.expr_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_inner = LetNonRec(
|
let new_inner = LetNonRec(Box::new(new_def), cont, outer_annotation);
|
||||||
Box::new(new_def),
|
|
||||||
cont,
|
|
||||||
outer_pattern_vars,
|
|
||||||
outer_annotation,
|
|
||||||
);
|
|
||||||
|
|
||||||
let new_outer = LetNonRec(
|
let new_outer = LetNonRec(
|
||||||
nested_def,
|
nested_def,
|
||||||
Box::new(Located::at_zero(new_inner)),
|
Box::new(Located::at_zero(new_inner)),
|
||||||
nested_pattern_vars,
|
|
||||||
nested_annotation,
|
nested_annotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
return from_can(env, new_outer, procs, layout_cache);
|
return from_can(env, new_outer, procs, layout_cache);
|
||||||
}
|
}
|
||||||
roc_can::expr::Expr::LetRec(
|
roc_can::expr::Expr::LetRec(nested_defs, nested_cont, nested_annotation) => {
|
||||||
nested_defs,
|
|
||||||
nested_cont,
|
|
||||||
nested_pattern_vars,
|
|
||||||
nested_annotation,
|
|
||||||
) => {
|
|
||||||
use roc_can::expr::Expr::*;
|
use roc_can::expr::Expr::*;
|
||||||
// We must transform
|
// We must transform
|
||||||
//
|
//
|
||||||
|
@ -3280,17 +3264,11 @@ pub fn from_can<'a>(
|
||||||
expr_var: def.expr_var,
|
expr_var: def.expr_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_inner = LetNonRec(
|
let new_inner = LetNonRec(Box::new(new_def), cont, outer_annotation);
|
||||||
Box::new(new_def),
|
|
||||||
cont,
|
|
||||||
outer_pattern_vars,
|
|
||||||
outer_annotation,
|
|
||||||
);
|
|
||||||
|
|
||||||
let new_outer = LetRec(
|
let new_outer = LetRec(
|
||||||
nested_defs,
|
nested_defs,
|
||||||
Box::new(Located::at_zero(new_inner)),
|
Box::new(Located::at_zero(new_inner)),
|
||||||
nested_pattern_vars,
|
|
||||||
nested_annotation,
|
nested_annotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use roc_can::operator;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
||||||
use roc_constrain::expr::constrain_expr;
|
use roc_constrain::expr::constrain_expr;
|
||||||
use roc_constrain::module::{constrain_imported_values, load_builtin_aliases, Import};
|
use roc_constrain::module::{constrain_imported_values, Import};
|
||||||
use roc_module::ident::Ident;
|
use roc_module::ident::Ident;
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
||||||
use roc_parse::ast::{self, Attempting};
|
use roc_parse::ast::{self, Attempting};
|
||||||
|
@ -210,7 +210,6 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
||||||
value: with_builtins,
|
value: with_builtins,
|
||||||
}),
|
}),
|
||||||
var_store.fresh(),
|
var_store.fresh(),
|
||||||
SendMap::default(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use roc_can::operator;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
use roc_collections::all::{ImMap, MutMap, SendMap, SendSet};
|
use roc_collections::all::{ImMap, MutMap, SendMap, SendSet};
|
||||||
use roc_constrain::expr::constrain_expr;
|
use roc_constrain::expr::constrain_expr;
|
||||||
use roc_constrain::module::{constrain_imported_values, load_builtin_aliases, Import};
|
use roc_constrain::module::{constrain_imported_values, Import};
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds};
|
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds};
|
||||||
use roc_parse::ast::{self, Attempting};
|
use roc_parse::ast::{self, Attempting};
|
||||||
use roc_parse::blankspace::space0_before;
|
use roc_parse::blankspace::space0_before;
|
||||||
|
|
|
@ -529,7 +529,7 @@ fn solve(
|
||||||
let result = offenders.len();
|
let result = offenders.len();
|
||||||
|
|
||||||
if result > 0 {
|
if result > 0 {
|
||||||
dbg!(&subs, &offenders, &let_con.def_types, &let_con.def_aliases);
|
dbg!(&subs, &offenders, &let_con.def_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
|
@ -10,7 +10,7 @@ use roc_can::operator;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
||||||
use roc_constrain::expr::constrain_expr;
|
use roc_constrain::expr::constrain_expr;
|
||||||
use roc_constrain::module::{constrain_imported_values, load_builtin_aliases, Import};
|
use roc_constrain::module::{constrain_imported_values, Import};
|
||||||
use roc_module::ident::Ident;
|
use roc_module::ident::Ident;
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
||||||
use roc_parse::ast::{self, Attempting};
|
use roc_parse::ast::{self, Attempting};
|
||||||
|
|
|
@ -826,9 +826,6 @@ fn unify_shared_tags(
|
||||||
let mut problems = Vec::new();
|
let mut problems = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
// we always unify NonRecursive with Recursive, so this should never happen
|
|
||||||
//debug_assert_ne!(Some(actual), recursion_var);
|
|
||||||
|
|
||||||
problems.extend(unify_pool(subs, pool, actual, expected));
|
problems.extend(unify_pool(subs, pool, actual, expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,9 +1148,7 @@ fn unify_recursion(
|
||||||
}
|
}
|
||||||
|
|
||||||
Structure(_) => {
|
Structure(_) => {
|
||||||
// keep the recursion var around
|
// unify the structure variable with this Structure
|
||||||
// merge(subs, ctx, FlexVar(opt_name.clone()))
|
|
||||||
|
|
||||||
unify_pool(subs, pool, structure, ctx.second)
|
unify_pool(subs, pool, structure, ctx.second)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ pub fn exists(flex_vars: Vec<Variable>, constraint: Constraint) -> Constraint {
|
||||||
rigid_vars: Vec::new(),
|
rigid_vars: Vec::new(),
|
||||||
flex_vars,
|
flex_vars,
|
||||||
def_types: SendMap::default(),
|
def_types: SendMap::default(),
|
||||||
def_aliases: SendMap::default(),
|
|
||||||
defs_constraint: constraint,
|
defs_constraint: constraint,
|
||||||
ret_constraint: Constraint::True,
|
ret_constraint: Constraint::True,
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -843,14 +843,14 @@ pub fn annotate_usage(expr: &Expr, usage: &mut VarUsage) {
|
||||||
annotate_usage(&loc_elem.value, usage);
|
annotate_usage(&loc_elem.value, usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LetNonRec(def, loc_expr, _, _) => {
|
LetNonRec(def, loc_expr, _) => {
|
||||||
annotate_usage(&def.loc_expr.value, usage);
|
annotate_usage(&def.loc_expr.value, usage);
|
||||||
annotate_usage(&loc_expr.value, usage);
|
annotate_usage(&loc_expr.value, usage);
|
||||||
|
|
||||||
// annotate defaults of optional record fields
|
// annotate defaults of optional record fields
|
||||||
annotate_usage_pattern(&def.loc_pattern.value, usage)
|
annotate_usage_pattern(&def.loc_pattern.value, usage)
|
||||||
}
|
}
|
||||||
LetRec(defs, loc_expr, _, _) => {
|
LetRec(defs, loc_expr, _) => {
|
||||||
// TODO test this with a practical example.
|
// TODO test this with a practical example.
|
||||||
if defs.len() == 1 {
|
if defs.len() == 1 {
|
||||||
// just like a letrec, but mark defined symbol as Shared
|
// just like a letrec, but mark defined symbol as Shared
|
||||||
|
|
|
@ -10,7 +10,7 @@ use roc_can::operator;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
use roc_collections::all::{ImMap, ImSet, MutMap, SendMap, SendSet};
|
||||||
use roc_constrain::expr::constrain_expr;
|
use roc_constrain::expr::constrain_expr;
|
||||||
use roc_constrain::module::{constrain_imported_values, load_builtin_aliases, Import};
|
use roc_constrain::module::{constrain_imported_values, Import};
|
||||||
use roc_module::ident::Ident;
|
use roc_module::ident::Ident;
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
||||||
use roc_parse::ast::{self, Attempting};
|
use roc_parse::ast::{self, Attempting};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue