mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
WIP
This commit is contained in:
parent
c7920b2a24
commit
487948e514
1 changed files with 39 additions and 31 deletions
|
@ -459,6 +459,10 @@ impl<'a> Procs<'a> {
|
||||||
self.module_thunks.iter().any(|x| *x == symbol)
|
self.module_thunks.iter().any(|x| *x == symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_partial_proc<'b>(&'b self, symbol: Symbol) -> Option<&'b PartialProc<'a>> {
|
||||||
|
self.partial_procs.get(&symbol)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_specialized_procs_without_rc(
|
pub fn get_specialized_procs_without_rc(
|
||||||
self,
|
self,
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
|
@ -573,7 +577,7 @@ impl<'a> Procs<'a> {
|
||||||
let outside_layout = layout;
|
let outside_layout = layout;
|
||||||
|
|
||||||
let partial_proc;
|
let partial_proc;
|
||||||
if let Some(existing) = self.partial_procs.get(&symbol) {
|
if let Some(existing) = self.get_partial_proc(symbol) {
|
||||||
// if we're adding the same partial proc twice, they must be the actual same!
|
// if we're adding the same partial proc twice, they must be the actual same!
|
||||||
//
|
//
|
||||||
// NOTE we can't skip extra work! we still need to make the specialization for this
|
// NOTE we can't skip extra work! we still need to make the specialization for this
|
||||||
|
@ -583,17 +587,17 @@ impl<'a> Procs<'a> {
|
||||||
debug_assert_eq!(captured_symbols, existing.captured_symbols);
|
debug_assert_eq!(captured_symbols, existing.captured_symbols);
|
||||||
debug_assert_eq!(is_self_recursive, existing.is_self_recursive);
|
debug_assert_eq!(is_self_recursive, existing.is_self_recursive);
|
||||||
|
|
||||||
partial_proc = existing.clone();
|
partial_proc = existing;
|
||||||
} else {
|
} else {
|
||||||
let pattern_symbols = pattern_symbols.into_bump_slice();
|
let pattern_symbols = pattern_symbols.into_bump_slice();
|
||||||
|
|
||||||
partial_proc = PartialProc {
|
partial_proc = env.arena.alloc(PartialProc {
|
||||||
annotation,
|
annotation,
|
||||||
pattern_symbols,
|
pattern_symbols,
|
||||||
captured_symbols,
|
captured_symbols,
|
||||||
body: body.value,
|
body: body.value,
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
match specialize(env, self, symbol, layout_cache, pending, partial_proc)
|
match specialize(env, self, symbol, layout_cache, pending, partial_proc)
|
||||||
|
@ -662,9 +666,8 @@ impl<'a> Procs<'a> {
|
||||||
None => {
|
None => {
|
||||||
let symbol = name;
|
let symbol = name;
|
||||||
|
|
||||||
// TODO should pending_procs hold a Rc<Proc>?
|
let partial_proc = match self.get_partial_proc(symbol) {
|
||||||
let partial_proc = match self.partial_procs.get(&symbol) {
|
Some(p) => p,
|
||||||
Some(p) => p.clone(),
|
|
||||||
None => panic!("no partial_proc for {:?} in module {:?}", symbol, env.home),
|
None => panic!("no partial_proc for {:?} in module {:?}", symbol, env.home),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1722,14 +1725,14 @@ pub fn specialize_all<'a>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Entry::Vacant(vacant) => {
|
Entry::Vacant(vacant) => {
|
||||||
match procs.partial_procs.get(&name) {
|
match procs.get_partial_proc(name) {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
// Mark this proc as in-progress, so if we're dealing with
|
// Mark this proc as in-progress, so if we're dealing with
|
||||||
// mutually recursive functions, we don't loop forever.
|
// mutually recursive functions, we don't loop forever.
|
||||||
// (We had a bug around this before this system existed!)
|
// (We had a bug around this before this system existed!)
|
||||||
vacant.insert(InProgress);
|
vacant.insert(InProgress);
|
||||||
|
|
||||||
v.clone()
|
v
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// TODO this assumes the specialization is done by another module
|
// TODO this assumes the specialization is done by another module
|
||||||
|
@ -1804,8 +1807,8 @@ fn specialize_externals_others_need<'a>(
|
||||||
|
|
||||||
let name = *symbol;
|
let name = *symbol;
|
||||||
|
|
||||||
let partial_proc = match procs.partial_procs.get(&name) {
|
let partial_proc = match procs.get_partial_proc(name) {
|
||||||
Some(v) => v.clone(),
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
panic!("Cannot find a partial proc for {:?}", name);
|
panic!("Cannot find a partial proc for {:?}", name);
|
||||||
}
|
}
|
||||||
|
@ -1897,7 +1900,7 @@ fn specialize_external<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
fn_var: Variable,
|
fn_var: Variable,
|
||||||
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> {
|
||||||
let PartialProc {
|
let PartialProc {
|
||||||
annotation,
|
annotation,
|
||||||
|
@ -1911,7 +1914,7 @@ fn specialize_external<'a>(
|
||||||
let snapshot = env.subs.snapshot();
|
let snapshot = env.subs.snapshot();
|
||||||
let cache_snapshot = layout_cache.snapshot();
|
let cache_snapshot = layout_cache.snapshot();
|
||||||
|
|
||||||
let _unified = roc_unify::unify::unify(env.subs, annotation, fn_var);
|
let _unified = roc_unify::unify::unify(env.subs, *annotation, fn_var);
|
||||||
|
|
||||||
// This will not hold for programs with type errors
|
// This will not hold for programs with type errors
|
||||||
// let is_valid = matches!(unified, roc_unify::unify::Unified::Success(_));
|
// let is_valid = matches!(unified, roc_unify::unify::Unified::Success(_));
|
||||||
|
@ -2019,13 +2022,13 @@ fn specialize_external<'a>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let recursivity = if is_self_recursive {
|
let recursivity = if *is_self_recursive {
|
||||||
SelfRecursive::SelfRecursive(JoinPointId(env.unique_symbol()))
|
SelfRecursive::SelfRecursive(JoinPointId(env.unique_symbol()))
|
||||||
} else {
|
} else {
|
||||||
SelfRecursive::NotSelfRecursive
|
SelfRecursive::NotSelfRecursive
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut specialized_body = from_can(env, fn_var, body, procs, layout_cache);
|
let mut specialized_body = from_can(env, fn_var, body.clone(), procs, layout_cache);
|
||||||
|
|
||||||
match specialized {
|
match specialized {
|
||||||
SpecializedLayout::FunctionPointerBody {
|
SpecializedLayout::FunctionPointerBody {
|
||||||
|
@ -2415,13 +2418,24 @@ struct SpecializeFailure<'a> {
|
||||||
|
|
||||||
type SpecializeSuccess<'a> = (Proc<'a>, RawFunctionLayout<'a>);
|
type SpecializeSuccess<'a> = (Proc<'a>, RawFunctionLayout<'a>);
|
||||||
|
|
||||||
fn specialize<'a>(
|
fn specialize2<'a, 'b>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
procs: &mut Procs<'a>,
|
partial_proc: &'b PartialProc<'a>,
|
||||||
|
procs: &'b mut Procs<'a>,
|
||||||
proc_name: Symbol,
|
proc_name: Symbol,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
pending: PendingSpecialization,
|
pending: PendingSpecialization,
|
||||||
partial_proc: PartialProc<'a>,
|
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn specialize<'a, 'b>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
procs: &'b mut Procs<'a>,
|
||||||
|
proc_name: Symbol,
|
||||||
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
|
pending: PendingSpecialization,
|
||||||
|
partial_proc: &'b PartialProc<'a>,
|
||||||
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
||||||
let PendingSpecialization {
|
let PendingSpecialization {
|
||||||
solved_type,
|
solved_type,
|
||||||
|
@ -2466,7 +2480,7 @@ fn specialize_solved_type<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
solved_type: &SolvedType,
|
solved_type: &SolvedType,
|
||||||
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: &PartialProc<'a>,
|
||||||
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
||||||
specialize_variable_help(
|
specialize_variable_help(
|
||||||
env,
|
env,
|
||||||
|
@ -2486,7 +2500,7 @@ fn specialize_variable<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
fn_var: Variable,
|
fn_var: Variable,
|
||||||
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: &PartialProc<'a>,
|
||||||
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>> {
|
||||||
specialize_variable_help(
|
specialize_variable_help(
|
||||||
env,
|
env,
|
||||||
|
@ -2506,7 +2520,7 @@ fn specialize_variable_help<'a, F>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
fn_var_thunk: F,
|
fn_var_thunk: F,
|
||||||
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
host_exposed_aliases: BumpMap<Symbol, SolvedType>,
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: &PartialProc<'a>,
|
||||||
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>>
|
) -> Result<SpecializeSuccess<'a>, SpecializeFailure<'a>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Env<'a, '_>) -> Variable,
|
F: FnOnce(&mut Env<'a, '_>) -> Variable,
|
||||||
|
@ -2629,7 +2643,7 @@ fn specialize_naked_symbol<'a>(
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
if procs.is_module_thunk(symbol) {
|
if procs.is_module_thunk(symbol) {
|
||||||
let partial_proc = procs.partial_procs.get(&symbol).unwrap();
|
let partial_proc = procs.get_partial_proc(symbol).unwrap();
|
||||||
let fn_var = partial_proc.annotation;
|
let fn_var = partial_proc.annotation;
|
||||||
|
|
||||||
// This is a top-level declaration, which will code gen to a 0-arity thunk.
|
// This is a top-level declaration, which will code gen to a 0-arity thunk.
|
||||||
|
@ -6086,7 +6100,7 @@ fn reuse_function_symbol<'a>(
|
||||||
result: Stmt<'a>,
|
result: Stmt<'a>,
|
||||||
original: Symbol,
|
original: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
match procs.partial_procs.get(&original) {
|
match procs.get_partial_proc(original) {
|
||||||
None => {
|
None => {
|
||||||
match arg_var {
|
match arg_var {
|
||||||
Some(arg_var) if env.is_imported_symbol(original) => {
|
Some(arg_var) if env.is_imported_symbol(original) => {
|
||||||
|
@ -6659,7 +6673,7 @@ fn call_by_name_help<'a>(
|
||||||
assign_to_symbols(env, procs, layout_cache, iter, result)
|
assign_to_symbols(env, procs, layout_cache, iter, result)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let opt_partial_proc = procs.partial_procs.get(&proc_name);
|
let opt_partial_proc = procs.get_partial_proc(proc_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -6676,9 +6690,6 @@ fn call_by_name_help<'a>(
|
||||||
|
|
||||||
match opt_partial_proc {
|
match opt_partial_proc {
|
||||||
Some(partial_proc) => {
|
Some(partial_proc) => {
|
||||||
// TODO should pending_procs hold a Rc<Proc> to avoid this .clone()?
|
|
||||||
let partial_proc = partial_proc.clone();
|
|
||||||
|
|
||||||
// Mark this proc as in-progress, so if we're dealing with
|
// Mark this proc as in-progress, so if we're dealing with
|
||||||
// mutually recursive functions, we don't loop forever.
|
// mutually recursive functions, we don't loop forever.
|
||||||
// (We had a bug around this before this system existed!)
|
// (We had a bug around this before this system existed!)
|
||||||
|
@ -6797,13 +6808,10 @@ fn call_by_name_module_thunk<'a>(
|
||||||
force_thunk(env, proc_name, inner_layout, assigned, hole)
|
force_thunk(env, proc_name, inner_layout, assigned, hole)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let opt_partial_proc = procs.partial_procs.get(&proc_name);
|
let opt_partial_proc = procs.get_partial_proc(proc_name);
|
||||||
|
|
||||||
match opt_partial_proc {
|
match opt_partial_proc {
|
||||||
Some(partial_proc) => {
|
Some(partial_proc) => {
|
||||||
// TODO should pending_procs hold a Rc<Proc> to avoid this .clone()?
|
|
||||||
let partial_proc = partial_proc.clone();
|
|
||||||
|
|
||||||
// Mark this proc as in-progress, so if we're dealing with
|
// Mark this proc as in-progress, so if we're dealing with
|
||||||
// mutually recursive functions, we don't loop forever.
|
// mutually recursive functions, we don't loop forever.
|
||||||
// (We had a bug around this before this system existed!)
|
// (We had a bug around this before this system existed!)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue