mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
abstract checking of is module thunk
This commit is contained in:
parent
6400baf2c1
commit
6a6ea64323
2 changed files with 35 additions and 28 deletions
|
@ -3953,7 +3953,6 @@ fn make_specializations<'a>(
|
||||||
|
|
||||||
procs.partial_procs = procs_base.partial_procs;
|
procs.partial_procs = procs_base.partial_procs;
|
||||||
procs.module_thunks.extend(procs_base.module_thunks);
|
procs.module_thunks.extend(procs_base.module_thunks);
|
||||||
procs.pending_specializations = Some(procs_base.pending_specializations);
|
|
||||||
procs.runtime_errors = procs_base.runtime_errors;
|
procs.runtime_errors = procs_base.runtime_errors;
|
||||||
procs.imported_module_thunks = procs_base.imported_module_thunks;
|
procs.imported_module_thunks = procs_base.imported_module_thunks;
|
||||||
|
|
||||||
|
@ -3964,6 +3963,7 @@ fn make_specializations<'a>(
|
||||||
&mut mono_env,
|
&mut mono_env,
|
||||||
procs,
|
procs,
|
||||||
specializations_we_must_make,
|
specializations_we_must_make,
|
||||||
|
procs_base.pending_specializations,
|
||||||
&mut layout_cache,
|
&mut layout_cache,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -453,6 +453,10 @@ impl<'a> Procs<'a> {
|
||||||
self.imported_module_thunks.iter().any(|x| *x == symbol)
|
self.imported_module_thunks.iter().any(|x| *x == symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_module_thunk(&self, symbol: Symbol) -> bool {
|
||||||
|
self.module_thunks.iter().any(|x| *x == 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, '_>,
|
||||||
|
@ -555,12 +559,13 @@ impl<'a> Procs<'a> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.is_module_thunk(symbol) {
|
||||||
|
debug_assert!(layout.arguments.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
match &mut self.pending_specializations {
|
match &mut self.pending_specializations {
|
||||||
Some(pending_specializations) => {
|
Some(pending_specializations) => {
|
||||||
// register the pending specialization, so this gets code genned later
|
// register the pending specialization, so this gets code genned later
|
||||||
if self.module_thunks.contains(&symbol) {
|
|
||||||
debug_assert!(layout.arguments.is_empty());
|
|
||||||
}
|
|
||||||
add_pending(pending_specializations, symbol, layout, pending);
|
add_pending(pending_specializations, symbol, layout, pending);
|
||||||
|
|
||||||
self.partial_procs.insert(symbol, partial_proc);
|
self.partial_procs.insert(symbol, partial_proc);
|
||||||
|
@ -584,7 +589,7 @@ impl<'a> Procs<'a> {
|
||||||
proc.name
|
proc.name
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.module_thunks.contains(&proc.name) {
|
if self.is_module_thunk(proc.name) {
|
||||||
debug_assert!(top_level.arguments.is_empty());
|
debug_assert!(top_level.arguments.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,16 +628,17 @@ impl<'a> Procs<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register the pending specialization, so this gets code genned later
|
||||||
|
if self.module_thunks.contains(&name) {
|
||||||
|
debug_assert!(layout.arguments.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
// This should only be called when pending_specializations is Some.
|
// This should only be called when pending_specializations is Some.
|
||||||
// Otherwise, it's being called in the wrong pass!
|
// Otherwise, it's being called in the wrong pass!
|
||||||
match &mut self.pending_specializations {
|
match &mut self.pending_specializations {
|
||||||
Some(pending_specializations) => {
|
Some(pending_specializations) => {
|
||||||
let pending = PendingSpecialization::from_var(env.arena, env.subs, fn_var);
|
let pending = PendingSpecialization::from_var(env.arena, env.subs, fn_var);
|
||||||
|
|
||||||
// register the pending specialization, so this gets code genned later
|
|
||||||
if self.module_thunks.contains(&name) {
|
|
||||||
debug_assert!(layout.arguments.is_empty());
|
|
||||||
}
|
|
||||||
add_pending(pending_specializations, name, layout, pending)
|
add_pending(pending_specializations, name, layout, pending)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1675,15 +1681,18 @@ pub fn specialize_all<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
mut procs: Procs<'a>,
|
mut procs: Procs<'a>,
|
||||||
externals_others_need: ExternalSpecializations<'a>,
|
externals_others_need: ExternalSpecializations<'a>,
|
||||||
|
mut pending_specializations: BumpMap<Symbol, MutMap<ProcLayout<'a>, PendingSpecialization<'a>>>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
) -> Procs<'a> {
|
) -> Procs<'a> {
|
||||||
specialize_all_help(env, &mut procs, externals_others_need, layout_cache);
|
specialize_all_help(env, &mut procs, externals_others_need, layout_cache);
|
||||||
|
|
||||||
// When calling from_can, pending_specializations should be unavailable.
|
// When calling from_can, pending_specializations should be unavailable.
|
||||||
// This must be a single pass, and we must not add any more entries to it!
|
// This must be a single pass, and we must not add any more entries to it!
|
||||||
let opt_pending_specializations = std::mem::replace(&mut procs.pending_specializations, None);
|
|
||||||
|
|
||||||
for (name, by_layout) in opt_pending_specializations.into_iter().flatten() {
|
let opt_pending_specializations = std::mem::replace(&mut procs.pending_specializations, None);
|
||||||
|
pending_specializations.extend(opt_pending_specializations.into_iter().flatten());
|
||||||
|
|
||||||
|
for (name, by_layout) in pending_specializations {
|
||||||
for (outside_layout, pending) in by_layout.into_iter() {
|
for (outside_layout, pending) in by_layout.into_iter() {
|
||||||
// If we've already seen this (Symbol, Layout) combination before,
|
// If we've already seen this (Symbol, Layout) combination before,
|
||||||
// don't try to specialize it again. If we do, we'll loop forever!
|
// don't try to specialize it again. If we do, we'll loop forever!
|
||||||
|
@ -1718,7 +1727,7 @@ pub fn specialize_all<'a>(
|
||||||
// TODO thiscode is duplicated elsewhere
|
// TODO thiscode is duplicated elsewhere
|
||||||
let top_level = ProcLayout::from_raw(env.arena, layout);
|
let top_level = ProcLayout::from_raw(env.arena, layout);
|
||||||
|
|
||||||
if procs.module_thunks.contains(&proc.name) {
|
if procs.is_module_thunk(proc.name) {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
top_level.arguments.is_empty(),
|
top_level.arguments.is_empty(),
|
||||||
"{:?} from {:?}",
|
"{:?} from {:?}",
|
||||||
|
@ -1798,7 +1807,7 @@ fn specialize_all_help<'a>(
|
||||||
Ok((proc, layout)) => {
|
Ok((proc, layout)) => {
|
||||||
let top_level = ProcLayout::from_raw(env.arena, layout);
|
let top_level = ProcLayout::from_raw(env.arena, layout);
|
||||||
|
|
||||||
if procs.module_thunks.contains(&name) {
|
if procs.is_module_thunk(name) {
|
||||||
debug_assert!(top_level.arguments.is_empty());
|
debug_assert!(top_level.arguments.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2498,7 +2507,7 @@ where
|
||||||
.raw_from_var(env.arena, fn_var, env.subs)
|
.raw_from_var(env.arena, fn_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||||
|
|
||||||
let raw = if procs.module_thunks.contains(&proc_name) {
|
let raw = if procs.is_module_thunk(proc_name) {
|
||||||
match raw {
|
match raw {
|
||||||
RawFunctionLayout::Function(_, lambda_set, _) => {
|
RawFunctionLayout::Function(_, lambda_set, _) => {
|
||||||
RawFunctionLayout::ZeroArgumentThunk(Layout::LambdaSet(lambda_set))
|
RawFunctionLayout::ZeroArgumentThunk(Layout::LambdaSet(lambda_set))
|
||||||
|
@ -2601,7 +2610,7 @@ fn specialize_naked_symbol<'a>(
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
if procs.module_thunks.contains(&symbol) {
|
if procs.is_module_thunk(symbol) {
|
||||||
let partial_proc = procs.partial_procs.get(&symbol).unwrap();
|
let partial_proc = procs.partial_procs.get(&symbol).unwrap();
|
||||||
let fn_var = partial_proc.annotation;
|
let fn_var = partial_proc.annotation;
|
||||||
|
|
||||||
|
@ -6163,7 +6172,7 @@ fn reuse_function_symbol<'a>(
|
||||||
closure_data,
|
closure_data,
|
||||||
env.arena.alloc(result),
|
env.arena.alloc(result),
|
||||||
)
|
)
|
||||||
} else if procs.module_thunks.contains(&original) {
|
} else if procs.is_module_thunk(original) {
|
||||||
// this is a 0-argument thunk
|
// this is a 0-argument thunk
|
||||||
|
|
||||||
// TODO suspicious
|
// TODO suspicious
|
||||||
|
@ -6359,7 +6368,7 @@ fn call_by_name<'a>(
|
||||||
evaluate_arguments_then_runtime_error(env, procs, layout_cache, msg, loc_args)
|
evaluate_arguments_then_runtime_error(env, procs, layout_cache, msg, loc_args)
|
||||||
}
|
}
|
||||||
Ok(RawFunctionLayout::Function(arg_layouts, lambda_set, ret_layout)) => {
|
Ok(RawFunctionLayout::Function(arg_layouts, lambda_set, ret_layout)) => {
|
||||||
if procs.module_thunks.contains(&proc_name) {
|
if procs.is_module_thunk(proc_name) {
|
||||||
if loc_args.is_empty() {
|
if loc_args.is_empty() {
|
||||||
call_by_name_module_thunk(
|
call_by_name_module_thunk(
|
||||||
env,
|
env,
|
||||||
|
@ -6436,7 +6445,7 @@ fn call_by_name<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(RawFunctionLayout::ZeroArgumentThunk(ret_layout)) => {
|
Ok(RawFunctionLayout::ZeroArgumentThunk(ret_layout)) => {
|
||||||
if procs.module_thunks.contains(&proc_name) {
|
if procs.is_module_thunk(proc_name) {
|
||||||
// here we turn a call to a module thunk into forcing of that thunk
|
// here we turn a call to a module thunk into forcing of that thunk
|
||||||
call_by_name_module_thunk(
|
call_by_name_module_thunk(
|
||||||
env,
|
env,
|
||||||
|
@ -6590,14 +6599,14 @@ fn call_by_name_help<'a>(
|
||||||
// the same specialization independently), we work through the
|
// the same specialization independently), we work through the
|
||||||
// queue of pending specializations to complete each specialization
|
// queue of pending specializations to complete each specialization
|
||||||
// exactly once.
|
// exactly once.
|
||||||
|
if procs.is_module_thunk(proc_name) {
|
||||||
|
debug_assert!(top_level_layout.arguments.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
match &mut procs.pending_specializations {
|
match &mut procs.pending_specializations {
|
||||||
Some(pending_specializations) => {
|
Some(pending_specializations) => {
|
||||||
debug_assert!(!env.is_imported_symbol(proc_name));
|
debug_assert!(!env.is_imported_symbol(proc_name));
|
||||||
|
|
||||||
if procs.module_thunks.contains(&proc_name) {
|
|
||||||
debug_assert!(top_level_layout.arguments.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
// register the pending specialization, so this gets code genned later
|
// register the pending specialization, so this gets code genned later
|
||||||
add_pending(
|
add_pending(
|
||||||
pending_specializations,
|
pending_specializations,
|
||||||
|
@ -6725,8 +6734,6 @@ fn call_by_name_module_thunk<'a>(
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
debug_assert!(!env.is_imported_symbol(proc_name));
|
debug_assert!(!env.is_imported_symbol(proc_name));
|
||||||
|
|
||||||
// debug_assert!(!procs.module_thunks.contains(&proc_name), "{:?}", proc_name);
|
|
||||||
|
|
||||||
let top_level_layout = ProcLayout::new(env.arena, &[], *ret_layout);
|
let top_level_layout = ProcLayout::new(env.arena, &[], *ret_layout);
|
||||||
|
|
||||||
let inner_layout = *ret_layout;
|
let inner_layout = *ret_layout;
|
||||||
|
@ -6751,14 +6758,14 @@ fn call_by_name_module_thunk<'a>(
|
||||||
// the same specialization independently), we work through the
|
// the same specialization independently), we work through the
|
||||||
// queue of pending specializations to complete each specialization
|
// queue of pending specializations to complete each specialization
|
||||||
// exactly once.
|
// exactly once.
|
||||||
|
if procs.is_module_thunk(proc_name) {
|
||||||
|
debug_assert!(top_level_layout.arguments.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
match &mut procs.pending_specializations {
|
match &mut procs.pending_specializations {
|
||||||
Some(pending_specializations) => {
|
Some(pending_specializations) => {
|
||||||
debug_assert!(!env.is_imported_symbol(proc_name));
|
debug_assert!(!env.is_imported_symbol(proc_name));
|
||||||
|
|
||||||
if procs.module_thunks.contains(&proc_name) {
|
|
||||||
debug_assert!(top_level_layout.arguments.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
// register the pending specialization, so this gets code genned later
|
// register the pending specialization, so this gets code genned later
|
||||||
add_pending(
|
add_pending(
|
||||||
pending_specializations,
|
pending_specializations,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue