Merge branch 'trunk' of github.com:rtfeldman/roc into list-repeat

This commit is contained in:
Chad Stearns 2020-06-20 13:45:04 -04:00
commit 7bf8be5e9a
25 changed files with 533 additions and 470 deletions

View File

@ -9,8 +9,25 @@ To see which version of LLVM you need, take a look at `Cargo.toml`, in particula
For Ubuntu, I used the `Automatic installation script` at [apt.llvm.org](https://apt.llvm.org) - but there are plenty of alternative options at http://releases.llvm.org/download.html
> On some Linux systems we've seen the error "failed to run custom build command for x11".
> On Ubuntu, running `sudo apt-get install cmake libx11-dev` fixed this.
### Troubleshooting LLVM installation on Linux
On some Linux systems we've seen the error "failed to run custom build command for x11".
On Ubuntu, running `sudo apt-get install cmake libx11-dev` fixed this.
### Troubleshooting LLVM installation on Windows
Installing LLVM's prebuilt binaries doesn't seem to be enough for the `llvm-sys` crate that Roc depends on, so I had to build LLVM from source
on Windows. After lots of help from [**@IanMacKenzie**](https://github.com/IanMacKenzie) (thank you, Ian!), here's what worked for me:
1. I downloaded and installed [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) (a full Visual Studio install should work tool; the Build Tools are just the CLI tools, which is all I wanted)
2. In the installation configuration, under "additional components" I had to check both "C++ ATL for latest v142 build tools (x86 & x64)" and also "C++/CLI support for v142 build tools"
3. I launched the "x64 Native Tools Command Prompt for Visual Studio 2019" application (note: not the similarly-named "x86" one!)
4. I followed most of the steps under LLVM's [building from source instructions](https://github.com/llvm/llvm-project#getting-the-source-code-and-building-llvm) up to the `cmake -G ...` command, which didn't work for me. Instead, at that point I did the following step.
5. I ran `cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ../llvm` to generate a NMake makefile.
6. Once that completed, I ran `nmake` to build LLVM. (This took about 2 hours on my laptop.)
7. Finally, I set an environment variable `LLVM_SYS_100_PREFIX` to point to the `build` directory where I ran the `cmake` command.
Once all that was done, `cargo` ran successfully for Roc!
## Use LLD for the linker

View File

@ -27,7 +27,7 @@ use inkwell::targets::{
use std::io::{self, ErrorKind};
use std::path::{Path, PathBuf};
use std::process;
use target_lexicon::{Architecture, OperatingSystem, Triple, Vendor};
use target_lexicon::{Architecture, Environment, OperatingSystem, Triple, Vendor};
use tokio::process::Command;
use tokio::runtime::Builder;
@ -565,6 +565,8 @@ fn gen(
// Best guide I've found on how to determine these magic strings:
//
// https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures
//
// Clang docs are particularly helpful: http://clang.llvm.org/docs/CrossCompilation.html
let target_triple_str = match target {
Triple {
architecture: Architecture::X86_64,
@ -590,6 +592,13 @@ fn gen(
operating_system: OperatingSystem::Darwin,
..
} => "x86_64-apple-darwin10",
Triple {
architecture: Architecture::X86_64,
vendor: Vendor::Pc,
operating_system: OperatingSystem::Windows,
environment: Environment::Msvc,
..
} => "x86_64-pc-win32-gnu",
_ => panic!("TODO gracefully handle unsupported target: {:?}", target),
};
let target_machine = Target::from_name(arch_str)
@ -608,5 +617,5 @@ fn gen(
.write_to_file(&env.module, FileType::Object, &dest_filename)
.expect("Writing .o file failed");
println!("\nSuccess! 🎉\n\n\t {}\n", dest_filename.display());
println!("\nSuccess!\n\n\t—> {}\n", dest_filename.display());
}

View File

@ -50,7 +50,7 @@ pub fn main() -> io::Result<()> {
loop {
if pending_src.is_empty() {
print!("\n\u{001b}[36m\u{001b}[0m ");
print!("\n\u{001b}[36m»\u{001b}[0m ");
} else {
print!("\u{001b}[36m…\u{001b}[0m ");
}
@ -430,19 +430,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str)?;
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -464,12 +464,12 @@ pub fn uniq_expr_with(
// TODO what to do with those rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -491,7 +491,7 @@ pub struct CanExprOut {
pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> Result<CanExprOut, Fail> {
let loc_expr = parse_loc_with(&arena, expr_str)?;
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -510,7 +510,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> Result<Can
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -538,7 +538,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> Result<Can
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// TODO determine what to do with those rigids
// for var in introduced_rigids {
@ -546,9 +546,10 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> Result<Can
// }
//load builtin types
let mut constraint = load_builtin_aliases(roc_builtins::std::aliases(), constraint, &var_store);
let mut constraint =
load_builtin_aliases(roc_builtins::std::aliases(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -65,7 +65,7 @@ pub fn canonicalize_annotation(
scope: &mut Scope,
annotation: &roc_parse::ast::TypeAnnotation,
region: Region,
var_store: &VarStore,
var_store: &mut VarStore,
) -> Annotation {
let mut introduced_variables = IntroducedVariables::default();
let mut aliases = SendMap::default();
@ -95,7 +95,7 @@ fn can_annotation_help(
annotation: &roc_parse::ast::TypeAnnotation,
region: Region,
scope: &mut Scope,
var_store: &VarStore,
var_store: &mut VarStore,
introduced_variables: &mut IntroducedVariables,
local_aliases: &mut SendMap<Symbol, Alias>,
references: &mut MutSet<Symbol>,
@ -407,7 +407,7 @@ fn can_assigned_field<'a>(
field: &AssignedField<'a, TypeAnnotation<'a>>,
region: Region,
scope: &mut Scope,
var_store: &VarStore,
var_store: &mut VarStore,
introduced_variables: &mut IntroducedVariables,
local_aliases: &mut SendMap<Symbol, Alias>,
field_types: &mut SendMap<Lowercase, Type>,
@ -472,7 +472,7 @@ fn can_tag<'a>(
tag: &Tag<'a>,
region: Region,
scope: &mut Scope,
var_store: &VarStore,
var_store: &mut VarStore,
introduced_variables: &mut IntroducedVariables,
local_aliases: &mut SendMap<Symbol, Alias>,
tag_types: &mut Vec<(TagName, Vec<Type>)>,

View File

@ -23,7 +23,7 @@ use roc_types::subs::{VarStore, Variable};
/// 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,
/// which works fine because it doesn't involve any open tag unions.
pub fn builtin_defs(var_store: &VarStore) -> MutMap<Symbol, Expr> {
pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Expr> {
mut_map! {
Symbol::LIST_GET => list_get(var_store),
Symbol::LIST_FIRST => list_first(var_store),
@ -43,342 +43,407 @@ pub fn builtin_defs(var_store: &VarStore) -> MutMap<Symbol, Expr> {
}
/// Float.tan : Float -> Float
fn float_tan(var_store: &VarStore) -> Expr {
fn float_tan(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::FLOAT_DIV,
vec![
call(
Symbol::FLOAT_SIN,
vec![Var(Symbol::FLOAT_TAN_ARG)],
var_store,
),
call(
Symbol::FLOAT_COS,
vec![Var(Symbol::FLOAT_TAN_ARG)],
var_store,
),
],
var_store,
);
defn(
Symbol::FLOAT_TAN,
vec![Symbol::FLOAT_TAN_ARG],
var_store,
call(
Symbol::FLOAT_DIV,
vec![
call(
Symbol::FLOAT_SIN,
vec![Var(Symbol::FLOAT_TAN_ARG)],
var_store,
),
call(
Symbol::FLOAT_COS,
vec![Var(Symbol::FLOAT_TAN_ARG)],
var_store,
),
],
var_store,
),
body,
)
}
/// Float.isZero : Float -> Bool
fn float_is_zero(var_store: &VarStore) -> Expr {
fn float_is_zero(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::FLOAT_EQ,
vec![
Float(var_store.fresh(), 0.0),
Var(Symbol::FLOAT_IS_ZERO_ARG),
],
var_store,
);
defn(
Symbol::FLOAT_IS_ZERO,
vec![Symbol::FLOAT_IS_ZERO_ARG],
var_store,
call(
Symbol::FLOAT_EQ,
vec![
Float(var_store.fresh(), 0.0),
Var(Symbol::FLOAT_IS_ZERO_ARG),
],
var_store,
),
body,
)
}
/// Float.isNegative : Float -> Bool
fn float_is_negative(var_store: &VarStore) -> Expr {
fn float_is_negative(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::FLOAT_GT,
vec![
Float(var_store.fresh(), 0.0),
Var(Symbol::FLOAT_IS_NEGATIVE_ARG),
],
var_store,
);
defn(
Symbol::FLOAT_IS_NEGATIVE,
vec![Symbol::FLOAT_IS_NEGATIVE_ARG],
var_store,
call(
Symbol::FLOAT_GT,
vec![
Float(var_store.fresh(), 0.0),
Var(Symbol::FLOAT_IS_NEGATIVE_ARG),
],
var_store,
),
body,
)
}
/// Float.isPositive : Float -> Bool
fn float_is_positive(var_store: &VarStore) -> Expr {
fn float_is_positive(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::FLOAT_GT,
vec![
Var(Symbol::FLOAT_IS_POSITIVE_ARG),
Float(var_store.fresh(), 0.0),
],
var_store,
);
defn(
Symbol::FLOAT_IS_POSITIVE,
vec![Symbol::FLOAT_IS_POSITIVE_ARG],
var_store,
call(
Symbol::FLOAT_GT,
vec![
Var(Symbol::FLOAT_IS_POSITIVE_ARG),
Float(var_store.fresh(), 0.0),
],
var_store,
),
body,
)
}
/// Int.isNegative : Int -> Bool
fn int_is_negative(var_store: &VarStore) -> Expr {
fn int_is_negative(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::NUM_LT,
vec![Var(Symbol::INT_IS_NEGATIVE_ARG), Int(var_store.fresh(), 0)],
var_store,
);
defn(
Symbol::INT_IS_NEGATIVE,
vec![Symbol::INT_IS_NEGATIVE_ARG],
var_store,
call(
Symbol::NUM_LT,
vec![Var(Symbol::INT_IS_NEGATIVE_ARG), Int(var_store.fresh(), 0)],
var_store,
),
body,
)
}
/// Int.isPositive : Int -> Bool
fn int_is_positive(var_store: &VarStore) -> Expr {
fn int_is_positive(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::NUM_GT,
vec![Var(Symbol::INT_IS_POSITIVE_ARG), Int(var_store.fresh(), 0)],
var_store,
);
defn(
Symbol::INT_IS_POSITIVE,
vec![Symbol::INT_IS_POSITIVE_ARG],
var_store,
call(
Symbol::NUM_GT,
vec![Var(Symbol::INT_IS_POSITIVE_ARG), Int(var_store.fresh(), 0)],
var_store,
),
body,
)
}
/// Int.isZero : Int -> Bool
fn int_is_zero(var_store: &VarStore) -> Expr {
fn int_is_zero(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::INT_EQ_I64,
vec![Var(Symbol::INT_IS_ZERO_ARG), Int(var_store.fresh(), 0)],
var_store,
);
defn(
Symbol::INT_IS_ZERO,
vec![Symbol::INT_IS_ZERO_ARG],
var_store,
call(
Symbol::INT_EQ_I64,
vec![Var(Symbol::INT_IS_ZERO_ARG), Int(var_store.fresh(), 0)],
var_store,
),
body,
)
}
/// Int.isOdd : Int -> Bool
fn int_is_odd(var_store: &VarStore) -> Expr {
fn int_is_odd(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::INT_EQ_I64,
vec![
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_IS_ODD_ARG), Int(var_store.fresh(), 2)],
var_store,
),
Int(var_store.fresh(), 1),
],
var_store,
);
defn(
Symbol::INT_IS_ODD,
vec![Symbol::INT_IS_ODD_ARG],
var_store,
call(
Symbol::INT_EQ_I64,
vec![
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_IS_ODD_ARG), Int(var_store.fresh(), 2)],
var_store,
),
Int(var_store.fresh(), 1),
],
var_store,
),
body,
)
}
/// Int.isEven : Int -> Bool
fn int_is_even(var_store: &VarStore) -> Expr {
fn int_is_even(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = call(
Symbol::INT_EQ_I64,
vec![
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_IS_EVEN_ARG), Int(var_store.fresh(), 2)],
var_store,
),
Int(var_store.fresh(), 0),
],
var_store,
);
defn(
Symbol::INT_IS_EVEN,
vec![Symbol::INT_IS_EVEN_ARG],
var_store,
call(
Symbol::INT_EQ_I64,
vec![
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_IS_EVEN_ARG), Int(var_store.fresh(), 2)],
var_store,
),
Int(var_store.fresh(), 0),
],
var_store,
),
body,
)
}
/// List.get : List elem, Int -> Result elem [ OutOfBounds ]*
fn list_get(var_store: &VarStore) -> Expr {
fn list_get(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
// Perform a bounds check. If it passes, delegate to List.#getUnsafe
let body = If {
cond_var: var_store.fresh(),
branch_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// index < List.len list
call(
Symbol::NUM_LT,
vec![
Var(Symbol::LIST_GET_ARG_INDEX),
call(
Symbol::LIST_LEN,
vec![Var(Symbol::LIST_GET_ARG_LIST)],
var_store,
),
],
var_store,
),
),
// then-branch
no_region(
// Ok
tag(
"Ok",
vec![
// List.getUnsafe list index
Call(
Box::new((
var_store.fresh(),
no_region(Var(Symbol::LIST_GET_UNSAFE)),
var_store.fresh(),
)),
vec![
(var_store.fresh(), no_region(Var(Symbol::LIST_GET_ARG_LIST))),
(
var_store.fresh(),
no_region(Var(Symbol::LIST_GET_ARG_INDEX)),
),
],
CalledVia::Space,
),
],
var_store,
),
),
)],
final_else: Box::new(
// else-branch
no_region(
// Err
tag(
"Err",
vec![tag("OutOfBounds", Vec::new(), var_store)],
var_store,
),
),
),
};
defn(
Symbol::LIST_GET,
vec![Symbol::LIST_GET_ARG_LIST, Symbol::LIST_GET_ARG_INDEX],
var_store,
// Perform a bounds check. If it passes, delegate to List.#getUnsafe
If {
cond_var: var_store.fresh(),
branch_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// index < List.len list
call(
Symbol::NUM_LT,
vec![
Var(Symbol::LIST_GET_ARG_INDEX),
call(
Symbol::LIST_LEN,
vec![Var(Symbol::LIST_GET_ARG_LIST)],
var_store,
),
],
var_store,
),
),
// then-branch
no_region(
// Ok
tag(
"Ok",
vec![
// List.getUnsafe list index
Call(
Box::new((
var_store.fresh(),
no_region(Var(Symbol::LIST_GET_UNSAFE)),
var_store.fresh(),
)),
vec![
(var_store.fresh(), no_region(Var(Symbol::LIST_GET_ARG_LIST))),
(
var_store.fresh(),
no_region(Var(Symbol::LIST_GET_ARG_INDEX)),
),
],
CalledVia::Space,
),
],
var_store,
),
),
)],
final_else: Box::new(
// else-branch
no_region(
// Err
tag(
"Err",
vec![tag("OutOfBounds", Vec::new(), var_store)],
var_store,
),
),
),
},
body,
)
}
/// Int.rem : Int, Int -> Int
fn int_rem(var_store: &VarStore) -> Expr {
fn int_rem(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if condition
no_region(
// Int.neq arg1 0
call(
Symbol::INT_NEQ_I64,
vec![Var(Symbol::INT_REM_ARG_1), (Int(var_store.fresh(), 0))],
var_store,
),
),
// arg1 was not zero
no_region(
// Ok (Int.#remUnsafe arg0 arg1)
tag(
"Ok",
vec![
// Int.#remUnsafe arg0 arg1
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_REM_ARG_0), Var(Symbol::INT_REM_ARG_1)],
var_store,
),
],
var_store,
),
),
)],
final_else: Box::new(no_region(tag(
"Err",
vec![tag("DivByZero", Vec::new(), var_store)],
var_store,
))),
};
defn(
Symbol::INT_REM,
vec![Symbol::INT_REM_ARG_0, Symbol::INT_REM_ARG_1],
var_store,
If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if condition
no_region(
// Int.neq arg1 0
call(
Symbol::INT_NEQ_I64,
vec![Var(Symbol::INT_REM_ARG_1), (Int(var_store.fresh(), 0))],
var_store,
),
),
// arg1 was not zero
no_region(
// Ok (Int.#remUnsafe arg0 arg1)
tag(
"Ok",
vec![
// Int.#remUnsafe arg0 arg1
call(
Symbol::INT_REM_UNSAFE,
vec![Var(Symbol::INT_REM_ARG_0), Var(Symbol::INT_REM_ARG_1)],
var_store,
),
],
var_store,
),
),
)],
final_else: Box::new(no_region(tag(
"Err",
vec![tag("DivByZero", Vec::new(), var_store)],
var_store,
))),
},
body,
)
}
/// Int.abs : Int -> Int
fn int_abs(var_store: &VarStore) -> Expr {
fn int_abs(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
defn(
Symbol::INT_ABS,
vec![Symbol::INT_ABS_ARG],
var_store,
If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// Int.isLt 0 n
// 0 < n
call(
Symbol::INT_LT,
vec![Int(var_store.fresh(), 0), Var(Symbol::INT_ABS_ARG)],
var_store,
),
),
// int is at least 0, so just pass it along
no_region(Var(Symbol::INT_ABS_ARG)),
)],
final_else: Box::new(
// int is below 0, so negate it.
no_region(call(
Symbol::NUM_NEG,
vec![Var(Symbol::INT_ABS_ARG)],
let body = If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// Int.isLt 0 n
// 0 < n
call(
Symbol::INT_LT,
vec![Int(var_store.fresh(), 0), Var(Symbol::INT_ABS_ARG)],
var_store,
)),
),
),
},
)
// int is at least 0, so just pass it along
no_region(Var(Symbol::INT_ABS_ARG)),
)],
final_else: Box::new(
// int is below 0, so negate it.
no_region(call(
Symbol::NUM_NEG,
vec![Var(Symbol::INT_ABS_ARG)],
var_store,
)),
),
};
defn(Symbol::INT_ABS, vec![Symbol::INT_ABS_ARG], var_store, body)
}
/// Int.div : Int, Int -> Result Int [ DivByZero ]*
fn int_div(var_store: &VarStore) -> Expr {
fn int_div(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
let body = If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// Int.neq denominator 0
call(
Symbol::INT_NEQ_I64,
vec![
Var(Symbol::INT_DIV_ARG_DENOMINATOR),
(Int(var_store.fresh(), 0)),
],
var_store,
),
),
// denominator was not zero
no_region(
// Ok (Int.#divUnsafe numerator denominator)
tag(
"Ok",
vec![
// Int.#divUnsafe numerator denominator
call(
Symbol::INT_DIV_UNSAFE,
vec![
Var(Symbol::INT_DIV_ARG_NUMERATOR),
Var(Symbol::INT_DIV_ARG_DENOMINATOR),
],
var_store,
),
],
var_store,
),
),
)],
final_else: Box::new(
// denominator was zero
no_region(tag(
"Err",
vec![tag("DivByZero", Vec::new(), var_store)],
var_store,
)),
),
};
defn(
Symbol::INT_DIV,
vec![
@ -386,107 +451,65 @@ fn int_div(var_store: &VarStore) -> Expr {
Symbol::INT_DIV_ARG_DENOMINATOR,
],
var_store,
If {
branch_var: var_store.fresh(),
cond_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// Int.neq denominator 0
call(
Symbol::INT_NEQ_I64,
vec![
Var(Symbol::INT_DIV_ARG_DENOMINATOR),
(Int(var_store.fresh(), 0)),
],
var_store,
),
),
// denominator was not zero
no_region(
// Ok (Int.#divUnsafe numerator denominator)
tag(
"Ok",
vec![
// Int.#divUnsafe numerator denominator
call(
Symbol::INT_DIV_UNSAFE,
vec![
Var(Symbol::INT_DIV_ARG_NUMERATOR),
Var(Symbol::INT_DIV_ARG_DENOMINATOR),
],
var_store,
),
],
var_store,
),
),
)],
final_else: Box::new(
// denominator was zero
no_region(tag(
"Err",
vec![tag("DivByZero", Vec::new(), var_store)],
var_store,
)),
),
},
body,
)
}
/// List.first : List elem -> Result elem [ ListWasEmpty ]*
fn list_first(var_store: &VarStore) -> Expr {
fn list_first(var_store: &mut VarStore) -> Expr {
use crate::expr::Expr::*;
// Perform a bounds check. If it passes, delegate to List.getUnsafe.
let body = If {
// TODO Use "when" instead of "if" so that we can have False be the first branch.
// We want that for branch prediction; usually we expect the list to be nonempty.
cond_var: var_store.fresh(),
branch_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// List.isEmpty list
call(
Symbol::LIST_IS_EMPTY,
vec![Var(Symbol::LIST_FIRST_ARG)],
var_store,
),
),
// list was empty
no_region(
// Err ListWasEmpty
tag(
"Err",
vec![tag("ListWasEmpty", Vec::new(), var_store)],
var_store,
),
),
)],
final_else: Box::new(
// list was not empty
no_region(
// Ok (List.#getUnsafe list 0)
tag(
"Ok",
vec![
// List.#getUnsafe list 0
call(
Symbol::LIST_GET_UNSAFE,
vec![(Var(Symbol::LIST_FIRST_ARG)), (Int(var_store.fresh(), 0))],
var_store,
),
],
var_store,
),
),
),
};
defn(
Symbol::LIST_FIRST,
vec![Symbol::LIST_FIRST_ARG],
var_store,
// Perform a bounds check. If it passes, delegate to List.getUnsafe.
If {
// TODO Use "when" instead of "if" so that we can have False be the first branch.
// We want that for branch prediction; usually we expect the list to be nonempty.
cond_var: var_store.fresh(),
branch_var: var_store.fresh(),
branches: vec![(
// if-condition
no_region(
// List.isEmpty list
call(
Symbol::LIST_IS_EMPTY,
vec![Var(Symbol::LIST_FIRST_ARG)],
var_store,
),
),
// list was empty
no_region(
// Err ListWasEmpty
tag(
"Err",
vec![tag("ListWasEmpty", Vec::new(), var_store)],
var_store,
),
),
)],
final_else: Box::new(
// list was not empty
no_region(
// Ok (List.#getUnsafe list 0)
tag(
"Ok",
vec![
// List.#getUnsafe list 0
call(
Symbol::LIST_GET_UNSAFE,
vec![(Var(Symbol::LIST_FIRST_ARG)), (Int(var_store.fresh(), 0))],
var_store,
),
],
var_store,
),
),
),
},
body,
)
}
@ -499,7 +522,7 @@ fn no_region<T>(value: T) -> Located<T> {
}
#[inline(always)]
fn tag(name: &'static str, args: Vec<Expr>, var_store: &VarStore) -> Expr {
fn tag(name: &'static str, args: Vec<Expr>, var_store: &mut VarStore) -> Expr {
Expr::Tag {
variant_var: var_store.fresh(),
ext_var: var_store.fresh(),
@ -512,7 +535,7 @@ fn tag(name: &'static str, args: Vec<Expr>, var_store: &VarStore) -> Expr {
}
#[inline(always)]
fn call(symbol: Symbol, args: Vec<Expr>, var_store: &VarStore) -> Expr {
fn call(symbol: Symbol, args: Vec<Expr>, var_store: &mut VarStore) -> Expr {
Expr::Call(
Box::new((
var_store.fresh(),
@ -527,7 +550,7 @@ fn call(symbol: Symbol, args: Vec<Expr>, var_store: &VarStore) -> Expr {
}
#[inline(always)]
fn defn(fn_name: Symbol, args: Vec<Symbol>, var_store: &VarStore, body: Expr) -> Expr {
fn defn(fn_name: Symbol, args: Vec<Symbol>, var_store: &mut VarStore, body: Expr) -> Expr {
use crate::expr::Expr::*;
use crate::pattern::Pattern::*;

View File

@ -17,14 +17,14 @@ pub enum Constraint {
}
impl Constraint {
pub fn instantiate_aliases(&mut self, var_store: &VarStore) {
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: &VarStore,
var_store: &mut VarStore,
introduced: &mut ImSet<Variable>,
) {
use Constraint::*;

View File

@ -108,7 +108,7 @@ impl Declaration {
pub fn canonicalize_defs<'a>(
env: &mut Env<'a>,
mut output: Output,
var_store: &VarStore,
var_store: &mut VarStore,
original_scope: &Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>,
pattern_type: PatternType,
@ -251,7 +251,7 @@ pub fn canonicalize_defs<'a>(
}
}
correct_mutual_recursive_type_alias(env, &mut aliases, &var_store);
correct_mutual_recursive_type_alias(env, &mut aliases, var_store);
// Now that we have the scope completely assembled, and shadowing resolved,
// we're ready to canonicalize any body exprs.
@ -723,7 +723,7 @@ fn canonicalize_pending_def<'a>(
mut output: Output,
scope: &mut Scope,
can_defs_by_symbol: &mut MutMap<Symbol, Def>,
var_store: &VarStore,
var_store: &mut VarStore,
refs_by_symbol: &mut MutMap<Symbol, (Located<Ident>, References)>,
aliases: &mut SendMap<Symbol, Alias>,
) -> Output {
@ -1182,7 +1182,7 @@ fn canonicalize_pending_def<'a>(
#[inline(always)]
pub fn can_defs_with_return<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>,
loc_ret: &'a Located<ast::Expr<'a>>,
@ -1234,7 +1234,7 @@ pub fn can_defs_with_return<'a>(
}
fn decl_to_let(
var_store: &VarStore,
var_store: &mut VarStore,
decl: Declaration,
loc_ret: Located<Expr>,
aliases: SendMap<Symbol, Alias>,
@ -1288,7 +1288,7 @@ fn closure_recursivity(symbol: Symbol, closures: &MutMap<Symbol, References>) ->
fn to_pending_def<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
def: &'a ast::Def<'a>,
scope: &mut Scope,
pattern_type: PatternType,
@ -1393,7 +1393,7 @@ fn pending_typed_body<'a>(
loc_pattern: &'a Located<ast::Pattern<'a>>,
loc_ann: &'a Located<ast::TypeAnnotation<'a>>,
loc_expr: &'a Located<ast::Expr<'a>>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
pattern_type: PatternType,
) -> PendingDef<'a> {
@ -1414,7 +1414,7 @@ fn pending_typed_body<'a>(
fn correct_mutual_recursive_type_alias<'a>(
env: &mut Env<'a>,
aliases: &mut SendMap<Symbol, Alias>,
var_store: &VarStore,
var_store: &mut VarStore,
) {
let mut symbols_introduced = ImSet::default();
@ -1510,7 +1510,7 @@ fn make_tag_union_recursive<'a>(
region: Region,
others: Vec<Symbol>,
typ: &mut Type,
var_store: &VarStore,
var_store: &mut VarStore,
can_report_error: &mut bool,
) {
match typ {

View File

@ -168,7 +168,7 @@ pub struct WhenBranch {
pub fn canonicalize_expr<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
region: Region,
expr: &'a ast::Expr<'a>,
@ -690,7 +690,7 @@ pub fn canonicalize_expr<'a>(
#[inline(always)]
fn canonicalize_when_branch<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
_region: Region,
branch: &'a ast::WhenBranch<'a>,
@ -885,7 +885,7 @@ where
fn canonicalize_fields<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
region: Region,
fields: &'a [Located<ast::AssignedField<'a, ast::Expr<'a>>>],
@ -922,7 +922,7 @@ fn canonicalize_fields<'a>(
fn canonicalize_field<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
field: &'a ast::AssignedField<'a, ast::Expr<'a>>,
region: Region,

View File

@ -49,7 +49,7 @@ pub fn canonicalize_module_defs<'a>(
dep_idents: MutMap<ModuleId, IdentIds>,
exposed_imports: MutMap<Ident, (Symbol, Region)>,
mut exposed_symbols: MutSet<Symbol>,
var_store: &VarStore,
var_store: &mut VarStore,
) -> Result<ModuleOutput, RuntimeError> {
let mut can_exposed_imports = MutMap::default();
let mut scope = Scope::new(home);

View File

@ -8,7 +8,7 @@ use std::i64;
#[inline(always)]
pub fn num_expr_from_result(
var_store: &VarStore,
var_store: &mut VarStore,
result: Result<i64, &str>,
env: &mut Env,
) -> Expr {
@ -29,7 +29,7 @@ pub fn num_expr_from_result(
#[inline(always)]
pub fn int_expr_from_result(
var_store: &VarStore,
var_store: &mut VarStore,
result: Result<i64, &str>,
env: &mut Env,
) -> Expr {
@ -48,7 +48,7 @@ pub fn int_expr_from_result(
#[inline(always)]
pub fn float_expr_from_result(
var_store: &VarStore,
var_store: &mut VarStore,
result: Result<f64, &str>,
env: &mut Env,
) -> Expr {

View File

@ -84,7 +84,7 @@ pub fn symbols_from_pattern_help(pattern: &Pattern, symbols: &mut Vec<Symbol>) {
pub fn canonicalize_pattern<'a>(
env: &mut Env<'a>,
var_store: &VarStore,
var_store: &mut VarStore,
scope: &mut Scope,
pattern_type: PatternType,
pattern: &ast::Pattern<'a>,

View File

@ -60,7 +60,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let module_ids = ModuleIds::default();
@ -78,7 +78,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,

View File

@ -28,7 +28,7 @@ pub fn constrain_module(
module: &ModuleOutput,
home: ModuleId,
mode: Mode,
var_store: &VarStore,
var_store: &mut VarStore,
) -> Constraint {
use Mode::*;
@ -42,7 +42,7 @@ pub fn constrain_module(
match mode {
Standard => constrain_decls(home, decls, send_aliases),
Uniqueness => crate::uniq::constrain_decls(home, decls, send_aliases, &var_store),
Uniqueness => crate::uniq::constrain_decls(home, decls, send_aliases, var_store),
}
}
@ -55,7 +55,7 @@ pub struct Import {
pub fn constrain_imported_values(
imports: Vec<Import>,
body_con: Constraint,
var_store: &VarStore,
var_store: &mut VarStore,
) -> (Vec<Variable>, Constraint) {
use Constraint::*;
let mut def_types = SendMap::default();
@ -111,7 +111,11 @@ pub fn constrain_imported_values(
)
}
pub fn load_builtin_aliases<I>(aliases: I, body_con: Constraint, var_store: &VarStore) -> Constraint
pub fn load_builtin_aliases<I>(
aliases: I,
body_con: Constraint,
var_store: &mut VarStore,
) -> Constraint
where
I: IntoIterator<Item = (Symbol, BuiltinAlias)>,
{
@ -169,7 +173,7 @@ pub struct FreeVars {
pub wildcards: Vec<Variable>,
}
fn to_type(solved_type: &SolvedType, free_vars: &mut FreeVars, var_store: &VarStore) -> Type {
fn to_type(solved_type: &SolvedType, free_vars: &mut FreeVars, var_store: &mut VarStore) -> Type {
use roc_types::solved_types::SolvedType::*;
match solved_type {
@ -293,7 +297,11 @@ fn to_type(solved_type: &SolvedType, free_vars: &mut FreeVars, var_store: &VarSt
}
}
pub fn to_atom(solved_atom: &SolvedAtom, free_vars: &mut FreeVars, var_store: &VarStore) -> Atom {
pub fn to_atom(
solved_atom: &SolvedAtom,
free_vars: &mut FreeVars,
var_store: &mut VarStore,
) -> Atom {
match solved_atom {
SolvedAtom::Zero => Atom::Zero,
SolvedAtom::One => Atom::One,
@ -313,7 +321,7 @@ pub fn to_atom(solved_atom: &SolvedAtom, free_vars: &mut FreeVars, var_store: &V
pub fn constrain_imported_aliases(
aliases: MutMap<Symbol, Alias>,
body_con: Constraint,
var_store: &VarStore,
var_store: &mut VarStore,
) -> Constraint {
use Constraint::*;
let mut def_aliases = SendMap::default();

View File

@ -28,7 +28,7 @@ pub struct Env {
pub fn constrain_declaration(
home: ModuleId,
var_store: &VarStore,
var_store: &mut VarStore,
region: Region,
loc_expr: &Located<Expr>,
_declared_idents: &ImMap<Ident, (Symbol, Region)>,
@ -61,7 +61,7 @@ pub fn constrain_decls(
home: ModuleId,
decls: &[Declaration],
mut aliases: SendMap<Symbol, Alias>,
var_store: &VarStore,
var_store: &mut VarStore,
) -> Constraint {
let mut constraint = Constraint::SaveTheEnvironment;
@ -96,7 +96,7 @@ pub fn constrain_decls(
home,
rigids: ImMap::default(),
},
&var_store,
var_store,
&var_usage,
&mut ImSet::default(),
def,
@ -113,7 +113,7 @@ pub fn constrain_decls(
home,
rigids: ImMap::default(),
},
&var_store,
var_store,
&var_usage,
&mut ImSet::default(),
defs,
@ -135,7 +135,7 @@ pub struct PatternState {
}
fn constrain_pattern(
var_store: &VarStore,
var_store: &mut VarStore,
state: &mut PatternState,
pattern: &Located<Pattern>,
expected: PExpected<Type>,
@ -347,7 +347,7 @@ fn constrain_pattern(
fn unique_unbound_num(
inner_var: Variable,
var_store: &VarStore,
var_store: &mut VarStore,
) -> (Variable, Variable, Type, Variable) {
let num_var = var_store.fresh();
let num_uvar = var_store.fresh();
@ -362,7 +362,7 @@ fn unique_unbound_num(
(num_uvar, val_uvar, num_type, num_var)
}
fn unique_num(var_store: &VarStore, symbol: Symbol) -> (Variable, Variable, Type) {
fn unique_num(var_store: &mut VarStore, symbol: Symbol) -> (Variable, Variable, Type) {
let num_uvar = var_store.fresh();
let val_uvar = var_store.fresh();
@ -375,17 +375,17 @@ fn unique_num(var_store: &VarStore, symbol: Symbol) -> (Variable, Variable, Type
(num_uvar, val_uvar, num_type)
}
fn unique_int(var_store: &VarStore) -> (Variable, Variable, Type) {
fn unique_int(var_store: &mut VarStore) -> (Variable, Variable, Type) {
unique_num(var_store, Symbol::INT_INTEGER)
}
fn unique_float(var_store: &VarStore) -> (Variable, Variable, Type) {
fn unique_float(var_store: &mut VarStore) -> (Variable, Variable, Type) {
unique_num(var_store, Symbol::FLOAT_FLOATINGPOINT)
}
pub fn constrain_expr(
env: &Env,
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
region: Region,
@ -1350,7 +1350,7 @@ pub fn constrain_expr(
}
fn constrain_var(
var_store: &VarStore,
var_store: &mut VarStore,
applied_usage_constraint: &mut ImSet<Symbol>,
symbol_for_lookup: Symbol,
usage: Option<&Usage>,
@ -1415,7 +1415,7 @@ fn constrain_var(
fn constrain_by_usage(
usage: &Usage,
var_store: &VarStore,
var_store: &mut VarStore,
introduced: &mut Vec<Variable>,
) -> (Atom, Vec<Atom>, Type) {
use Mark::*;
@ -1478,7 +1478,7 @@ fn constrain_by_usage_list(
fields: &FieldAccess,
list_uniq_var: Atom,
introduced: &mut Vec<Variable>,
var_store: &VarStore,
var_store: &mut VarStore,
) -> (Atom, Vec<Atom>, Type) {
let field_usage = fields
.get(&sharing::LIST_ELEM.into())
@ -1502,7 +1502,7 @@ fn constrain_by_usage_record(
record_uniq_var: Atom,
ext_type: Type,
introduced: &mut Vec<Variable>,
var_store: &VarStore,
var_store: &mut VarStore,
) -> (Atom, Vec<Atom>, Type) {
let mut field_types = SendMap::default();
@ -1547,7 +1547,7 @@ fn constrain_by_usage_record(
// NOTE enabling the inline pragma can blow the stack in debug mode
// #[inline(always)]
fn constrain_when_branch(
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
env: &Env,
@ -1628,7 +1628,7 @@ fn constrain_when_branch(
}
fn constrain_def_pattern(
var_store: &VarStore,
var_store: &mut VarStore,
loc_pattern: &Located<Pattern>,
expr_type: Type,
) -> PatternState {
@ -1649,7 +1649,7 @@ fn constrain_def_pattern(
/// Turn e.g. `Int` into `Attr.Attr * Int`
fn annotation_to_attr_type(
var_store: &VarStore,
var_store: &mut VarStore,
ann: &Type,
rigids: &mut ImMap<Variable, Variable>,
change_var_kind: bool,
@ -1838,7 +1838,7 @@ fn annotation_to_attr_type(
}
fn annotation_to_attr_type_many(
var_store: &VarStore,
var_store: &mut VarStore,
anns: &[Type],
rigids: &mut ImMap<Variable, Variable>,
change_var_kind: bool,
@ -1854,7 +1854,7 @@ fn annotation_to_attr_type_many(
})
}
fn aliases_to_attr_type(var_store: &VarStore, aliases: &mut SendMap<Symbol, Alias>) {
fn aliases_to_attr_type(var_store: &mut VarStore, aliases: &mut SendMap<Symbol, Alias>) {
for alias in aliases.iter_mut() {
// ensure
//
@ -1880,7 +1880,7 @@ fn aliases_to_attr_type(var_store: &VarStore, aliases: &mut SendMap<Symbol, Alia
fn constrain_def(
env: &Env,
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
def: &Def,
@ -1973,7 +1973,7 @@ fn constrain_def(
}
fn instantiate_rigids(
var_store: &VarStore,
var_store: &mut VarStore,
annotation: &Type,
introduced_vars: &IntroducedVariables,
new_rigids: &mut Vec<Variable>,
@ -2041,7 +2041,7 @@ fn instantiate_rigids(
fn constrain_recursive_defs(
env: &Env,
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
defs: &[Def],
@ -2062,7 +2062,7 @@ fn constrain_recursive_defs(
#[allow(clippy::too_many_arguments)]
pub fn rec_defs_help(
env: &Env,
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
defs: &[Def],
@ -2222,7 +2222,7 @@ pub fn rec_defs_help(
#[inline(always)]
fn constrain_field_update(
env: &Env,
var_store: &VarStore,
var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
var: Variable,

View File

@ -149,19 +149,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str);
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -183,12 +183,12 @@ pub fn uniq_expr_with(
// TODO what to do with those rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -216,7 +216,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -235,7 +235,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -245,7 +245,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
// Add builtin defs (e.g. List.get) directly to the canonical Expr,
// 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(&mut var_store);
for (symbol, expr) in builtin_defs {
if output.references.lookups.contains(&symbol) || output.references.calls.contains(&symbol)
@ -301,7 +301,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
// load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// TODO determine what to do with those rigids
// for var in introduced_rigids {
@ -309,9 +309,10 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
// }
//load builtin types
let mut constraint = load_builtin_aliases(roc_builtins::std::aliases(), constraint, &var_store);
let mut constraint =
load_builtin_aliases(roc_builtins::std::aliases(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -800,7 +800,7 @@ fn spawn_solve_module(
module: Module,
src: Box<str>,
constraint: Constraint,
var_store: VarStore,
mut var_store: VarStore,
imported_modules: MutSet<ModuleId>,
msg_tx: MsgSender,
exposed_types: &mut SubsByModule,
@ -922,12 +922,12 @@ fn spawn_solve_module(
// in the ones we just computed. We can do this off the main thread.
// TODO what to do with the introduced rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imported_symbols, constraint, &var_store);
let constraint = constrain_imported_aliases(imported_aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(aliases, constraint, &var_store);
constrain_imported_values(imported_symbols, constraint, &mut var_store);
let constraint = constrain_imported_aliases(imported_aliases, constraint, &mut var_store);
let mut constraint = load_builtin_aliases(aliases, constraint, &mut var_store);
// Turn Apply into Alias
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let (solved_subs, solved_module) =
roc_solve::module::solve_module(module, constraint, var_store);
@ -1029,7 +1029,7 @@ fn parse_and_constrain(
msg_tx: MsgSender,
) {
let module_id = header.module_id;
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let arena = Bump::new();
let state = State::new(&header.src, Attempting::Module);
@ -1046,10 +1046,10 @@ fn parse_and_constrain(
dep_idents,
header.exposed_imports,
exposed_symbols,
&var_store,
&mut var_store,
) {
Ok(module_output) => {
let constraint = constrain_module(&module_output, module_id, mode, &var_store);
let constraint = constrain_module(&module_output, module_id, mode, &mut var_store);
let module = Module {
module_id,
exposed_imports: module_output.exposed_imports,

View File

@ -144,19 +144,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str);
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -176,12 +176,12 @@ pub fn uniq_expr_with(
// load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -210,7 +210,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -229,7 +229,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -257,7 +257,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// TODO include only the aliases actually used in this module
let aliases = roc_builtins::std::aliases()
@ -266,9 +266,9 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
.collect::<Vec<(Symbol, BuiltinAlias)>>();
//load builtin types
let mut constraint = load_builtin_aliases(aliases.into_iter(), constraint, &var_store);
let mut constraint = load_builtin_aliases(aliases.into_iter(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -124,19 +124,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str);
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -158,12 +158,12 @@ pub fn uniq_expr_with(
// TODO what to do with those rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -192,7 +192,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -211,7 +211,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -239,12 +239,13 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
//load builtin types
let mut constraint = load_builtin_aliases(roc_builtins::std::aliases(), constraint, &var_store);
let mut constraint =
load_builtin_aliases(roc_builtins::std::aliases(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -235,6 +235,10 @@ fn spaces<'a>(
// indentation yet, but maybe it will be after more spaces happen!
state = state.advance_spaces(1)?;
}
'\r' => {
// Ignore carriage returns.
state = state.advance_spaces(1)?;
}
'\n' => {
// No need to check indentation because we're about to reset it anyway.
state = state.newline()?;

View File

@ -145,7 +145,7 @@ pub fn can_expr_with(
}
};
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -164,7 +164,7 @@ pub fn can_expr_with(
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
loc_expr.region,
&loc_expr.value,
@ -192,12 +192,13 @@ pub fn can_expr_with(
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
//load builtin types
let mut constraint = load_builtin_aliases(roc_builtins::std::aliases(), constraint, &var_store);
let mut constraint =
load_builtin_aliases(roc_builtins::std::aliases(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -145,19 +145,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str);
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -179,12 +179,12 @@ pub fn uniq_expr_with(
// TODO what to do with those rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -213,7 +213,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -232,7 +232,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -260,16 +260,16 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
//load builtin types
let mut constraint = load_builtin_aliases(
roc_builtins::std::aliases().into_iter(),
constraint,
&var_store,
&mut var_store,
);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -5,7 +5,6 @@ use roc_module::ident::{Lowercase, TagName};
use roc_module::symbol::Symbol;
use std::fmt;
use std::iter::{once, Iterator};
use std::sync::atomic::{AtomicU32, Ordering};
use ven_ena::unify::{InPlace, Snapshot, UnificationTable, UnifyKey};
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
@ -56,7 +55,7 @@ impl fmt::Debug for Subs {
#[derive(Debug)]
pub struct VarStore {
next: AtomicU32,
next: u32,
}
impl Default for VarStore {
@ -70,24 +69,22 @@ impl VarStore {
pub fn new(next_var: Variable) -> Self {
debug_assert!(next_var.0 >= Variable::FIRST_USER_SPACE_VAR.0);
VarStore {
next: AtomicU32::new(next_var.0),
}
VarStore { next: next_var.0 }
}
pub fn fresh(&self) -> Variable {
// Increment the counter and return the previous value.
//
// Since the counter starts at 0, this will return 0 on first invocation,
// and var_store.into() will return the number of Variables distributed
// (in this case, 1).
Variable(AtomicU32::fetch_add(&self.next, 1, Ordering::Relaxed))
pub fn fresh(&mut self) -> Variable {
// Increment the counter and return the value it had before it was incremented.
let answer = self.next;
self.next += 1;
Variable(answer)
}
}
impl Into<Variable> for VarStore {
fn into(self) -> Variable {
Variable(self.next.into_inner())
Variable(self.next)
}
}

View File

@ -397,7 +397,7 @@ impl Type {
&mut self,
region: Region,
aliases: &ImMap<Symbol, Alias>,
var_store: &VarStore,
var_store: &mut VarStore,
introduced: &mut ImSet<Variable>,
) {
use Type::*;

View File

@ -145,19 +145,19 @@ pub fn uniq_expr_with(
loc_expr,
output,
problems,
var_store: old_var_store,
var_store: mut old_var_store,
var,
interns,
..
} = can_expr_with(arena, home, expr_str);
// double check
let var_store = VarStore::new(old_var_store.fresh());
let mut var_store = VarStore::new(old_var_store.fresh());
let expected2 = Expected::NoExpectation(Type::Variable(var));
let constraint = roc_constrain::uniq::constrain_declaration(
home,
&var_store,
&mut var_store,
Region::zero(),
&loc_expr,
declared_idents,
@ -179,12 +179,12 @@ pub fn uniq_expr_with(
// TODO what to do with those rigids?
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
// load builtin types
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &var_store);
let mut constraint = load_builtin_aliases(stdlib.aliases, constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let subs2 = Subs::new(var_store.into());
@ -213,7 +213,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
)
});
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let var = var_store.fresh();
let expected = Expected::NoExpectation(Type::Variable(var));
let module_ids = ModuleIds::default();
@ -232,7 +232,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
let mut env = Env::new(home, dep_idents, &module_ids, IdentIds::default());
let (loc_expr, output) = canonicalize_expr(
&mut env,
&var_store,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
@ -260,12 +260,13 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
//load builtin values
let (_introduced_rigids, constraint) =
constrain_imported_values(imports, constraint, &var_store);
constrain_imported_values(imports, constraint, &mut var_store);
//load builtin types
let mut constraint = load_builtin_aliases(roc_builtins::std::aliases(), constraint, &var_store);
let mut constraint =
load_builtin_aliases(roc_builtins::std::aliases(), constraint, &mut var_store);
constraint.instantiate_aliases(&var_store);
constraint.instantiate_aliases(&mut var_store);
let mut all_ident_ids = MutMap::default();

View File

@ -548,7 +548,7 @@ impl Module {
fn single_backspace_1_caret() {
use roc_types::subs::VarStore;
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let int_var = var_store.fresh();
let int_node_id;
let caret_node_id;
@ -628,7 +628,7 @@ fn single_backspace_1_caret() {
fn double_backspace_1_caret() {
use roc_types::subs::VarStore;
let var_store = VarStore::default();
let mut var_store = VarStore::default();
let int_var = var_store.fresh();
let int_node_id;
let caret_node_id;