Limit recursion depth for macro expansions, closes #17628

This commit is contained in:
Florian Hahn
2014-10-01 11:38:54 +02:00
parent 60e7317345
commit 49e976d771
4 changed files with 35 additions and 0 deletions

View File

@@ -463,6 +463,7 @@ pub struct ExtCtxt<'a> {
pub exported_macros: Vec<P<ast::Item>>,
pub syntax_env: SyntaxEnv,
pub recursion_count: uint,
}
impl<'a> ExtCtxt<'a> {
@@ -478,6 +479,7 @@ impl<'a> ExtCtxt<'a> {
trace_mac: false,
exported_macros: Vec::new(),
syntax_env: env,
recursion_count: 0,
}
}
@@ -552,6 +554,13 @@ impl<'a> ExtCtxt<'a> {
return v;
}
pub fn bt_push(&mut self, ei: ExpnInfo) {
self.recursion_count += 1;
if self.recursion_count > self.ecfg.recursion_limit {
self.span_fatal(ei.call_site,
format!("Recursion limit reached while expanding the macro `{}`",
ei.callee.name).as_slice());
}
let mut call_site = ei.call_site;
call_site.expn_id = self.backtrace;
self.backtrace = self.codemap().record_expansion(ExpnInfo {
@@ -563,6 +572,7 @@ impl<'a> ExtCtxt<'a> {
match self.backtrace {
NO_EXPANSION => self.bug("tried to pop without a push"),
expn_id => {
self.recursion_count -= 1;
self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| {
expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id)
});