Merge branch 'trunk' into fuzz

This commit is contained in:
Richard Feldman 2020-11-01 08:57:19 -05:00 committed by GitHub
commit 2f2e67059b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 56 additions and 593 deletions

View file

@ -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(),
); );
} }
} }

View file

@ -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,

View file

@ -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,
} }

View file

@ -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))
} }

View file

@ -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,
), ),
}; };
} }

View file

@ -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);

View file

@ -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)

View file

@ -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,
})) }))

View file

@ -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),
})), })),

View file

@ -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 {

View file

@ -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(_) => {}
}
}

View file

@ -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,

View file

@ -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;

View file

@ -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,
); );

View file

@ -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(),
); );
} }
} }

View file

@ -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;

View file

@ -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

View file

@ -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};

View file

@ -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)
} }

View file

@ -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,
})) }))

View file

@ -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

View file

@ -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};