mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Handle recursion_limit parsing errors
This commit is contained in:
parent
116dff95a3
commit
c53693d34d
@ -50,6 +50,7 @@
|
|||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(hash_raw_entry)]
|
#![feature(hash_raw_entry)]
|
||||||
|
#![feature(int_error_matching)]
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -6,26 +6,60 @@
|
|||||||
// just peeks and looks for that attribute.
|
// just peeks and looks for that attribute.
|
||||||
|
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
|
use core::num::IntErrorKind;
|
||||||
|
use rustc::bug;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use rustc_data_structures::sync::Once;
|
use rustc_data_structures::sync::Once;
|
||||||
|
|
||||||
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
|
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
|
||||||
update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 128);
|
update_limit(sess, 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.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 {
|
for attr in &krate.attrs {
|
||||||
if !attr.check_name(name) {
|
if !attr.check_name(name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = attr.value_str() {
|
if let Some(s) = attr.value_str() {
|
||||||
if let Some(n) = s.as_str().parse().ok() {
|
match s.as_str().parse() {
|
||||||
limit.set(n);
|
Ok(n) => {
|
||||||
return;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
src/test/ui/recursion_limit/empty.rs
Normal file
6
src/test/ui/recursion_limit/empty.rs
Normal 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() {}
|
10
src/test/ui/recursion_limit/empty.stderr
Normal file
10
src/test/ui/recursion_limit/empty.stderr
Normal 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
|
||||||
|
|
6
src/test/ui/recursion_limit/invalid_digit.rs
Normal file
6
src/test/ui/recursion_limit/invalid_digit.rs
Normal 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() {}
|
10
src/test/ui/recursion_limit/invalid_digit.stderr
Normal file
10
src/test/ui/recursion_limit/invalid_digit.stderr
Normal 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
|
||||||
|
|
7
src/test/ui/recursion_limit/overflow.rs
Normal file
7
src/test/ui/recursion_limit/overflow.rs
Normal 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() {}
|
10
src/test/ui/recursion_limit/overflow.stderr
Normal file
10
src/test/ui/recursion_limit/overflow.stderr
Normal 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
|
||||||
|
|
12
src/test/ui/recursion_limit/zero.rs
Normal file
12
src/test/ui/recursion_limit/zero.rs
Normal 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() {}
|
10
src/test/ui/recursion_limit/zero.stderr
Normal file
10
src/test/ui/recursion_limit/zero.stderr
Normal 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user