Fix a panic when checking the call graph for an extractor with type errors in its definition
This commit is contained in:
committed by
Chris Fallin
parent
9af23bf061
commit
fddff6ee2d
@@ -128,10 +128,10 @@ impl Pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call `f` for each of the terms in this pattern.
|
/// Call `f` for each of the terms in this pattern.
|
||||||
pub fn terms(&self, f: &mut dyn FnMut(&Ident)) {
|
pub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident)) {
|
||||||
match self {
|
match self {
|
||||||
Pattern::Term { sym, args, .. } => {
|
Pattern::Term { sym, args, pos } => {
|
||||||
f(sym);
|
f(*pos, sym);
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if let TermArgPattern::Pattern(p) = arg {
|
if let TermArgPattern::Pattern(p) = arg {
|
||||||
p.terms(f);
|
p.terms(f);
|
||||||
|
|||||||
@@ -847,17 +847,29 @@ impl TermEnv {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let termdata = &mut self.terms[term.index()];
|
|
||||||
let template = ext.template.make_macro_template(&ext.args[..]);
|
let template = ext.template.make_macro_template(&ext.args[..]);
|
||||||
log::trace!("extractor def: {:?} becomes template {:?}", def, template);
|
log::trace!("extractor def: {:?} becomes template {:?}", def, template);
|
||||||
|
|
||||||
let mut callees = HashSet::new();
|
let mut callees = HashSet::new();
|
||||||
template.terms(&mut |t| {
|
template.terms(&mut |pos, t| {
|
||||||
let t = tyenv.intern_mut(t);
|
let t = tyenv.intern_mut(t);
|
||||||
callees.insert(t);
|
callees.insert(t);
|
||||||
|
|
||||||
|
if !self.term_map.contains_key(&t) {
|
||||||
|
tyenv.report_error(
|
||||||
|
pos,
|
||||||
|
format!(
|
||||||
|
"`{}` extractor definition references unknown term `{}`",
|
||||||
|
ext.term.0,
|
||||||
|
tyenv.syms[t.index()]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
extractor_call_graph.insert(sym, callees);
|
extractor_call_graph.insert(sym, callees);
|
||||||
|
|
||||||
|
let termdata = &mut self.terms[term.index()];
|
||||||
match &termdata.kind {
|
match &termdata.kind {
|
||||||
&TermKind::Declared => {
|
&TermKind::Declared => {
|
||||||
termdata.kind = TermKind::InternalExtractor { template };
|
termdata.kind = TermKind::InternalExtractor { template };
|
||||||
@@ -892,7 +904,15 @@ impl TermEnv {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let term = self.term_map[&caller];
|
let term = match self.term_map.get(&caller) {
|
||||||
|
Some(t) => t,
|
||||||
|
None => {
|
||||||
|
// Some other error must have already been recorded
|
||||||
|
// if we don't have the caller's term data.
|
||||||
|
assert!(!tyenv.errors.is_empty());
|
||||||
|
continue 'outer;
|
||||||
|
}
|
||||||
|
};
|
||||||
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!(),
|
||||||
|
|||||||
Reference in New Issue
Block a user