diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-12-02 12:57:38 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-12-08 15:51:38 -0500 |
| commit | 87edbea9da1d7dfd7e8c68e15f846f08d5f3a8c0 (patch) | |
| tree | 6292fe21bf40e35ba3509ce7317790a8e0934bac | |
| parent | 2e996ffb46d4f9e58d111d7e0de21602ac92411f (diff) | |
| download | rust-87edbea9da1d7dfd7e8c68e15f846f08d5f3a8c0.tar.gz rust-87edbea9da1d7dfd7e8c68e15f846f08d5f3a8c0.zip | |
Add ability to configure recursion limit.
Fixes #19318.
| -rw-r--r-- | src/librustc/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/recursion_limit.rs | 39 | ||||
| -rw-r--r-- | src/librustc_driver/driver.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/recursion_limit.rs | 47 |
4 files changed, 91 insertions, 0 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index a964609e4e6..2af6a487629 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -88,6 +88,7 @@ pub mod middle { pub mod privacy; pub mod reachable; pub mod region; + pub mod recursion_limit; pub mod resolve; pub mod resolve_lifetime; pub mod stability; diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs new file mode 100644 index 00000000000..a6a6703353c --- /dev/null +++ b/src/librustc/middle/recursion_limit.rs @@ -0,0 +1,39 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Recursion limit. +// +// There are various parts of the compiler that must impose arbitrary limits +// on how deeply they recurse to prevent stack overflow. Users can override +// this via an attribute on the crate like `#![recursion_limit(22)]`. This pass +// just peeks and looks for that attribute. + +use session::Session; +use syntax::ast; +use syntax::attr::AttrMetaMethods; +use std::str::FromStr; + +pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) { + for attr in krate.attrs.iter() { + if !attr.check_name("recursion_limit") { + continue; + } + + if let Some(s) = attr.value_str() { + if let Some(n) = FromStr::from_str(s.get()) { + sess.recursion_limit.set(n); + return; + } + } + + sess.span_err(attr.span, "malformed recursion limit attribute, \ + expected #![recursion_limit(\"N\")]"); + } +} diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f3d76a8f12f..749bed15e38 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -180,6 +180,10 @@ pub fn phase_2_configure_and_expand(sess: &Session, *sess.features.borrow_mut() = features; }); + time(time_passes, "recursion limit", (), |_| { + middle::recursion_limit::update_recursion_limit(sess, &krate); + }); + // strip before expansion to allow macros to depend on // configuration variables e.g/ in // diff --git a/src/test/compile-fail/recursion_limit.rs b/src/test/compile-fail/recursion_limit.rs new file mode 100644 index 00000000000..35713f7cfa2 --- /dev/null +++ b/src/test/compile-fail/recursion_limit.rs @@ -0,0 +1,47 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the recursion limit can be changed. In this case, we have +// deeply nested types that will fail the `Send` check by overflow +// when the recursion limit is set very low. + +#![feature(macro_rules)] +#![allow(dead_code)] +#![recursion_limit="10"] + +macro_rules! link { + ($id:ident, $t:ty) => { + enum $id { $id($t) } + } +} + +link!(A,B) +link!(B,C) +link!(C,D) +link!(D,E) +link!(E,F) +link!(F,G) +link!(G,H) +link!(H,I) +link!(I,J) +link!(J,K) +link!(K,L) +link!(L,M) +link!(M,N) + +enum N { N(uint) } + +fn is_send<T:Send>() { } + +fn main() { + is_send::<A>(); + //~^ ERROR not implemented + //~^^ ERROR not implemented +} |
