2021-03-26 16:28:52 +00:00
|
|
|
//! Registering limits:
|
|
|
|
//! * recursion_limit,
|
2022-11-02 11:57:40 +00:00
|
|
|
//! * move_size_limit, and
|
|
|
|
//! * type_length_limit
|
2019-12-13 08:38:07 +00:00
|
|
|
//!
|
|
|
|
//! There are various parts of the compiler that must impose arbitrary limits
|
|
|
|
//! on how deeply they recurse to prevent stack overflow. Users can override
|
|
|
|
//! this via an attribute on the crate like `#![recursion_limit="22"]`. This pass
|
|
|
|
//! just peeks and looks for that attribute.
|
2014-12-02 17:57:38 +00:00
|
|
|
|
2022-09-01 14:09:45 +00:00
|
|
|
use std::num::IntErrorKind;
|
2024-07-28 22:13:50 +00:00
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
use rustc_ast::attr::AttributeExt;
|
2021-07-04 18:02:51 +00:00
|
|
|
use rustc_session::{Limit, Limits, Session};
|
2024-12-12 23:29:23 +00:00
|
|
|
use rustc_span::{Symbol, sym};
|
2014-12-02 17:57:38 +00:00
|
|
|
|
2020-03-11 11:49:08 +00:00
|
|
|
use crate::error::LimitInvalid;
|
2023-05-15 04:24:45 +00:00
|
|
|
use crate::query::Providers;
|
2016-11-15 21:25:59 +00:00
|
|
|
|
2023-05-15 04:24:45 +00:00
|
|
|
pub fn provide(providers: &mut Providers) {
|
2021-07-04 18:02:51 +00:00
|
|
|
providers.limits = |tcx, ()| Limits {
|
|
|
|
recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
|
2021-06-19 00:00:00 +00:00
|
|
|
move_size_limit: get_limit(
|
|
|
|
tcx.hir().krate_attrs(),
|
|
|
|
tcx.sess,
|
|
|
|
sym::move_size_limit,
|
2022-07-06 12:44:47 +00:00
|
|
|
tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0),
|
2021-06-19 00:00:00 +00:00
|
|
|
),
|
2021-07-04 18:02:51 +00:00
|
|
|
type_length_limit: get_limit(
|
|
|
|
tcx.hir().krate_attrs(),
|
|
|
|
tcx.sess,
|
|
|
|
sym::type_length_limit,
|
2024-05-24 18:09:40 +00:00
|
|
|
2usize.pow(24),
|
2021-07-04 18:02:51 +00:00
|
|
|
),
|
|
|
|
}
|
2016-11-15 21:25:59 +00:00
|
|
|
}
|
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
pub fn get_recursion_limit(krate_attrs: &[impl AttributeExt], sess: &Session) -> Limit {
|
2021-06-25 23:48:26 +00:00
|
|
|
get_limit(krate_attrs, sess, sym::recursion_limit, 128)
|
|
|
|
}
|
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
fn get_limit(
|
|
|
|
krate_attrs: &[impl AttributeExt],
|
|
|
|
sess: &Session,
|
|
|
|
name: Symbol,
|
|
|
|
default: usize,
|
|
|
|
) -> Limit {
|
2024-03-02 21:48:41 +00:00
|
|
|
match get_limit_size(krate_attrs, sess, name) {
|
|
|
|
Some(size) => Limit::new(size),
|
|
|
|
None => Limit::new(default),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
pub fn get_limit_size(
|
|
|
|
krate_attrs: &[impl AttributeExt],
|
|
|
|
sess: &Session,
|
|
|
|
name: Symbol,
|
|
|
|
) -> Option<usize> {
|
2021-06-25 23:48:26 +00:00
|
|
|
for attr in krate_attrs {
|
2021-07-29 17:00:41 +00:00
|
|
|
if !attr.has_name(name) {
|
2014-12-02 17:57:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
if let Some(sym) = attr.value_str() {
|
|
|
|
match sym.as_str().parse() {
|
2024-03-02 21:48:41 +00:00
|
|
|
Ok(n) => return Some(n),
|
2019-12-13 04:18:21 +00:00
|
|
|
Err(e) => {
|
|
|
|
let error_str = match e.kind() {
|
2020-10-06 13:06:25 +00:00
|
|
|
IntErrorKind::PosOverflow => "`limit` is too large",
|
2020-10-06 21:42:33 +00:00
|
|
|
IntErrorKind::Empty => "`limit` must be a non-negative integer",
|
2020-10-26 18:14:12 +00:00
|
|
|
IntErrorKind::InvalidDigit => "not a valid integer",
|
|
|
|
IntErrorKind::NegOverflow => {
|
2020-10-26 18:16:25 +00:00
|
|
|
bug!("`limit` should never negatively overflow")
|
2020-10-26 18:14:12 +00:00
|
|
|
}
|
2020-02-19 09:24:16 +00:00
|
|
|
IntErrorKind::Zero => bug!("zero is a valid `limit`"),
|
2019-12-13 04:18:21 +00:00
|
|
|
kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
|
|
|
|
};
|
2024-10-16 23:14:01 +00:00
|
|
|
sess.dcx().emit_err(LimitInvalid {
|
|
|
|
span: attr.span(),
|
|
|
|
value_span: attr.value_span().unwrap(),
|
|
|
|
error_str,
|
|
|
|
});
|
2019-12-13 04:18:21 +00:00
|
|
|
}
|
2014-12-02 17:57:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-03-02 21:48:41 +00:00
|
|
|
None
|
2014-12-02 17:57:38 +00:00
|
|
|
}
|