This commit is contained in:
Folkert 2021-11-02 21:08:12 +01:00
parent c7920b2a24
commit 487948e514

View file

@ -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!)