Fix infinite loop

This commit is contained in:
Richard Feldman 2020-06-21 21:23:06 -04:00
parent 5ec512a0e7
commit b97c94c2da
3 changed files with 22 additions and 17 deletions

View file

@ -244,7 +244,7 @@ pub fn build(
// Add all the Proc headers to the module. // Add all the Proc headers to the module.
// We have to do this in a separate pass first, // We have to do this in a separate pass first,
// because their bodies may reference each other. // because their bodies may reference each other.
for (symbol, layout, proc) in specializations.drain(..) { for ((symbol, layout), proc) in specializations.drain() {
let (fn_val, arg_basic_types) = let (fn_val, arg_basic_types) =
build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc); build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc);

View file

@ -92,7 +92,7 @@ macro_rules! assert_llvm_evals_to {
// Add all the Proc headers to the module. // Add all the Proc headers to the module.
// We have to do this in a separate pass first, // We have to do this in a separate pass first,
// because their bodies may reference each other. // because their bodies may reference each other.
for (symbol, layout, proc) in specializations.drain(..) { for ((symbol, layout), proc) in specializations.drain() {
let (fn_val, arg_basic_types) = let (fn_val, arg_basic_types) =
build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc); build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc);
@ -263,7 +263,7 @@ macro_rules! assert_opt_evals_to {
// Add all the Proc headers to the module. // Add all the Proc headers to the module.
// We have to do this in a separate pass first, // We have to do this in a separate pass first,
// because their bodies may reference each other. // because their bodies may reference each other.
for (symbol, layout, proc) in specializations.drain(..) { for ((symbol, layout), proc) in specializations.drain() {
let (fn_val, arg_basic_types) = let (fn_val, arg_basic_types) =
build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc); build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc);

View file

@ -1383,8 +1383,9 @@ pub fn specialize_all<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
mut procs: Procs<'a>, mut procs: Procs<'a>,
layout_cache: &mut LayoutCache<'a>, layout_cache: &mut LayoutCache<'a>,
) -> (Vec<'a, (Symbol, Layout<'a>, Proc<'a>)>, MutSet<Symbol>) { ) -> (MutMap<(Symbol, Layout<'a>), Proc<'a>>, MutSet<Symbol>) {
let mut answer = Vec::with_capacity_in(procs.pending_specializations.len(), env.arena); let mut answer =
HashMap::with_capacity_and_hasher(procs.pending_specializations.len(), default_hasher());
let mut runtime_errors = MutSet::default(); let mut runtime_errors = MutSet::default();
let mut is_finished = procs.pending_specializations.is_empty(); let mut is_finished = procs.pending_specializations.is_empty();
@ -1409,19 +1410,23 @@ pub fn specialize_all<'a>(
for (name, mut by_layout) in pending_specializations.drain() { for (name, mut by_layout) in pending_specializations.drain() {
for (layout, pending) in by_layout.drain() { for (layout, pending) in by_layout.drain() {
// TODO should pending_procs hold a Rc<Proc>? // If we've already seen this (Symbol, Layout) combination before,
let partial_proc = procs // don't try to specialize it again. If we do, we'll loop forever!
.partial_procs if !answer.contains_key(&(name, layout.clone())) {
.get(&name) // TODO should pending_procs hold a Rc<Proc>?
.unwrap_or_else(|| panic!("Could not find partial_proc for {:?}", name)) let partial_proc = procs
.clone(); .partial_procs
.get(&name)
.unwrap_or_else(|| panic!("Could not find partial_proc for {:?}", name))
.clone();
match specialize(env, &mut procs, name, layout_cache, pending, partial_proc) { match specialize(env, &mut procs, name, layout_cache, pending, partial_proc) {
Ok(proc) => { Ok(proc) => {
answer.push((name, layout, proc)); answer.insert((name, layout), proc);
} }
Err(()) => { Err(()) => {
runtime_errors.insert(name); runtime_errors.insert(name);
}
} }
} }
} }