Report the recursive calls when an extractor is recursive
This commit is contained in:
committed by
Chris Fallin
parent
31d1cf3808
commit
9af23bf061
@@ -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,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user