Change:
The following code since it exceeds the default recursion limit. Using as the recursion limit works as expected. This is because we don't check for integer overflow errors when parsing limits: There's a few options here. My preference would be to silently default to when overflow occurs. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
Hi! I'd like to try and handle this. If I understand this correctly, we should check if there is an , and if that error is an overflow. If it's an overflow, we default to ? claim
correct

Discussion:
#![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(hash_raw_entry)] <ins> #![feature(int_error_matching)] </ins> #![recursion_limit = "512"] #[macro_use]

// just peeks and looks for that attribute. use crate::session::Session; <ins> use core::num::IntErrorKind; use rustc::bug; </ins> use rustc_span::symbol::{sym, Symbol}; use syntax::ast; use rustc_data_structures::sync::Once; pub fn update_limits(sess: &Session, krate: &ast::Crate) { <del> update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 128); update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576); </del> <ins> update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128); update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576); </ins> } <del> fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize) { </del> <ins> fn update_limit( sess: &Session, krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize, ) { </ins> for attr in &krate.attrs { if !attr.check_name(name) { continue; } if let Some(s) = attr.value_str() { <del> if let Some(n) = s.as_str().parse().ok() { limit.set(n); return; </del> <ins> match s.as_str().parse() { Ok(n) => { limit.set(n); return; } Err(e) => { let mut err = sess.struct_span_err( attr.span, "`recursion_limit` must be a non-negative integer", ); let value_span = attr .meta() .and_then(|meta| meta.name_value_literal().cloned()) .map(|lit| lit.span) .unwrap_or(attr.span); let error_str = match e.kind() { IntErrorKind::Overflow => "`recursion_limit` is too large", IntErrorKind::Empty => "`recursion_limit` must be a non-negative integer", IntErrorKind::InvalidDigit => "not a valid integer", IntErrorKind::Underflow => bug!("`recursion_limit` should never underflow"), IntErrorKind::Zero => bug!("zero is a valid `recursion_limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; err.span_label(value_span, error_str); err.emit(); } </ins> } } }

<ins> // Test the parse error for an empty recursion_limit #![recursion_limit = ""] //~ ERROR `recursion_limit` must be a non-negative integer //~| `recursion_limit` must be a non-negative integer fn main() {} </ins>

<ins> error: `recursion_limit` must be a non-negative integer --> $DIR/empty.rs:3:1 | LL | #![recursion_limit = ""] | ^^^^^^^^^^^^^^^^^^^^^--^ |                      | |                      `recursion_limit` must be a non-negative integer error: aborting due to previous error </ins>

<ins> // Test the parse error for an invalid digit in recursion_limit #![recursion_limit = "-100"] //~ ERROR `recursion_limit` must be a non-negative integer //~| not a valid integer fn main() {} </ins>

<ins> error: `recursion_limit` must be a non-negative integer --> $DIR/invalid_digit.rs:3:1 | LL | #![recursion_limit = "-100"] | ^^^^^^^^^^^^^^^^^^^^^------^ |                      | |                      not a valid integer error: aborting due to previous error </ins>

<ins> // Test the parse error for an overflowing recursion_limit #![recursion_limit = "999999999999999999999999"] //~^ ERROR `recursion_limit` must be a non-negative integer //~| `recursion_limit` is too large fn main() {} </ins>

<ins> error: `recursion_limit` must be a non-negative integer --> $DIR/overflow.rs:3:1 | LL | #![recursion_limit = "999999999999999999999999"] | ^^^^^^^^^^^^^^^^^^^^^--------------------------^ |                      | |                      `recursion_limit` is too large error: aborting due to previous error </ins>

<ins> // Test that a `recursion_limit` of 0 is valid #![recursion_limit = "0"] macro_rules! test { () => {}; ($tt:tt) => { test!(); }; } test!(test); //~ ERROR 10:1: 10:13: recursion limit reached while expanding `test!` fn main() {} </ins>

<ins> error: recursion limit reached while expanding `test!` --> $DIR/zero.rs:10:1 | LL | test!(test); | ^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="0"]` attribute to your crate (`zero`) error: aborting due to previous error </ins>