Skip to content

Commit b224dfe

Browse files
committed
auto merge of #17678 : fhahn/rust/issue-17628-infinite-recursion, r=alexcrichton
This is a patch for #17628, thanks to @kmcallister for your helpful hints!
2 parents 49fcb27 + 49e976d commit b224dfe

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

src/librustc/driver/driver.rs

+1
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
291291
crate_name: crate_name.to_string(),
292292
deriving_hash_type_parameter: sess.features.borrow().default_type_params,
293293
enable_quotes: sess.features.borrow().quote,
294+
recursion_limit: sess.recursion_limit.get(),
294295
};
295296
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
296297
cfg,

src/libsyntax/ext/base.rs

+10
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ pub struct ExtCtxt<'a> {
463463
pub exported_macros: Vec<P<ast::Item>>,
464464

465465
pub syntax_env: SyntaxEnv,
466+
pub recursion_count: uint,
466467
}
467468

468469
impl<'a> ExtCtxt<'a> {
@@ -478,6 +479,7 @@ impl<'a> ExtCtxt<'a> {
478479
trace_mac: false,
479480
exported_macros: Vec::new(),
480481
syntax_env: env,
482+
recursion_count: 0,
481483
}
482484
}
483485

@@ -552,6 +554,13 @@ impl<'a> ExtCtxt<'a> {
552554
return v;
553555
}
554556
pub fn bt_push(&mut self, ei: ExpnInfo) {
557+
self.recursion_count += 1;
558+
if self.recursion_count > self.ecfg.recursion_limit {
559+
self.span_fatal(ei.call_site,
560+
format!("Recursion limit reached while expanding the macro `{}`",
561+
ei.callee.name).as_slice());
562+
}
563+
555564
let mut call_site = ei.call_site;
556565
call_site.expn_id = self.backtrace;
557566
self.backtrace = self.codemap().record_expansion(ExpnInfo {
@@ -563,6 +572,7 @@ impl<'a> ExtCtxt<'a> {
563572
match self.backtrace {
564573
NO_EXPANSION => self.bug("tried to pop without a push"),
565574
expn_id => {
575+
self.recursion_count -= 1;
566576
self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| {
567577
expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id)
568578
});

src/libsyntax/ext/expand.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ pub struct ExpansionConfig {
10691069
pub crate_name: String,
10701070
pub deriving_hash_type_parameter: bool,
10711071
pub enable_quotes: bool,
1072+
pub recursion_limit: uint,
10721073
}
10731074

10741075
impl ExpansionConfig {
@@ -1077,6 +1078,7 @@ impl ExpansionConfig {
10771078
crate_name: crate_name,
10781079
deriving_hash_type_parameter: false,
10791080
enable_quotes: false,
1081+
recursion_limit: 64,
10801082
}
10811083
}
10821084
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(macro_rules)]
12+
13+
macro_rules! recursive(
14+
() => (
15+
recursive!() //~ ERROR Recursion limit reached while expanding the macro `recursive`
16+
)
17+
)
18+
19+
fn main() {
20+
recursive!()
21+
}
22+

0 commit comments

Comments
 (0)