mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 05:34:11 +03:00
Merge branch 'trunk' of github.com:rtfeldman/roc into list-repeat
This commit is contained in:
commit
7bf8be5e9a
@ -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
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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>)>,
|
||||
|
@ -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::*;
|
||||
|
||||
|
@ -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::*;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()?;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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::*;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user