mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00

Continuing the work started in #136466. Every method gains a `hir_` prefix, though for the ones that already have a `par_` or `try_par_` prefix I added the `hir_` after that.
86 lines
2.9 KiB
Rust
86 lines
2.9 KiB
Rust
//! Registering limits:
|
|
//! - recursion_limit: there are various parts of the compiler that must impose arbitrary limits
|
|
//! on how deeply they recurse to prevent stack overflow.
|
|
//! - move_size_limit
|
|
//! - type_length_limit
|
|
//! - pattern_complexity_limit
|
|
//!
|
|
//! Users can override these limits via an attribute on the crate like
|
|
//! `#![recursion_limit="22"]`. This pass just looks for those attributes.
|
|
|
|
use std::num::IntErrorKind;
|
|
|
|
use rustc_ast::attr::AttributeExt;
|
|
use rustc_middle::bug;
|
|
use rustc_middle::query::Providers;
|
|
use rustc_session::{Limit, Limits, Session};
|
|
use rustc_span::{Symbol, sym};
|
|
|
|
use crate::errors::LimitInvalid;
|
|
|
|
pub(crate) fn provide(providers: &mut Providers) {
|
|
providers.limits = |tcx, ()| Limits {
|
|
recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess),
|
|
move_size_limit: get_limit(
|
|
tcx.hir_krate_attrs(),
|
|
tcx.sess,
|
|
sym::move_size_limit,
|
|
Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0)),
|
|
),
|
|
type_length_limit: get_limit(
|
|
tcx.hir_krate_attrs(),
|
|
tcx.sess,
|
|
sym::type_length_limit,
|
|
Limit::new(2usize.pow(24)),
|
|
),
|
|
pattern_complexity_limit: get_limit(
|
|
tcx.hir_krate_attrs(),
|
|
tcx.sess,
|
|
sym::pattern_complexity_limit,
|
|
Limit::unlimited(),
|
|
),
|
|
}
|
|
}
|
|
|
|
// This one is separate because it must be read prior to macro expansion.
|
|
pub(crate) fn get_recursion_limit(krate_attrs: &[impl AttributeExt], sess: &Session) -> Limit {
|
|
get_limit(krate_attrs, sess, sym::recursion_limit, Limit::new(128))
|
|
}
|
|
|
|
fn get_limit(
|
|
krate_attrs: &[impl AttributeExt],
|
|
sess: &Session,
|
|
name: Symbol,
|
|
default: Limit,
|
|
) -> Limit {
|
|
for attr in krate_attrs {
|
|
if !attr.has_name(name) {
|
|
continue;
|
|
}
|
|
|
|
if let Some(sym) = attr.value_str() {
|
|
match sym.as_str().parse() {
|
|
Ok(n) => return Limit::new(n),
|
|
Err(e) => {
|
|
let error_str = match e.kind() {
|
|
IntErrorKind::PosOverflow => "`limit` is too large",
|
|
IntErrorKind::Empty => "`limit` must be a non-negative integer",
|
|
IntErrorKind::InvalidDigit => "not a valid integer",
|
|
IntErrorKind::NegOverflow => {
|
|
bug!("`limit` should never negatively overflow")
|
|
}
|
|
IntErrorKind::Zero => bug!("zero is a valid `limit`"),
|
|
kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
|
|
};
|
|
sess.dcx().emit_err(LimitInvalid {
|
|
span: attr.span(),
|
|
value_span: attr.value_span().unwrap(),
|
|
error_str,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
default
|
|
}
|