Report the recursive calls when an extractor is recursive

This commit is contained in:
Nick Fitzgerald
2021-10-05 14:40:51 -07:00
committed by Chris Fallin
parent 31d1cf3808
commit 9af23bf061

View File

@@ -879,20 +879,36 @@ impl TermEnv {
'outer: for root in extractor_call_graph.keys().copied() { 'outer: for root in extractor_call_graph.keys().copied() {
seen.clear(); seen.clear();
stack.clear(); stack.clear();
stack.push(root); stack.push((root, vec![root]));
while let Some(caller) = stack.pop() { while let Some((caller, path)) = stack.pop() {
let already_seen = seen.insert(caller); let is_new = seen.insert(caller);
if already_seen { 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 term = self.term_map[&caller];
let pos = match &self.terms[term.index()].kind { let pos = match &self.terms[term.index()].kind {
TermKind::InternalExtractor { template } => template.pos(), TermKind::InternalExtractor { template } => template.pos(),
_ => unreachable!(), _ => 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; continue 'outer;
} else {
stack.extend(extractor_call_graph[&caller].iter().copied());
} }
} }
} }
@@ -957,7 +973,7 @@ impl TermEnv {
pos, pos,
format!( format!(
"Constructor defined on term of improper type '{}'", "Constructor defined on term of improper type '{}'",
term.0 term.0,
), ),
); );
} }