1 //! Registering limits, recursion_limit, type_length_limit and const_eval_limit
3 //! There are various parts of the compiler that must impose arbitrary limits
4 //! on how deeply they recurse to prevent stack overflow. Users can override
5 //! this via an attribute on the crate like `#![recursion_limit="22"]`. This pass
6 //! just peeks and looks for that attribute.
10 use rustc_data_structures::sync::OnceCell;
11 use rustc_session::{Limit, Session};
12 use rustc_span::symbol::{sym, Symbol};
14 use std::num::IntErrorKind;
16 pub fn update_limits(sess: &Session, krate: &ast::Crate) {
17 update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
18 update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
19 update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000);
25 limit: &OnceCell<Limit>,
29 for attr in &krate.attrs {
30 if !sess.check_name(attr, name) {
34 if let Some(s) = attr.value_str() {
35 match s.as_str().parse() {
37 limit.set(Limit::new(n)).unwrap();
42 sess.struct_span_err(attr.span, "`limit` must be a non-negative integer");
46 .and_then(|meta| meta.name_value_literal().cloned())
48 .unwrap_or(attr.span);
50 let error_str = match e.kind() {
51 IntErrorKind::Overflow => "`limit` is too large",
52 IntErrorKind::Empty => "`limit` must be a non-negative integer",
53 IntErrorKind::InvalidDigit => "not a valid integer",
54 IntErrorKind::Underflow => bug!("`limit` should never underflow"),
55 IntErrorKind::Zero => bug!("zero is a valid `limit`"),
56 kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
59 err.span_label(value_span, error_str);
65 limit.set(Limit::new(default)).unwrap();