mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Merging in remote
This commit is contained in:
commit
5ad05efa39
13 changed files with 122 additions and 95 deletions
|
@ -1,7 +1,5 @@
|
||||||
use crate::def::Def;
|
use crate::expr::{Expr, Recursive};
|
||||||
use crate::expr::Expr;
|
use roc_collections::all::MutMap;
|
||||||
use crate::expr::Recursive;
|
|
||||||
use roc_collections::all::SendMap;
|
|
||||||
use roc_module::ident::TagName;
|
use roc_module::ident::TagName;
|
||||||
use roc_module::operator::CalledVia;
|
use roc_module::operator::CalledVia;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
|
@ -25,27 +23,27 @@ use roc_types::subs::{VarStore, Variable};
|
||||||
/// delegates to the compiler-internal List.getUnsafe function to do the actual
|
/// delegates to the compiler-internal List.getUnsafe function to do the actual
|
||||||
/// lookup (if the bounds check passed). That internal function is hardcoded in code gen,
|
/// lookup (if the bounds check passed). That internal function is hardcoded in code gen,
|
||||||
/// which works fine because it doesn't involve any open tag unions.
|
/// which works fine because it doesn't involve any open tag unions.
|
||||||
pub fn builtin_defs(var_store: &VarStore) -> Vec<Def> {
|
pub fn builtin_defs(var_store: &VarStore) -> MutMap<Symbol, Expr> {
|
||||||
vec![
|
mut_map! {
|
||||||
list_get(var_store),
|
Symbol::LIST_GET => list_get(var_store),
|
||||||
list_first(var_store),
|
Symbol::LIST_FIRST => list_first(var_store),
|
||||||
int_div(var_store),
|
Symbol::INT_DIV => int_div(var_store),
|
||||||
int_abs(var_store),
|
Symbol::INT_ABS => int_abs(var_store),
|
||||||
int_rem(var_store),
|
Symbol::INT_REM => int_rem(var_store),
|
||||||
int_is_odd(var_store),
|
Symbol::INT_IS_ODD => int_is_odd(var_store),
|
||||||
int_is_even(var_store),
|
Symbol::INT_IS_EVEN => int_is_even(var_store),
|
||||||
int_is_zero(var_store),
|
Symbol::INT_IS_ZERO => int_is_zero(var_store),
|
||||||
int_is_positive(var_store),
|
Symbol::INT_IS_POSITIVE => int_is_positive(var_store),
|
||||||
int_is_negative(var_store),
|
Symbol::INT_IS_NEGATIVE => int_is_negative(var_store),
|
||||||
float_is_positive(var_store),
|
Symbol::FLOAT_IS_POSITIVE => float_is_positive(var_store),
|
||||||
float_is_negative(var_store),
|
Symbol::FLOAT_IS_NEGATIVE => float_is_negative(var_store),
|
||||||
float_is_zero(var_store),
|
Symbol::FLOAT_IS_ZERO => float_is_zero(var_store),
|
||||||
float_tan(var_store),
|
Symbol::FLOAT_TAN => float_tan(var_store),
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float.tan : Float -> Float
|
/// Float.tan : Float -> Float
|
||||||
fn float_tan(var_store: &VarStore) -> Def {
|
fn float_tan(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -72,7 +70,7 @@ fn float_tan(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float.isZero : Float -> Bool
|
/// Float.isZero : Float -> Bool
|
||||||
fn float_is_zero(var_store: &VarStore) -> Def {
|
fn float_is_zero(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -91,7 +89,7 @@ fn float_is_zero(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float.isNegative : Float -> Bool
|
/// Float.isNegative : Float -> Bool
|
||||||
fn float_is_negative(var_store: &VarStore) -> Def {
|
fn float_is_negative(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -110,7 +108,7 @@ fn float_is_negative(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float.isPositive : Float -> Bool
|
/// Float.isPositive : Float -> Bool
|
||||||
fn float_is_positive(var_store: &VarStore) -> Def {
|
fn float_is_positive(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -129,7 +127,7 @@ fn float_is_positive(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.isNegative : Int -> Bool
|
/// Int.isNegative : Int -> Bool
|
||||||
fn int_is_negative(var_store: &VarStore) -> Def {
|
fn int_is_negative(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -145,7 +143,7 @@ fn int_is_negative(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.isPositive : Int -> Bool
|
/// Int.isPositive : Int -> Bool
|
||||||
fn int_is_positive(var_store: &VarStore) -> Def {
|
fn int_is_positive(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -161,7 +159,7 @@ fn int_is_positive(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.isZero : Int -> Bool
|
/// Int.isZero : Int -> Bool
|
||||||
fn int_is_zero(var_store: &VarStore) -> Def {
|
fn int_is_zero(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -177,7 +175,7 @@ fn int_is_zero(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.isOdd : Int -> Bool
|
/// Int.isOdd : Int -> Bool
|
||||||
fn int_is_odd(var_store: &VarStore) -> Def {
|
fn int_is_odd(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -200,7 +198,7 @@ fn int_is_odd(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.isEven : Int -> Bool
|
/// Int.isEven : Int -> Bool
|
||||||
fn int_is_even(var_store: &VarStore) -> Def {
|
fn int_is_even(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -223,7 +221,7 @@ fn int_is_even(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.get : List elem, Int -> Result elem [ OutOfBounds ]*
|
/// List.get : List elem, Int -> Result elem [ OutOfBounds ]*
|
||||||
fn list_get(var_store: &VarStore) -> Def {
|
fn list_get(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -294,7 +292,7 @@ fn list_get(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.rem : Int, Int -> Int
|
/// Int.rem : Int, Int -> Int
|
||||||
fn int_rem(var_store: &VarStore) -> Def {
|
fn int_rem(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -341,7 +339,7 @@ fn int_rem(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.abs : Int -> Int
|
/// Int.abs : Int -> Int
|
||||||
fn int_abs(var_store: &VarStore) -> Def {
|
fn int_abs(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -378,7 +376,7 @@ fn int_abs(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Int.div : Int, Int -> Result Int [ DivByZero ]*
|
/// Int.div : Int, Int -> Result Int [ DivByZero ]*
|
||||||
fn int_div(var_store: &VarStore) -> Def {
|
fn int_div(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -437,7 +435,7 @@ fn int_div(var_store: &VarStore) -> Def {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.first : List elem -> Result elem [ ListWasEmpty ]*
|
/// List.first : List elem -> Result elem [ ListWasEmpty ]*
|
||||||
fn list_first(var_store: &VarStore) -> Def {
|
fn list_first(var_store: &VarStore) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
|
|
||||||
defn(
|
defn(
|
||||||
|
@ -529,7 +527,7 @@ fn call(symbol: Symbol, args: Vec<Expr>, var_store: &VarStore) -> Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn defn(fn_name: Symbol, args: Vec<Symbol>, var_store: &VarStore, body: Expr) -> Def {
|
fn defn(fn_name: Symbol, args: Vec<Symbol>, var_store: &VarStore, body: Expr) -> Expr {
|
||||||
use crate::expr::Expr::*;
|
use crate::expr::Expr::*;
|
||||||
use crate::pattern::Pattern::*;
|
use crate::pattern::Pattern::*;
|
||||||
|
|
||||||
|
@ -538,19 +536,11 @@ fn defn(fn_name: Symbol, args: Vec<Symbol>, var_store: &VarStore, body: Expr) ->
|
||||||
.map(|symbol| (var_store.fresh(), no_region(Identifier(symbol))))
|
.map(|symbol| (var_store.fresh(), no_region(Identifier(symbol))))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let expr = Closure(
|
Closure(
|
||||||
var_store.fresh(),
|
var_store.fresh(),
|
||||||
fn_name,
|
fn_name,
|
||||||
Recursive::NotRecursive,
|
Recursive::NotRecursive,
|
||||||
closure_args,
|
closure_args,
|
||||||
Box::new((no_region(body), var_store.fresh())),
|
Box::new((no_region(body), var_store.fresh())),
|
||||||
);
|
)
|
||||||
|
|
||||||
Def {
|
|
||||||
loc_pattern: no_region(Identifier(fn_name)),
|
|
||||||
loc_expr: no_region(expr),
|
|
||||||
expr_var: var_store.fresh(),
|
|
||||||
pattern_vars: SendMap::default(),
|
|
||||||
annotation: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,8 +358,8 @@ pub fn sort_can_defs(
|
||||||
let mut defined_symbols_set: ImSet<Symbol> = ImSet::default();
|
let mut defined_symbols_set: ImSet<Symbol> = ImSet::default();
|
||||||
|
|
||||||
for symbol in can_defs_by_symbol.keys().into_iter() {
|
for symbol in can_defs_by_symbol.keys().into_iter() {
|
||||||
defined_symbols.push(symbol.clone());
|
defined_symbols.push(*symbol);
|
||||||
defined_symbols_set.insert(symbol.clone());
|
defined_symbols_set.insert(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use topological sort to reorder the defs based on their dependencies to one another.
|
// Use topological sort to reorder the defs based on their dependencies to one another.
|
||||||
|
@ -688,7 +688,7 @@ fn pattern_to_vars_by_symbol(
|
||||||
use Pattern::*;
|
use Pattern::*;
|
||||||
match pattern {
|
match pattern {
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
vars_by_symbol.insert(symbol.clone(), expr_var);
|
vars_by_symbol.insert(*symbol, expr_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppliedTag { arguments, .. } => {
|
AppliedTag { arguments, .. } => {
|
||||||
|
@ -699,7 +699,7 @@ fn pattern_to_vars_by_symbol(
|
||||||
|
|
||||||
RecordDestructure { destructs, .. } => {
|
RecordDestructure { destructs, .. } => {
|
||||||
for destruct in destructs {
|
for destruct in destructs {
|
||||||
vars_by_symbol.insert(destruct.value.symbol.clone(), destruct.value.var);
|
vars_by_symbol.insert(destruct.value.symbol, destruct.value.var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,7 +947,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
) = (
|
) = (
|
||||||
&loc_pattern.value,
|
&loc_pattern.value,
|
||||||
&loc_can_pattern.value,
|
&loc_can_pattern.value,
|
||||||
&loc_can_expr.value.clone(),
|
&loc_can_expr.value,
|
||||||
) {
|
) {
|
||||||
is_closure = true;
|
is_closure = true;
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
// closures don't have a name, and therefore pick a fresh symbol. But in this
|
// closures don't have a name, and therefore pick a fresh symbol. But in this
|
||||||
// case, the closure has a proper name (e.g. `foo` in `foo = \x y -> ...`
|
// case, the closure has a proper name (e.g. `foo` in `foo = \x y -> ...`
|
||||||
// and we want to reference it by that name.
|
// and we want to reference it by that name.
|
||||||
env.closures.insert(defined_symbol.clone(), references);
|
env.closures.insert(*defined_symbol, references);
|
||||||
|
|
||||||
// The closure is self tail recursive iff it tail calls itself (by defined name).
|
// The closure is self tail recursive iff it tail calls itself (by defined name).
|
||||||
let is_recursive = match can_output.tail_call {
|
let is_recursive = match can_output.tail_call {
|
||||||
|
@ -975,7 +975,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
||||||
// would result in circular def errors!)
|
// would result in circular def errors!)
|
||||||
refs_by_symbol
|
refs_by_symbol
|
||||||
.entry(defined_symbol.clone())
|
.entry(*defined_symbol)
|
||||||
.and_modify(|(_, refs)| {
|
.and_modify(|(_, refs)| {
|
||||||
refs.lookups = refs.lookups.without(defined_symbol);
|
refs.lookups = refs.lookups.without(defined_symbol);
|
||||||
});
|
});
|
||||||
|
@ -1008,7 +1008,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
refs_by_symbol.insert(
|
refs_by_symbol.insert(
|
||||||
symbol.clone(),
|
*symbol,
|
||||||
(
|
(
|
||||||
Located {
|
Located {
|
||||||
value: ident.clone(),
|
value: ident.clone(),
|
||||||
|
@ -1055,7 +1055,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
env.tailcallable_symbol = Some(*defined_symbol);
|
env.tailcallable_symbol = Some(*defined_symbol);
|
||||||
|
|
||||||
// TODO isn't types_by_symbol enough? Do we need vars_by_symbol too?
|
// TODO isn't types_by_symbol enough? Do we need vars_by_symbol too?
|
||||||
vars_by_symbol.insert(defined_symbol.clone(), expr_var);
|
vars_by_symbol.insert(*defined_symbol, expr_var);
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut loc_can_expr, can_output) =
|
let (mut loc_can_expr, can_output) =
|
||||||
|
@ -1080,7 +1080,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
) = (
|
) = (
|
||||||
&loc_pattern.value,
|
&loc_pattern.value,
|
||||||
&loc_can_pattern.value,
|
&loc_can_pattern.value,
|
||||||
&loc_can_expr.value.clone(),
|
&loc_can_expr.value,
|
||||||
) {
|
) {
|
||||||
is_closure = true;
|
is_closure = true;
|
||||||
|
|
||||||
|
@ -1097,7 +1097,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
// closures don't have a name, and therefore pick a fresh symbol. But in this
|
// closures don't have a name, and therefore pick a fresh symbol. But in this
|
||||||
// case, the closure has a proper name (e.g. `foo` in `foo = \x y -> ...`
|
// case, the closure has a proper name (e.g. `foo` in `foo = \x y -> ...`
|
||||||
// and we want to reference it by that name.
|
// and we want to reference it by that name.
|
||||||
env.closures.insert(defined_symbol.clone(), references);
|
env.closures.insert(*defined_symbol, references);
|
||||||
|
|
||||||
// The closure is self tail recursive iff it tail calls itself (by defined name).
|
// The closure is self tail recursive iff it tail calls itself (by defined name).
|
||||||
let is_recursive = match can_output.tail_call {
|
let is_recursive = match can_output.tail_call {
|
||||||
|
@ -1108,7 +1108,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
||||||
// would result in circular def errors!)
|
// would result in circular def errors!)
|
||||||
refs_by_symbol
|
refs_by_symbol
|
||||||
.entry(defined_symbol.clone())
|
.entry(*defined_symbol)
|
||||||
.and_modify(|(_, refs)| {
|
.and_modify(|(_, refs)| {
|
||||||
refs.lookups = refs.lookups.without(defined_symbol);
|
refs.lookups = refs.lookups.without(defined_symbol);
|
||||||
});
|
});
|
||||||
|
@ -1145,7 +1145,7 @@ fn canonicalize_pending_def<'a>(
|
||||||
});
|
});
|
||||||
|
|
||||||
refs_by_symbol.insert(
|
refs_by_symbol.insert(
|
||||||
symbol.clone(),
|
symbol,
|
||||||
(
|
(
|
||||||
Located {
|
Located {
|
||||||
value: ident.clone().into(),
|
value: ident.clone().into(),
|
||||||
|
@ -1259,7 +1259,7 @@ fn closure_recursivity(symbol: Symbol, closures: &MutMap<Symbol, References>) ->
|
||||||
|
|
||||||
if let Some(references) = closures.get(&symbol) {
|
if let Some(references) = closures.get(&symbol) {
|
||||||
for v in &references.calls {
|
for v in &references.calls {
|
||||||
stack.push(v.clone());
|
stack.push(*v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// while there are symbols left to visit
|
// while there are symbols left to visit
|
||||||
|
@ -1275,7 +1275,7 @@ fn closure_recursivity(symbol: Symbol, closures: &MutMap<Symbol, References>) ->
|
||||||
if let Some(nested_references) = closures.get(&nested_symbol) {
|
if let Some(nested_references) = closures.get(&nested_symbol) {
|
||||||
// add its called to the stack
|
// add its called to the stack
|
||||||
for v in &nested_references.calls {
|
for v in &nested_references.calls {
|
||||||
stack.push(v.clone());
|
stack.push(*v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visited.insert(nested_symbol);
|
visited.insert(nested_symbol);
|
||||||
|
|
|
@ -450,7 +450,7 @@ pub fn canonicalize_expr<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env.register_closure(symbol.clone(), output.references.clone());
|
env.register_closure(symbol, output.references.clone());
|
||||||
|
|
||||||
(
|
(
|
||||||
Closure(
|
Closure(
|
||||||
|
@ -818,7 +818,7 @@ where
|
||||||
answer = answer.union(other_refs);
|
answer = answer.union(other_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
answer.lookups.insert(local.clone());
|
answer.lookups.insert(*local);
|
||||||
}
|
}
|
||||||
|
|
||||||
for call in refs.calls.iter() {
|
for call in refs.calls.iter() {
|
||||||
|
@ -828,7 +828,7 @@ where
|
||||||
answer = answer.union(other_refs);
|
answer = answer.union(other_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
answer.calls.insert(call.clone());
|
answer.calls.insert(*call);
|
||||||
}
|
}
|
||||||
|
|
||||||
answer
|
answer
|
||||||
|
@ -860,7 +860,7 @@ where
|
||||||
answer = answer.union(other_refs);
|
answer = answer.union(other_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
answer.lookups.insert(closed_over_local.clone());
|
answer.lookups.insert(*closed_over_local);
|
||||||
}
|
}
|
||||||
|
|
||||||
for call in references.calls.iter() {
|
for call in references.calls.iter() {
|
||||||
|
|
|
@ -24,3 +24,6 @@ pub mod pattern;
|
||||||
pub mod procedure;
|
pub mod procedure;
|
||||||
pub mod scope;
|
pub mod scope;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate roc_collections;
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub fn symbols_from_pattern_help(pattern: &Pattern, symbols: &mut Vec<Symbol>) {
|
||||||
|
|
||||||
match pattern {
|
match pattern {
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
symbols.push(symbol.clone());
|
symbols.push(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppliedTag { arguments, .. } => {
|
AppliedTag { arguments, .. } => {
|
||||||
|
@ -67,7 +67,7 @@ pub fn symbols_from_pattern_help(pattern: &Pattern, symbols: &mut Vec<Symbol>) {
|
||||||
}
|
}
|
||||||
RecordDestructure { destructs, .. } => {
|
RecordDestructure { destructs, .. } => {
|
||||||
for destruct in destructs {
|
for destruct in destructs {
|
||||||
symbols.push(destruct.value.symbol.clone());
|
symbols.push(destruct.value.symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,3 +134,21 @@ fn int_to_ordinal(number: usize) -> std::string::String {
|
||||||
|
|
||||||
format!("{}{}", number, ending)
|
format!("{}{}", number, ending)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! mut_map {
|
||||||
|
(@single $($x:tt)*) => (());
|
||||||
|
(@count $($rest:expr),*) => (<[()]>::len(&[$(mut_map!(@single $rest)),*]));
|
||||||
|
|
||||||
|
($($key:expr => $value:expr,)+) => { mut_map!($($key => $value),+) };
|
||||||
|
($($key:expr => $value:expr),*) => {
|
||||||
|
{
|
||||||
|
let _cap = mut_map!(@count $($key),*);
|
||||||
|
let mut _map = ::std::collections::HashMap::with_capacity_and_hasher(_cap, $crate::all::default_hasher());
|
||||||
|
$(
|
||||||
|
let _ = _map.insert($key, $value);
|
||||||
|
)*
|
||||||
|
_map
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ fn headers_from_annotation_help(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match pattern {
|
match pattern {
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
headers.insert(symbol.clone(), annotation.clone());
|
headers.insert(*symbol, annotation.clone());
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Underscore
|
Underscore
|
||||||
|
@ -64,7 +64,7 @@ fn headers_from_annotation_help(
|
||||||
// NOTE ignores the .guard field.
|
// NOTE ignores the .guard field.
|
||||||
if let Some(field_type) = fields.get(&destruct.value.label) {
|
if let Some(field_type) = fields.get(&destruct.value.label) {
|
||||||
headers.insert(
|
headers.insert(
|
||||||
destruct.value.symbol.clone(),
|
destruct.value.symbol,
|
||||||
Located::at(annotation.region, field_type.clone()),
|
Located::at(annotation.region, field_type.clone()),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -123,7 +123,7 @@ pub fn constrain_pattern(
|
||||||
|
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
state.headers.insert(
|
state.headers.insert(
|
||||||
symbol.clone(),
|
*symbol,
|
||||||
Located {
|
Located {
|
||||||
region,
|
region,
|
||||||
value: expected.get_type(),
|
value: expected.get_type(),
|
||||||
|
@ -197,7 +197,7 @@ pub fn constrain_pattern(
|
||||||
if !state.headers.contains_key(&symbol) {
|
if !state.headers.contains_key(&symbol) {
|
||||||
state
|
state
|
||||||
.headers
|
.headers
|
||||||
.insert(symbol.clone(), Located::at(region, pat_type.clone()));
|
.insert(*symbol, Located::at(region, pat_type.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
field_types.insert(label.clone(), pat_type.clone());
|
field_types.insert(label.clone(), pat_type.clone());
|
||||||
|
|
|
@ -148,7 +148,7 @@ fn constrain_pattern(
|
||||||
match &pattern.value {
|
match &pattern.value {
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
state.headers.insert(
|
state.headers.insert(
|
||||||
symbol.clone(),
|
*symbol,
|
||||||
Located {
|
Located {
|
||||||
region: pattern.region,
|
region: pattern.region,
|
||||||
value: expected.get_type(),
|
value: expected.get_type(),
|
||||||
|
@ -223,10 +223,9 @@ fn constrain_pattern(
|
||||||
let expected = PExpected::NoExpectation(pat_type.clone());
|
let expected = PExpected::NoExpectation(pat_type.clone());
|
||||||
|
|
||||||
if !state.headers.contains_key(&symbol) {
|
if !state.headers.contains_key(&symbol) {
|
||||||
state.headers.insert(
|
state
|
||||||
symbol.clone(),
|
.headers
|
||||||
Located::at(pattern.region, pat_type.clone()),
|
.insert(*symbol, Located::at(pattern.region, pat_type.clone()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
field_types.insert(label.clone(), pat_type.clone());
|
field_types.insert(label.clone(), pat_type.clone());
|
||||||
|
@ -1391,7 +1390,7 @@ fn constrain_var(
|
||||||
Lookup(symbol_for_lookup, expected, region)
|
Lookup(symbol_for_lookup, expected, region)
|
||||||
}
|
}
|
||||||
Some(Usage::Access(_, _, _)) | Some(Usage::Update(_, _, _)) => {
|
Some(Usage::Access(_, _, _)) | Some(Usage::Update(_, _, _)) => {
|
||||||
applied_usage_constraint.insert(symbol_for_lookup.clone());
|
applied_usage_constraint.insert(symbol_for_lookup);
|
||||||
|
|
||||||
let mut variables = Vec::new();
|
let mut variables = Vec::new();
|
||||||
let (free, rest, inner_type) =
|
let (free, rest, inner_type) =
|
||||||
|
|
|
@ -6,10 +6,12 @@ pub mod eval;
|
||||||
use self::bumpalo::Bump;
|
use self::bumpalo::Bump;
|
||||||
use roc_builtins::unique::uniq_stdlib;
|
use roc_builtins::unique::uniq_stdlib;
|
||||||
use roc_can::constraint::Constraint;
|
use roc_can::constraint::Constraint;
|
||||||
|
use roc_can::def::Def;
|
||||||
use roc_can::env::Env;
|
use roc_can::env::Env;
|
||||||
use roc_can::expected::Expected;
|
use roc_can::expected::Expected;
|
||||||
use roc_can::expr::{canonicalize_expr, Expr, Output};
|
use roc_can::expr::{canonicalize_expr, Expr, Output};
|
||||||
use roc_can::operator;
|
use roc_can::operator;
|
||||||
|
use roc_can::pattern::Pattern;
|
||||||
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;
|
||||||
|
@ -245,16 +247,31 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
||||||
// since we aren't using modules here.
|
// since we aren't using modules here.
|
||||||
let builtin_defs = roc_can::builtins::builtin_defs(&var_store);
|
let builtin_defs = roc_can::builtins::builtin_defs(&var_store);
|
||||||
|
|
||||||
for def in builtin_defs {
|
for (symbol, expr) in builtin_defs {
|
||||||
with_builtins = Expr::LetNonRec(
|
if output.references.lookups.contains(&symbol) || output.references.calls.contains(&symbol)
|
||||||
Box::new(def),
|
{
|
||||||
Box::new(Located {
|
with_builtins = Expr::LetNonRec(
|
||||||
region: Region::zero(),
|
Box::new(Def {
|
||||||
value: with_builtins,
|
loc_pattern: Located {
|
||||||
}),
|
region: Region::zero(),
|
||||||
var_store.fresh(),
|
value: Pattern::Identifier(symbol),
|
||||||
SendMap::default(),
|
},
|
||||||
);
|
loc_expr: Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: expr,
|
||||||
|
},
|
||||||
|
expr_var: var_store.fresh(),
|
||||||
|
pattern_vars: SendMap::default(),
|
||||||
|
annotation: None,
|
||||||
|
}),
|
||||||
|
Box::new(Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: with_builtins,
|
||||||
|
}),
|
||||||
|
var_store.fresh(),
|
||||||
|
SendMap::default(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loc_expr = Located {
|
let loc_expr = Located {
|
||||||
|
|
|
@ -280,7 +280,7 @@ fn pretty_runtime_error<'b>(
|
||||||
if idents.is_empty() {
|
if idents.is_empty() {
|
||||||
alloc
|
alloc
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.ident(first.value.clone()))
|
.append(alloc.ident(first.value))
|
||||||
.append(alloc.reflow(
|
.append(alloc.reflow(
|
||||||
" value is defined directly in terms of itself, causing an infinite loop.",
|
" value is defined directly in terms of itself, causing an infinite loop.",
|
||||||
))
|
))
|
||||||
|
|
|
@ -333,7 +333,7 @@ fn solve(
|
||||||
let var = type_to_var(subs, rank, pools, cached_aliases, &loc_type.value);
|
let var = type_to_var(subs, rank, pools, cached_aliases, &loc_type.value);
|
||||||
|
|
||||||
local_def_vars.insert(
|
local_def_vars.insert(
|
||||||
symbol.clone(),
|
*symbol,
|
||||||
Located {
|
Located {
|
||||||
value: var,
|
value: var,
|
||||||
region: loc_type.region,
|
region: loc_type.region,
|
||||||
|
@ -344,7 +344,7 @@ fn solve(
|
||||||
let mut new_env = env.clone();
|
let mut new_env = env.clone();
|
||||||
for (symbol, loc_var) in local_def_vars.iter() {
|
for (symbol, loc_var) in local_def_vars.iter() {
|
||||||
if !new_env.vars_by_symbol.contains_key(&symbol) {
|
if !new_env.vars_by_symbol.contains_key(&symbol) {
|
||||||
new_env.vars_by_symbol.insert(symbol.clone(), loc_var.value);
|
new_env.vars_by_symbol.insert(*symbol, loc_var.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ fn solve(
|
||||||
type_to_var(subs, next_rank, next_pools, cached_aliases, &def_type);
|
type_to_var(subs, next_rank, next_pools, cached_aliases, &def_type);
|
||||||
|
|
||||||
local_def_vars.insert(
|
local_def_vars.insert(
|
||||||
symbol.clone(),
|
*symbol,
|
||||||
Located {
|
Located {
|
||||||
value: var,
|
value: var,
|
||||||
region: loc_type.region,
|
region: loc_type.region,
|
||||||
|
@ -469,7 +469,7 @@ fn solve(
|
||||||
|
|
||||||
for (symbol, loc_var) in local_def_vars.iter() {
|
for (symbol, loc_var) in local_def_vars.iter() {
|
||||||
if !new_env.vars_by_symbol.contains_key(&symbol) {
|
if !new_env.vars_by_symbol.contains_key(&symbol) {
|
||||||
new_env.vars_by_symbol.insert(symbol.clone(), loc_var.value);
|
new_env.vars_by_symbol.insert(*symbol, loc_var.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ impl Bool {
|
||||||
|
|
||||||
for atom in &self.1 {
|
for atom in &self.1 {
|
||||||
if let Variable(v) = atom {
|
if let Variable(v) = atom {
|
||||||
result.insert(v.clone());
|
result.insert(*v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ impl Bool {
|
||||||
if let Variable(v) = atom {
|
if let Variable(v) = atom {
|
||||||
new_bound.insert(Variable(f(*v)));
|
new_bound.insert(Variable(f(*v)));
|
||||||
} else {
|
} else {
|
||||||
new_bound.insert(atom.clone());
|
new_bound.insert(*atom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Bool(new_free, new_bound)
|
Bool(new_free, new_bound)
|
||||||
|
|
|
@ -416,7 +416,7 @@ impl Composable for VarUsage {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.usage.insert(symbol.clone(), value);
|
self.usage.insert(*symbol, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue