Handle recursion_limit parsing errors

This commit is contained in:
Fisher Darling 2019-12-12 21:18:21 -07:00 committed by Fisher Darling
parent 116dff95a3
commit c53693d34d
10 changed files with 112 additions and 6 deletions

View File

@ -50,6 +50,7 @@
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(hash_raw_entry)]
#![feature(int_error_matching)]
#![recursion_limit = "512"]
#[macro_use]

View File

@ -6,26 +6,60 @@
// just peeks and looks for that attribute.
use crate::session::Session;
use core::num::IntErrorKind;
use rustc::bug;
use rustc_span::symbol::{sym, Symbol};
use syntax::ast;
use rustc_data_structures::sync::Once;
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 128);
update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
}
fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize) {
fn update_limit(
sess: &Session,
krate: &ast::Crate,
limit: &Once<usize>,
name: Symbol,
default: usize,
) {
for attr in &krate.attrs {
if !attr.check_name(name) {
continue;
}
if let Some(s) = attr.value_str() {
if let Some(n) = s.as_str().parse().ok() {
limit.set(n);
return;
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();
}
}
}
}

View File

@ -0,0 +1,6 @@
// 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() {}

View File

@ -0,0 +1,10 @@
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

View File

@ -0,0 +1,6 @@
// 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() {}

View File

@ -0,0 +1,10 @@
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

View File

@ -0,0 +1,7 @@
// 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() {}

View File

@ -0,0 +1,10 @@
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

View File

@ -0,0 +1,12 @@
// 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() {}

View File

@ -0,0 +1,10 @@
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