From 9af23bf061ed4f3b73ef8162e8d110b785fde295 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 5 Oct 2021 14:40:51 -0700 Subject: [PATCH] Report the recursive calls when an extractor is recursive --- cranelift/isle/isle/src/sema.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/cranelift/isle/isle/src/sema.rs b/cranelift/isle/isle/src/sema.rs index 9c31016023..14062ea3f0 100644 --- a/cranelift/isle/isle/src/sema.rs +++ b/cranelift/isle/isle/src/sema.rs @@ -879,20 +879,36 @@ impl TermEnv { 'outer: for root in extractor_call_graph.keys().copied() { seen.clear(); stack.clear(); - stack.push(root); + stack.push((root, vec![root])); - while let Some(caller) = stack.pop() { - let already_seen = seen.insert(caller); - if already_seen { + while let Some((caller, path)) = stack.pop() { + let is_new = seen.insert(caller); + if is_new { + if let Some(callees) = extractor_call_graph.get(&caller) { + stack.extend(callees.iter().map(|callee| { + let mut path = path.clone(); + path.push(*callee); + (*callee, path) + })); + } + } else { let term = self.term_map[&caller]; let pos = match &self.terms[term.index()].kind { TermKind::InternalExtractor { template } => template.pos(), _ => unreachable!(), }; - tyenv.report_error(pos, "extractor definition is recursive".into()); + + let path: Vec<_> = path + .iter() + .map(|sym| tyenv.syms[sym.index()].as_str()) + .collect(); + let msg = format!( + "`{}` extractor definition is recursive: {}", + tyenv.syms[root.index()], + path.join(" -> ") + ); + tyenv.report_error(pos, msg); continue 'outer; - } else { - stack.extend(extractor_call_graph[&caller].iter().copied()); } } } @@ -957,7 +973,7 @@ impl TermEnv { pos, format!( "Constructor defined on term of improper type '{}'", - term.0 + term.0, ), ); }