diff options
| author | bors <bors@rust-lang.org> | 2025-02-17 08:10:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-02-17 08:10:13 +0000 |
| commit | 273465e1f2932a30a5b56ac95859cdc86f3f33fa (patch) | |
| tree | 435096c3bce1ea5e5d7cc7c35c95c2d1cd3a2a49 /compiler/rustc_interface/src/limits.rs | |
| parent | d5eb31c9347ae3c494c8d723711dacca7d1cfe8b (diff) | |
| parent | f0710999a969d6810234066d58e40bfd7c232c7b (diff) | |
| download | rust-273465e1f2932a30a5b56ac95859cdc86f3f33fa.tar.gz rust-273465e1f2932a30a5b56ac95859cdc86f3f33fa.zip | |
Auto merge of #137163 - matthiaskrgr:rollup-ovgfkns, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #136466 (Start removing `rustc_middle::hir::map::Map`) - #136671 (Overhaul `rustc_middle::limits`) - #136817 (Pattern Migration 2024: clean up and comment) - #136844 (Use `const_error!` when possible) - #137080 (bootstrap: add more tracing to compiler/std/llvm flows) - #137101 (`invalid_from_utf8[_unchecked]`: also lint inherent methods) - #137140 (Fix const items not being allowed to be called `r#move` or `r#static`) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_interface/src/limits.rs')
| -rw-r--r-- | compiler/rustc_interface/src/limits.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs new file mode 100644 index 00000000000..3de513797e3 --- /dev/null +++ b/compiler/rustc_interface/src/limits.rs @@ -0,0 +1,85 @@ +//! 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 +} |
