mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
make after work
This commit is contained in:
parent
f3ed367d97
commit
7e6724262d
7 changed files with 449 additions and 135 deletions
|
@ -162,15 +162,20 @@ mod cli_run {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[serial(effect)]
|
||||||
|
fn run_effect_unoptimized() {
|
||||||
|
check_output(
|
||||||
|
&example_file("effect", "Main.roc"),
|
||||||
|
&[],
|
||||||
|
"I am Dep2.str2\n",
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial(multi_dep_str)]
|
#[serial(multi_dep_str)]
|
||||||
fn run_multi_dep_str_unoptimized() {
|
fn run_multi_dep_str_unoptimized() {
|
||||||
// if true {
|
|
||||||
// todo!(
|
|
||||||
// "fix this test so it no longer deadlocks and hangs during monomorphization! The test never shows the error; to see the panic error, run this: cargo run run cli/tests/fixtures/multi-dep-str/Main.roc"
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
check_output(
|
check_output(
|
||||||
&fixture_file("multi-dep-str", "Main.roc"),
|
&fixture_file("multi-dep-str", "Main.roc"),
|
||||||
&[],
|
&[],
|
||||||
|
|
|
@ -1134,9 +1134,10 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
env.arena.alloc(format!("closure_field_access_{}_", index)),
|
env.arena.alloc(format!("closure_field_access_{}_", index)),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
(other, layout) => {
|
(other, layout) => unreachable!(
|
||||||
unreachable!("can only index into struct layout {:?} {:?}", other, layout)
|
"can only index into struct layout\nValue: {:?}\nLayout: {:?}\nIndex: {:?}",
|
||||||
}
|
other, layout, index
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||||
|
|
||||||
let deps_by_name = &parsed.deps_by_name;
|
let deps_by_name = &parsed.deps_by_name;
|
||||||
let num_deps = deps_by_name.len();
|
let num_deps = deps_by_name.len();
|
||||||
let mut dep_idents: IdentIdsByModule = IdentIds::exposed_builtins(num_deps);
|
let mut dep_idents: MutMap<ModuleId, IdentIds> = IdentIds::exposed_builtins(num_deps);
|
||||||
|
|
||||||
let State {
|
let State {
|
||||||
ident_ids_by_module,
|
ident_ids_by_module,
|
||||||
|
@ -596,7 +596,7 @@ struct State<'a> {
|
||||||
/// From now on, these will be used by multiple threads; time to make an Arc<Mutex<_>>!
|
/// From now on, these will be used by multiple threads; time to make an Arc<Mutex<_>>!
|
||||||
pub arc_modules: Arc<Mutex<ModuleIds>>,
|
pub arc_modules: Arc<Mutex<ModuleIds>>,
|
||||||
|
|
||||||
pub ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
pub ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
|
|
||||||
/// All the dependent modules we've already begun loading -
|
/// All the dependent modules we've already begun loading -
|
||||||
/// meaning we should never kick off another load_module on them!
|
/// meaning we should never kick off another load_module on them!
|
||||||
|
@ -714,7 +714,7 @@ enum BuildTask<'a> {
|
||||||
LoadModule {
|
LoadModule {
|
||||||
module_name: ModuleName,
|
module_name: ModuleName,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
},
|
},
|
||||||
Parse {
|
Parse {
|
||||||
header: ModuleHeader<'a>,
|
header: ModuleHeader<'a>,
|
||||||
|
@ -722,7 +722,7 @@ enum BuildTask<'a> {
|
||||||
CanonicalizeAndConstrain {
|
CanonicalizeAndConstrain {
|
||||||
parsed: ParsedModule<'a>,
|
parsed: ParsedModule<'a>,
|
||||||
module_ids: ModuleIds,
|
module_ids: ModuleIds,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: MutMap<ModuleId, IdentIds>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
exposed_symbols: MutSet<Symbol>,
|
exposed_symbols: MutSet<Symbol>,
|
||||||
aliases: MutMap<Symbol, Alias>,
|
aliases: MutMap<Symbol, Alias>,
|
||||||
|
@ -782,7 +782,6 @@ pub enum Phases {
|
||||||
Monomorphize,
|
Monomorphize,
|
||||||
}
|
}
|
||||||
|
|
||||||
type IdentIdsByModule = MutMap<ModuleId, IdentIds>;
|
|
||||||
type MsgSender<'a> = Sender<Msg<'a>>;
|
type MsgSender<'a> = Sender<Msg<'a>>;
|
||||||
|
|
||||||
/// Add a task to the queue, and notify all the listeners.
|
/// Add a task to the queue, and notify all the listeners.
|
||||||
|
@ -877,7 +876,7 @@ pub fn load_and_monomorphize_from_str<'a>(
|
||||||
|
|
||||||
struct LoadStart<'a> {
|
struct LoadStart<'a> {
|
||||||
pub arc_modules: Arc<Mutex<ModuleIds>>,
|
pub arc_modules: Arc<Mutex<ModuleIds>>,
|
||||||
pub ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
pub ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
pub root_id: ModuleId,
|
pub root_id: ModuleId,
|
||||||
pub root_msg: Msg<'a>,
|
pub root_msg: Msg<'a>,
|
||||||
}
|
}
|
||||||
|
@ -1701,7 +1700,7 @@ fn load_module<'a>(
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
module_name: ModuleName,
|
module_name: ModuleName,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
||||||
let module_start_time = SystemTime::now();
|
let module_start_time = SystemTime::now();
|
||||||
let mut filename = PathBuf::new();
|
let mut filename = PathBuf::new();
|
||||||
|
@ -1756,7 +1755,7 @@ fn parse_header<'a>(
|
||||||
read_file_duration: Duration,
|
read_file_duration: Duration,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
src_bytes: &'a [u8],
|
src_bytes: &'a [u8],
|
||||||
start_time: SystemTime,
|
start_time: SystemTime,
|
||||||
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
||||||
|
@ -1814,7 +1813,7 @@ fn load_filename<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
module_start_time: SystemTime,
|
module_start_time: SystemTime,
|
||||||
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
||||||
let file_io_start = SystemTime::now();
|
let file_io_start = SystemTime::now();
|
||||||
|
@ -1845,7 +1844,7 @@ fn load_from_str<'a>(
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
src: &'a str,
|
src: &'a str,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
module_start_time: SystemTime,
|
module_start_time: SystemTime,
|
||||||
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
|
||||||
let file_io_start = SystemTime::now();
|
let file_io_start = SystemTime::now();
|
||||||
|
@ -1870,7 +1869,7 @@ fn send_header<'a>(
|
||||||
imports: &'a [Located<ImportsEntry<'a>>],
|
imports: &'a [Located<ImportsEntry<'a>>],
|
||||||
parse_state: parser::State<'a>,
|
parse_state: parser::State<'a>,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
) -> (ModuleId, Msg<'a>) {
|
) -> (ModuleId, Msg<'a>) {
|
||||||
let declared_name: ModuleName = name.value.as_str().into();
|
let declared_name: ModuleName = name.value.as_str().into();
|
||||||
|
@ -2109,9 +2108,185 @@ fn run_solve<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fabricate_host_exposed_def<'a>(
|
fn fabricate_effect_after<'a>(
|
||||||
|
env: &mut roc_can::env::Env,
|
||||||
|
scope: &mut roc_can::scope::Scope,
|
||||||
|
module_id: ModuleId,
|
||||||
|
effect_symbol: Symbol,
|
||||||
|
effect_tag_name: TagName,
|
||||||
|
var_store: &mut VarStore,
|
||||||
|
) -> (Symbol, roc_can::def::Def) {
|
||||||
|
use roc_can::expr::Expr;
|
||||||
|
use roc_can::expr::Recursive;
|
||||||
|
use roc_module::operator::CalledVia;
|
||||||
|
|
||||||
|
let thunk_symbol = {
|
||||||
|
scope
|
||||||
|
.introduce(
|
||||||
|
"thunk".into(),
|
||||||
|
&env.exposed_ident_ids,
|
||||||
|
&mut env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let to_effect_symbol = {
|
||||||
|
scope
|
||||||
|
.introduce(
|
||||||
|
"toEffect".into(),
|
||||||
|
&env.exposed_ident_ids,
|
||||||
|
&mut env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let after_symbol = {
|
||||||
|
scope
|
||||||
|
.introduce(
|
||||||
|
"after".into(),
|
||||||
|
&env.exposed_ident_ids,
|
||||||
|
&mut env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
// `thunk {}`
|
||||||
|
let force_thunk_call = {
|
||||||
|
let boxed = (
|
||||||
|
var_store.fresh(),
|
||||||
|
Located::at_zero(Expr::Var(thunk_symbol)),
|
||||||
|
var_store.fresh(),
|
||||||
|
var_store.fresh(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let arguments = vec![(var_store.fresh(), Located::at_zero(Expr::EmptyRecord))];
|
||||||
|
Expr::Call(Box::new(boxed), arguments, CalledVia::Space)
|
||||||
|
};
|
||||||
|
|
||||||
|
// `toEffect (thunk {})`
|
||||||
|
let to_effect_call = {
|
||||||
|
let boxed = (
|
||||||
|
var_store.fresh(),
|
||||||
|
Located::at_zero(Expr::Var(to_effect_symbol)),
|
||||||
|
var_store.fresh(),
|
||||||
|
var_store.fresh(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let arguments = vec![(var_store.fresh(), Located::at_zero(force_thunk_call))];
|
||||||
|
Expr::Call(Box::new(boxed), arguments, CalledVia::Space)
|
||||||
|
};
|
||||||
|
|
||||||
|
use roc_can::pattern::Pattern;
|
||||||
|
let arguments = vec![
|
||||||
|
(
|
||||||
|
var_store.fresh(),
|
||||||
|
Located::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: var_store.fresh(),
|
||||||
|
ext_var: var_store.fresh(),
|
||||||
|
tag_name: effect_tag_name.clone(),
|
||||||
|
arguments: vec![(
|
||||||
|
var_store.fresh(),
|
||||||
|
Located::at_zero(Pattern::Identifier(thunk_symbol)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
var_store.fresh(),
|
||||||
|
Located::at_zero(Pattern::Identifier(to_effect_symbol)),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
let function_var = var_store.fresh();
|
||||||
|
let after_closure = Expr::Closure {
|
||||||
|
function_type: function_var,
|
||||||
|
closure_type: var_store.fresh(),
|
||||||
|
closure_ext_var: var_store.fresh(),
|
||||||
|
return_type: var_store.fresh(),
|
||||||
|
name: after_symbol,
|
||||||
|
captured_symbols: Vec::new(),
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments,
|
||||||
|
loc_body: Box::new(Located::at_zero(to_effect_call)),
|
||||||
|
};
|
||||||
|
|
||||||
|
use roc_can::annotation::IntroducedVariables;
|
||||||
|
|
||||||
|
let mut introduced_variables = IntroducedVariables::default();
|
||||||
|
|
||||||
|
let signature = {
|
||||||
|
let var_a = var_store.fresh();
|
||||||
|
let var_b = var_store.fresh();
|
||||||
|
|
||||||
|
introduced_variables.insert_named("a".into(), var_a);
|
||||||
|
introduced_variables.insert_named("b".into(), var_b);
|
||||||
|
|
||||||
|
let effect_a = {
|
||||||
|
let actual =
|
||||||
|
build_effect_actual(effect_tag_name.clone(), Type::Variable(var_a), var_store);
|
||||||
|
|
||||||
|
Type::Alias(
|
||||||
|
effect_symbol,
|
||||||
|
vec![("a".into(), Type::Variable(var_a))],
|
||||||
|
Box::new(actual),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let effect_b = {
|
||||||
|
let actual =
|
||||||
|
build_effect_actual(effect_tag_name.clone(), Type::Variable(var_b), var_store);
|
||||||
|
|
||||||
|
Type::Alias(
|
||||||
|
effect_symbol,
|
||||||
|
vec![("b".into(), Type::Variable(var_b))],
|
||||||
|
Box::new(actual),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let closure_var = var_store.fresh();
|
||||||
|
introduced_variables.insert_wildcard(closure_var);
|
||||||
|
let a_to_effect_b = Type::Function(
|
||||||
|
vec![Type::Variable(var_a)],
|
||||||
|
Box::new(Type::Variable(closure_var)),
|
||||||
|
Box::new(effect_b.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let closure_var = var_store.fresh();
|
||||||
|
introduced_variables.insert_wildcard(closure_var);
|
||||||
|
Type::Function(
|
||||||
|
vec![effect_a, a_to_effect_b],
|
||||||
|
Box::new(Type::Variable(closure_var)),
|
||||||
|
Box::new(effect_b),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let def_annotation = roc_can::def::Annotation {
|
||||||
|
signature,
|
||||||
|
introduced_variables,
|
||||||
|
aliases: SendMap::default(),
|
||||||
|
region: Region::zero(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pattern = Pattern::Identifier(after_symbol);
|
||||||
|
let mut pattern_vars = SendMap::default();
|
||||||
|
pattern_vars.insert(after_symbol, function_var);
|
||||||
|
let def = roc_can::def::Def {
|
||||||
|
loc_pattern: Located::at_zero(pattern),
|
||||||
|
loc_expr: Located::at_zero(after_closure),
|
||||||
|
expr_var: function_var,
|
||||||
|
pattern_vars,
|
||||||
|
annotation: Some(def_annotation),
|
||||||
|
};
|
||||||
|
|
||||||
|
(after_symbol, def)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fabricate_host_exposed_def<'a>(
|
||||||
|
env: &mut roc_can::env::Env,
|
||||||
|
scope: &mut roc_can::scope::Scope,
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
ident_ids: &mut IdentIds,
|
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
effect_tag_name: TagName,
|
effect_tag_name: TagName,
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
|
@ -2132,11 +2307,21 @@ fn fabricate_host_exposed_def<'a>(
|
||||||
|
|
||||||
match annotation.typ.shallow_dealias() {
|
match annotation.typ.shallow_dealias() {
|
||||||
Type::Function(args, _, _) => {
|
Type::Function(args, _, _) => {
|
||||||
for _ in 0..args.len() {
|
for i in 0..args.len() {
|
||||||
// let ident_id = ident_ids.gen_unique();
|
let name = format!("closure_arg_{}", i);
|
||||||
let ident_id = ident_ids.get_or_insert(&"mything".into());
|
|
||||||
module_id.register_debug_idents(&ident_ids);
|
let arg_symbol = {
|
||||||
let arg_symbol = Symbol::new(module_id, ident_id);
|
let ident = name.clone().into();
|
||||||
|
scope
|
||||||
|
.introduce(
|
||||||
|
ident,
|
||||||
|
&env.exposed_ident_ids,
|
||||||
|
&mut env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
let arg_var = var_store.fresh();
|
let arg_var = var_store.fresh();
|
||||||
|
|
||||||
arguments.push((arg_var, Located::at_zero(Pattern::Identifier(arg_symbol))));
|
arguments.push((arg_var, Located::at_zero(Pattern::Identifier(arg_symbol))));
|
||||||
|
@ -2156,9 +2341,17 @@ fn fabricate_host_exposed_def<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let effect_closure_symbol = {
|
let effect_closure_symbol = {
|
||||||
let ident_id = ident_ids.gen_unique();
|
let name = "effect_closure";
|
||||||
module_id.register_debug_idents(&ident_ids);
|
|
||||||
Symbol::new(module_id, ident_id)
|
let ident = name.clone().into();
|
||||||
|
scope
|
||||||
|
.introduce(
|
||||||
|
ident,
|
||||||
|
&env.exposed_ident_ids,
|
||||||
|
&mut env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let empty_record_pattern = Pattern::RecordDestructure {
|
let empty_record_pattern = Pattern::RecordDestructure {
|
||||||
|
@ -2214,10 +2407,60 @@ fn fabricate_host_exposed_def<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_effect_actual(effect_tag_name: TagName, a_type: Type, var_store: &mut VarStore) -> Type {
|
||||||
|
let closure_var = var_store.fresh();
|
||||||
|
|
||||||
|
Type::TagUnion(
|
||||||
|
vec![(
|
||||||
|
effect_tag_name,
|
||||||
|
vec![Type::Function(
|
||||||
|
vec![Type::EmptyRec],
|
||||||
|
Box::new(Type::Variable(closure_var)),
|
||||||
|
Box::new(a_type),
|
||||||
|
)],
|
||||||
|
)],
|
||||||
|
Box::new(Type::EmptyTagUnion),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack_exposes_entries<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
entries: &'a [Located<roc_parse::ast::EffectsEntry<'a>>],
|
||||||
|
) -> bumpalo::collections::Vec<
|
||||||
|
'a,
|
||||||
|
(
|
||||||
|
&'a Located<&'a str>,
|
||||||
|
&'a Located<roc_parse::ast::TypeAnnotation<'a>>,
|
||||||
|
),
|
||||||
|
> {
|
||||||
|
use bumpalo::collections::Vec;
|
||||||
|
use roc_parse::ast::EffectsEntry;
|
||||||
|
|
||||||
|
let mut stack: Vec<&EffectsEntry> = Vec::with_capacity_in(entries.len(), arena);
|
||||||
|
let mut output = Vec::with_capacity_in(entries.len(), arena);
|
||||||
|
|
||||||
|
for entry in entries.iter() {
|
||||||
|
stack.push(&entry.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(effects_entry) = stack.pop() {
|
||||||
|
match effects_entry {
|
||||||
|
EffectsEntry::Effect { ident, ann } => {
|
||||||
|
output.push((ident, ann));
|
||||||
|
}
|
||||||
|
EffectsEntry::SpaceAfter(nested, _) | EffectsEntry::SpaceBefore(nested, _) => {
|
||||||
|
stack.push(nested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
fn fabricate_effects_module<'a>(
|
fn fabricate_effects_module<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
ident_ids_by_module: Arc<Mutex<IdentIdsByModule>>,
|
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
header: PlatformHeader<'a>,
|
header: PlatformHeader<'a>,
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
|
@ -2230,48 +2473,112 @@ fn fabricate_effects_module<'a>(
|
||||||
|
|
||||||
// exposed_symbols: MutSet<Symbol>,
|
// exposed_symbols: MutSet<Symbol>,
|
||||||
// aliases: MutMap<Symbol, Alias>,
|
// aliases: MutMap<Symbol, Alias>,
|
||||||
let mut var_store = VarStore::default();
|
|
||||||
|
let num_exposes = header.provides.len() + 1;
|
||||||
|
let mut exposed: Vec<Symbol> = Vec::with_capacity(num_exposes);
|
||||||
|
|
||||||
|
let module_id: ModuleId;
|
||||||
|
|
||||||
|
let name = "Effect";
|
||||||
|
let declared_name: ModuleName = name.into();
|
||||||
|
|
||||||
let PlatformHeader { effects, .. } = header;
|
let PlatformHeader { effects, .. } = header;
|
||||||
|
let effect_entries = unpack_exposes_entries(arena, &effects);
|
||||||
|
|
||||||
let declared_name = "Effect".into();
|
let hardcoded_exposed_functions = vec![name, "after"];
|
||||||
let module_id = {
|
|
||||||
|
let exposed_ident_ids = {
|
||||||
// Lock just long enough to perform the minimal operations necessary.
|
// Lock just long enough to perform the minimal operations necessary.
|
||||||
let mut module_ids = (*module_ids).lock();
|
let mut module_ids = (*module_ids).lock();
|
||||||
|
|
||||||
module_ids.get_or_insert(&declared_name)
|
|
||||||
};
|
|
||||||
let mut scope = roc_can::scope::Scope::new(module_id, &mut var_store);
|
|
||||||
|
|
||||||
let effect_symbol = {
|
|
||||||
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
|
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
|
||||||
|
|
||||||
let ident_ids: &mut IdentIds = ident_ids_by_module.get_mut(&module_id).unwrap();
|
module_id = module_ids.get_or_insert(&declared_name.as_inline_str());
|
||||||
//let ident_id = ident_ids.get_or_insert(&declared_name);
|
|
||||||
//Symbol::new(module_id, ident_id)
|
|
||||||
|
|
||||||
let ident = declared_name.clone().into();
|
// Ensure this module has an entry in the exposed_ident_ids map.
|
||||||
|
ident_ids_by_module
|
||||||
|
.entry(module_id)
|
||||||
|
.or_insert_with(IdentIds::default);
|
||||||
|
|
||||||
|
let ident_ids = ident_ids_by_module.get_mut(&module_id).unwrap();
|
||||||
|
|
||||||
|
// Generate IdentIds entries for all values this module exposes.
|
||||||
|
// This way, when we encounter them in Defs later, they already
|
||||||
|
// have an IdentIds entry.
|
||||||
|
//
|
||||||
|
// We must *not* add them to scope yet, or else the Defs will
|
||||||
|
// incorrectly think they're shadowing them!
|
||||||
|
for (loc_exposed, _) in effect_entries.iter() {
|
||||||
|
// Use get_or_insert here because the ident_ids may already
|
||||||
|
// created an IdentId for this, when it was imported exposed
|
||||||
|
// in a dependent module.
|
||||||
|
//
|
||||||
|
// For example, if module A has [ B.{ foo } ], then
|
||||||
|
// when we get here for B, `foo` will already have
|
||||||
|
// an IdentId. We must reuse that!
|
||||||
|
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.into());
|
||||||
|
let symbol = Symbol::new(module_id, ident_id);
|
||||||
|
|
||||||
|
exposed.push(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
for hardcoded in hardcoded_exposed_functions {
|
||||||
|
// Use get_or_insert here because the ident_ids may already
|
||||||
|
// created an IdentId for this, when it was imported exposed
|
||||||
|
// in a dependent module.
|
||||||
|
//
|
||||||
|
// For example, if module A has [ B.{ foo } ], then
|
||||||
|
// when we get here for B, `foo` will already have
|
||||||
|
// an IdentId. We must reuse that!
|
||||||
|
let ident_id = ident_ids.get_or_insert(&hardcoded.into());
|
||||||
|
let symbol = Symbol::new(module_id, ident_id);
|
||||||
|
|
||||||
|
exposed.push(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
module_id.register_debug_idents(&ident_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
ident_ids.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
// a platform module has no dependencies, hence empty
|
||||||
|
let dep_idents: MutMap<ModuleId, IdentIds> = IdentIds::exposed_builtins(0);
|
||||||
|
|
||||||
|
let mut var_store = VarStore::default();
|
||||||
|
|
||||||
|
let module_ids = { (*module_ids).lock().clone() };
|
||||||
|
|
||||||
|
let mut scope = roc_can::scope::Scope::new(module_id, &mut var_store);
|
||||||
|
let mut can_env = roc_can::env::Env::new(module_id, dep_idents, &module_ids, exposed_ident_ids);
|
||||||
|
|
||||||
|
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
|
||||||
|
let ident_ids: &mut IdentIds = ident_ids_by_module.get_mut(&module_id).unwrap();
|
||||||
|
|
||||||
|
let effect_symbol = {
|
||||||
|
let ident = name.clone().into();
|
||||||
scope
|
scope
|
||||||
.introduce(ident, &(ident_ids.clone()), ident_ids, Region::zero())
|
.introduce(
|
||||||
|
ident,
|
||||||
|
&can_env.exposed_ident_ids,
|
||||||
|
&mut can_env.ident_ids,
|
||||||
|
Region::zero(),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let effect_tag_name = TagName::Private(effect_symbol);
|
||||||
|
|
||||||
let mut aliases = MutMap::default();
|
let mut aliases = MutMap::default();
|
||||||
let alias = {
|
let alias = {
|
||||||
let a_var = var_store.fresh();
|
let a_var = var_store.fresh();
|
||||||
let closure_var = var_store.fresh();
|
|
||||||
|
|
||||||
let actual = Type::TagUnion(
|
let actual = build_effect_actual(
|
||||||
vec![(
|
effect_tag_name.clone(),
|
||||||
TagName::Private(effect_symbol),
|
Type::Variable(a_var),
|
||||||
vec![Type::Function(
|
&mut var_store,
|
||||||
vec![Type::EmptyRec],
|
|
||||||
Box::new(Type::Variable(closure_var)),
|
|
||||||
Box::new(Type::Variable(a_var)),
|
|
||||||
)],
|
|
||||||
)],
|
|
||||||
Box::new(Type::EmptyTagUnion),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
scope.add_alias(
|
scope.add_alias(
|
||||||
effect_symbol,
|
effect_symbol,
|
||||||
Region::zero(),
|
Region::zero(),
|
||||||
|
@ -2287,69 +2594,56 @@ fn fabricate_effects_module<'a>(
|
||||||
let mut declarations = Vec::new();
|
let mut declarations = Vec::new();
|
||||||
|
|
||||||
let exposed_vars_by_symbol = {
|
let exposed_vars_by_symbol = {
|
||||||
let module_ids = (*module_ids).lock();
|
|
||||||
let mut ident_ids_by_module = (*ident_ids_by_module).lock();
|
|
||||||
|
|
||||||
let ident_ids: &mut IdentIds = ident_ids_by_module.get_mut(&module_id).unwrap();
|
|
||||||
|
|
||||||
let ident_id = ident_ids.get_or_insert(&declared_name);
|
|
||||||
let effect_symbol = Symbol::new(module_id, ident_id);
|
|
||||||
|
|
||||||
let mut exposed_vars_by_symbol = Vec::new();
|
let mut exposed_vars_by_symbol = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
use bumpalo::collections::Vec;
|
for (ident, ann) in effect_entries {
|
||||||
|
let symbol = {
|
||||||
let mut stack: Vec<&EffectsEntry> = Vec::with_capacity_in(effects.len(), arena);
|
scope
|
||||||
|
.introduce(
|
||||||
for entry in &effects {
|
ident.value.into(),
|
||||||
stack.push(&entry.value);
|
&can_env.exposed_ident_ids,
|
||||||
}
|
&mut can_env.ident_ids,
|
||||||
|
|
||||||
use roc_parse::ast::EffectsEntry;
|
|
||||||
|
|
||||||
// TODO this clone is almost certainly wrong
|
|
||||||
let exposed_ident_ids = ident_ids.clone();
|
|
||||||
let dep_idents: MutMap<ModuleId, IdentIds> = MutMap::default();
|
|
||||||
let mut can_env =
|
|
||||||
roc_can::env::Env::new(module_id, dep_idents, &module_ids, exposed_ident_ids);
|
|
||||||
|
|
||||||
while let Some(effects_entry) = stack.pop() {
|
|
||||||
match effects_entry {
|
|
||||||
EffectsEntry::Effect { ident, ann } => {
|
|
||||||
let as_inlinable_string: inlinable_string::InlinableString =
|
|
||||||
ident.value.into();
|
|
||||||
let ident_id = ident_ids.get_or_insert(&as_inlinable_string);
|
|
||||||
let symbol = Symbol::new(module_id, ident_id);
|
|
||||||
|
|
||||||
let annotation = roc_can::annotation::canonicalize_annotation(
|
|
||||||
&mut can_env,
|
|
||||||
&mut scope,
|
|
||||||
&ann.value,
|
|
||||||
Region::zero(),
|
Region::zero(),
|
||||||
&mut var_store,
|
)
|
||||||
);
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
let def = fabricate_host_exposed_def(
|
let annotation = roc_can::annotation::canonicalize_annotation(
|
||||||
module_id,
|
&mut can_env,
|
||||||
ident_ids,
|
&mut scope,
|
||||||
symbol,
|
&ann.value,
|
||||||
TagName::Private(effect_symbol),
|
Region::zero(),
|
||||||
&mut var_store,
|
&mut var_store,
|
||||||
annotation,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
exposed_vars_by_symbol.push((symbol, def.expr_var));
|
let def = fabricate_host_exposed_def(
|
||||||
|
&mut can_env,
|
||||||
|
&mut scope,
|
||||||
|
module_id,
|
||||||
|
symbol,
|
||||||
|
TagName::Private(effect_symbol),
|
||||||
|
&mut var_store,
|
||||||
|
annotation,
|
||||||
|
);
|
||||||
|
|
||||||
declarations.push(Declaration::Declare(def));
|
exposed_vars_by_symbol.push((symbol, def.expr_var));
|
||||||
}
|
|
||||||
EffectsEntry::SpaceAfter(nested, _) | EffectsEntry::SpaceBefore(nested, _) => {
|
declarations.push(Declaration::Declare(def));
|
||||||
stack.push(nested);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (effect_after_symbol, def) = fabricate_effect_after(
|
||||||
|
&mut can_env,
|
||||||
|
&mut scope,
|
||||||
|
module_id,
|
||||||
|
effect_symbol,
|
||||||
|
effect_tag_name,
|
||||||
|
&mut var_store,
|
||||||
|
);
|
||||||
|
exposed_vars_by_symbol.push((effect_after_symbol, def.expr_var));
|
||||||
|
declarations.push(Declaration::Declare(def));
|
||||||
|
|
||||||
exposed_vars_by_symbol
|
exposed_vars_by_symbol
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2360,8 +2654,8 @@ fn fabricate_effects_module<'a>(
|
||||||
declarations,
|
declarations,
|
||||||
exposed_imports: MutMap::default(),
|
exposed_imports: MutMap::default(),
|
||||||
lookups: Vec::new(),
|
lookups: Vec::new(),
|
||||||
problems: Vec::new(),
|
problems: can_env.problems,
|
||||||
ident_ids: IdentIds::default(),
|
ident_ids: can_env.ident_ids,
|
||||||
exposed_vars_by_symbol,
|
exposed_vars_by_symbol,
|
||||||
references: MutSet::default(),
|
references: MutSet::default(),
|
||||||
};
|
};
|
||||||
|
@ -2377,6 +2671,7 @@ fn fabricate_effects_module<'a>(
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let constraint = constrain_module(&module_output, module_id, mode, &mut var_store);
|
let constraint = constrain_module(&module_output, module_id, mode, &mut var_store);
|
||||||
|
dbg!(&module_output.aliases);
|
||||||
|
|
||||||
let module = Module {
|
let module = Module {
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -2431,7 +2726,7 @@ fn fabricate_effects_module<'a>(
|
||||||
fn canonicalize_and_constrain<'a>(
|
fn canonicalize_and_constrain<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
module_ids: &ModuleIds,
|
module_ids: &ModuleIds,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: MutMap<ModuleId, IdentIds>,
|
||||||
exposed_symbols: MutSet<Symbol>,
|
exposed_symbols: MutSet<Symbol>,
|
||||||
aliases: MutMap<Symbol, Alias>,
|
aliases: MutMap<Symbol, Alias>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
|
@ -2742,6 +3037,8 @@ fn add_def_to_module<'a>(
|
||||||
// this is a top-level definition, it should not capture anything
|
// this is a top-level definition, it should not capture anything
|
||||||
debug_assert!(captured_symbols.is_empty());
|
debug_assert!(captured_symbols.is_empty());
|
||||||
|
|
||||||
|
dbg!(symbol, &loc_body.value);
|
||||||
|
|
||||||
// If this is an exposed symbol, we need to
|
// If this is an exposed symbol, we need to
|
||||||
// register it as such. Otherwise, since it
|
// register it as such. Otherwise, since it
|
||||||
// never gets called by Roc code, it will never
|
// never gets called by Roc code, it will never
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub struct Symbol(u64);
|
||||||
// Set it to false if you want to see the raw ModuleId and IdentId ints,
|
// Set it to false if you want to see the raw ModuleId and IdentId ints,
|
||||||
// but please set it back to true before checking in the result!
|
// but please set it back to true before checking in the result!
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
const PRETTY_PRINT_DEBUG_SYMBOLS: bool = true;
|
const PRETTY_PRINT_DEBUG_SYMBOLS: bool = false;
|
||||||
|
|
||||||
/// In Debug builds only, Symbol has a name() method that lets
|
/// In Debug builds only, Symbol has a name() method that lets
|
||||||
/// you look up its name in a global intern table. This table is
|
/// you look up its name in a global intern table. This table is
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::exhaustive::{Ctor, Guard, RenderAs, TagId};
|
||||||
use crate::layout::{Builtin, ClosureLayout, Layout, LayoutCache, LayoutProblem};
|
use crate::layout::{Builtin, ClosureLayout, Layout, LayoutCache, LayoutProblem};
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_collections::all::{default_hasher, MutMap, MutSet, SendMap};
|
use roc_collections::all::{default_hasher, MutMap, MutSet};
|
||||||
use roc_module::ident::{ForeignSymbol, Ident, Lowercase, TagName};
|
use roc_module::ident::{ForeignSymbol, Ident, Lowercase, TagName};
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||||
|
@ -419,6 +419,7 @@ impl<'a> Procs<'a> {
|
||||||
|
|
||||||
match patterns_to_when(env, layout_cache, loc_args, ret_var, loc_body) {
|
match patterns_to_when(env, layout_cache, loc_args, ret_var, loc_body) {
|
||||||
Ok((_, pattern_symbols, body)) => {
|
Ok((_, pattern_symbols, body)) => {
|
||||||
|
dbg!(symbol, &pattern_symbols, &body);
|
||||||
// an anonymous closure. These will always be specialized already
|
// an anonymous closure. These will always be specialized already
|
||||||
// by the surrounding context, so we can add pending specializations
|
// by the surrounding context, so we can add pending specializations
|
||||||
// for them immediately.
|
// for them immediately.
|
||||||
|
@ -587,12 +588,12 @@ impl<'a> Procs<'a> {
|
||||||
self.specialized
|
self.specialized
|
||||||
.insert((symbol, layout.clone()), InProgress);
|
.insert((symbol, layout.clone()), InProgress);
|
||||||
|
|
||||||
|
dbg!(symbol, &pending);
|
||||||
match specialize(env, self, symbol, layout_cache, pending, partial_proc) {
|
match specialize(env, self, symbol, layout_cache, pending, partial_proc) {
|
||||||
Ok((proc, _ignore_layout)) => {
|
Ok((proc, _ignore_layout)) => {
|
||||||
// the `layout` is a function pointer, while `_ignore_layout` can be a
|
// the `layout` is a function pointer, while `_ignore_layout` can be a
|
||||||
// closure. We only specialize functions, storing this value with a closure
|
// closure. We only specialize functions, storing this value with a closure
|
||||||
// layout will give trouble.
|
// layout will give trouble.
|
||||||
dbg!(symbol, &layout);
|
|
||||||
self.specialized.insert((symbol, layout), Done(proc));
|
self.specialized.insert((symbol, layout), Done(proc));
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -614,6 +615,7 @@ fn add_pending<'a>(
|
||||||
layout: Layout<'a>,
|
layout: Layout<'a>,
|
||||||
pending: PendingSpecialization,
|
pending: PendingSpecialization,
|
||||||
) {
|
) {
|
||||||
|
// dbg!(symbol, &layout, &pending);
|
||||||
let all_pending = pending_specializations
|
let all_pending = pending_specializations
|
||||||
.entry(symbol)
|
.entry(symbol)
|
||||||
.or_insert_with(|| HashMap::with_capacity_and_hasher(1, default_hasher()));
|
.or_insert_with(|| HashMap::with_capacity_and_hasher(1, default_hasher()));
|
||||||
|
@ -1337,6 +1339,7 @@ pub fn specialize_all<'a>(
|
||||||
mut procs: Procs<'a>,
|
mut procs: Procs<'a>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
) -> Procs<'a> {
|
) -> Procs<'a> {
|
||||||
|
dbg!(&procs.externals_others_need);
|
||||||
let it = procs.externals_others_need.specs.clone();
|
let it = procs.externals_others_need.specs.clone();
|
||||||
let it = it
|
let it = it
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1360,7 +1363,6 @@ pub fn specialize_all<'a>(
|
||||||
partial_proc,
|
partial_proc,
|
||||||
) {
|
) {
|
||||||
Ok((proc, layout)) => {
|
Ok((proc, layout)) => {
|
||||||
dbg!(name, &layout);
|
|
||||||
procs.specialized.insert((name, layout), Done(proc));
|
procs.specialized.insert((name, layout), Done(proc));
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -1406,7 +1408,7 @@ pub fn specialize_all<'a>(
|
||||||
procs
|
procs
|
||||||
.specialized
|
.specialized
|
||||||
.insert((name, outside_layout.clone()), InProgress);
|
.insert((name, outside_layout.clone()), InProgress);
|
||||||
|
dbg!(name);
|
||||||
match specialize(
|
match specialize(
|
||||||
env,
|
env,
|
||||||
&mut procs,
|
&mut procs,
|
||||||
|
@ -1417,9 +1419,6 @@ pub fn specialize_all<'a>(
|
||||||
) {
|
) {
|
||||||
Ok((proc, layout)) => {
|
Ok((proc, layout)) => {
|
||||||
debug_assert_eq!(outside_layout, layout);
|
debug_assert_eq!(outside_layout, layout);
|
||||||
// procs.specialized.remove(&(name, outside_layout));
|
|
||||||
// dbg!(name, &layout);
|
|
||||||
// procs.specialized.insert((name, layout), Done(proc));
|
|
||||||
|
|
||||||
if let Layout::Closure(args, closure, ret) = layout {
|
if let Layout::Closure(args, closure, ret) = layout {
|
||||||
procs.specialized.remove(&(name, outside_layout));
|
procs.specialized.remove(&(name, outside_layout));
|
||||||
|
@ -1457,6 +1456,8 @@ fn specialize_external<'a>(
|
||||||
host_exposed_variables: &[(Symbol, Variable)],
|
host_exposed_variables: &[(Symbol, Variable)],
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: PartialProc<'a>,
|
||||||
) -> Result<Proc<'a>, LayoutProblem> {
|
) -> Result<Proc<'a>, LayoutProblem> {
|
||||||
|
println!("------- SPECIALIZE EXTERNAL {:?}", proc_name);
|
||||||
|
|
||||||
let PartialProc {
|
let PartialProc {
|
||||||
annotation,
|
annotation,
|
||||||
pattern_symbols,
|
pattern_symbols,
|
||||||
|
@ -1465,6 +1466,8 @@ fn specialize_external<'a>(
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
} = partial_proc;
|
} = partial_proc;
|
||||||
|
|
||||||
|
dbg!(&body);
|
||||||
|
|
||||||
// unify the called function with the specialized signature, then specialize the function body
|
// unify the called function with the specialized signature, then specialize the function body
|
||||||
let snapshot = env.subs.snapshot();
|
let snapshot = env.subs.snapshot();
|
||||||
let cache_snapshot = layout_cache.snapshot();
|
let cache_snapshot = layout_cache.snapshot();
|
||||||
|
@ -1472,7 +1475,7 @@ fn specialize_external<'a>(
|
||||||
let unified = roc_unify::unify::unify(env.subs, annotation, fn_var);
|
let unified = roc_unify::unify::unify(env.subs, annotation, fn_var);
|
||||||
|
|
||||||
let is_valid = matches!(unified, roc_unify::unify::Unified::Success(_));
|
let is_valid = matches!(unified, roc_unify::unify::Unified::Success(_));
|
||||||
debug_assert!(is_valid);
|
debug_assert!(is_valid, "unificaton failure for {:?}", proc_name);
|
||||||
|
|
||||||
// if this is a closure, add the closure record argument
|
// if this is a closure, add the closure record argument
|
||||||
let pattern_symbols = if let CapturedSymbols::Captured(_) = captured_symbols {
|
let pattern_symbols = if let CapturedSymbols::Captured(_) = captured_symbols {
|
||||||
|
@ -1558,7 +1561,8 @@ fn specialize_external<'a>(
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg!(proc_name, &proc_args, &ret_layout);
|
println!("Done for {:?}\n\n", proc_name);
|
||||||
|
|
||||||
let proc = Proc {
|
let proc = Proc {
|
||||||
name: proc_name,
|
name: proc_name,
|
||||||
args: proc_args,
|
args: proc_args,
|
||||||
|
@ -2977,16 +2981,19 @@ pub fn with_hole<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
match loc_expr.value {
|
match loc_expr.value {
|
||||||
roc_can::expr::Expr::Var(proc_name) if is_known(&proc_name) => call_by_name(
|
roc_can::expr::Expr::Var(proc_name) if is_known(&proc_name) => {
|
||||||
env,
|
// a call by a known name
|
||||||
procs,
|
call_by_name(
|
||||||
fn_var,
|
env,
|
||||||
proc_name,
|
procs,
|
||||||
loc_args,
|
fn_var,
|
||||||
layout_cache,
|
proc_name,
|
||||||
assigned,
|
loc_args,
|
||||||
hole,
|
layout_cache,
|
||||||
),
|
assigned,
|
||||||
|
hole,
|
||||||
|
)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Call by pointer - the closure was anonymous, e.g.
|
// Call by pointer - the closure was anonymous, e.g.
|
||||||
//
|
//
|
||||||
|
@ -3184,6 +3191,7 @@ pub fn with_hole<'a>(
|
||||||
hole,
|
hole,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let (var, _) = args[0];
|
||||||
let iter = args
|
let iter = args
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev()
|
.rev()
|
||||||
|
@ -4699,7 +4707,6 @@ fn call_by_name<'a>(
|
||||||
|
|
||||||
procs.specialized.remove(&(proc_name, full_layout));
|
procs.specialized.remove(&(proc_name, full_layout));
|
||||||
|
|
||||||
dbg!(proc_name, &function_layout.full);
|
|
||||||
procs.specialized.insert(
|
procs.specialized.insert(
|
||||||
(proc_name, function_layout.full.clone()),
|
(proc_name, function_layout.full.clone()),
|
||||||
Done(proc),
|
Done(proc),
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
app Main provides [ main ] imports [ Effect ]
|
app Main provides [ main ] imports [ Effect ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main : Effect.Effect {} as Fx
|
main : Effect.Effect {} as Fx
|
||||||
main =
|
main =
|
||||||
Effect.putChar 68
|
e = Effect.putChar 68
|
||||||
|
|
||||||
|
e |> Effect.after \{} -> e
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn roc_fx_put_char(foo: i64) -> () {
|
pub fn roc_fx_put_char(foo: i64) -> () {
|
||||||
let character = foo as u8 as char;
|
let character = foo as u8 as char;
|
||||||
println!("{}", character);
|
print!("{}", character);
|
||||||
|
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue