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.
// We have to do this in a separate pass first,
// 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) =
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.
// We have to do this in a separate pass first,
// 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) =
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.
// We have to do this in a separate pass first,
// 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) =
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, '_>,
mut procs: Procs<'a>,
layout_cache: &mut LayoutCache<'a>,
) -> (Vec<'a, (Symbol, Layout<'a>, Proc<'a>)>, MutSet<Symbol>) {
let mut answer = Vec::with_capacity_in(procs.pending_specializations.len(), env.arena);
) -> (MutMap<(Symbol, Layout<'a>), Proc<'a>>, MutSet<Symbol>) {
let mut answer =
HashMap::with_capacity_and_hasher(procs.pending_specializations.len(), default_hasher());
let mut runtime_errors = MutSet::default();
let mut is_finished = procs.pending_specializations.is_empty();
@ -1409,6 +1410,9 @@ pub fn specialize_all<'a>(
for (name, mut by_layout) in pending_specializations.drain() {
for (layout, pending) in by_layout.drain() {
// If we've already seen this (Symbol, Layout) combination before,
// don't try to specialize it again. If we do, we'll loop forever!
if !answer.contains_key(&(name, layout.clone())) {
// TODO should pending_procs hold a Rc<Proc>?
let partial_proc = procs
.partial_procs
@ -1418,7 +1422,7 @@ pub fn specialize_all<'a>(
match specialize(env, &mut procs, name, layout_cache, pending, partial_proc) {
Ok(proc) => {
answer.push((name, layout, proc));
answer.insert((name, layout), proc);
}
Err(()) => {
runtime_errors.insert(name);
@ -1426,6 +1430,7 @@ pub fn specialize_all<'a>(
}
}
}
}
is_finished = procs.pending_specializations.is_empty();
}