Move rustc_middle::limits
to rustc_interface
.
It's always good to make `rustc_middle` smaller. `rustc_interface` is the best destination, because it's the only crate that calls `get_recursive_limit`.
This commit is contained in:
parent
13280eed6a
commit
223c95fd59
9 changed files with 23 additions and 26 deletions
|
@ -127,3 +127,13 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
|
|||
pub feature: &'a str,
|
||||
pub enabled: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(interface_limit_invalid)]
|
||||
pub(crate) struct LimitInvalid<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub value_span: Span,
|
||||
pub error_str: &'a str,
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
mod callbacks;
|
||||
pub mod errors;
|
||||
pub mod interface;
|
||||
mod limits;
|
||||
pub mod passes;
|
||||
mod proc_macro_decls;
|
||||
mod queries;
|
||||
|
|
85
compiler/rustc_interface/src/limits.rs
Normal file
85
compiler/rustc_interface/src/limits.rs
Normal file
|
@ -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::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
|
||||
}
|
|
@ -39,7 +39,7 @@ use rustc_trait_selection::traits;
|
|||
use tracing::{info, instrument};
|
||||
|
||||
use crate::interface::Compiler;
|
||||
use crate::{errors, proc_macro_decls, util};
|
||||
use crate::{errors, limits, proc_macro_decls, util};
|
||||
|
||||
pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
|
||||
let krate = sess
|
||||
|
@ -687,6 +687,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
|
|||
|tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal());
|
||||
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
|
||||
providers.early_lint_checks = early_lint_checks;
|
||||
limits::provide(providers);
|
||||
proc_macro_decls::provide(providers);
|
||||
rustc_const_eval::provide(providers);
|
||||
rustc_middle::hir::provide(providers);
|
||||
|
@ -1134,7 +1135,7 @@ fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit
|
|||
// because that would require expanding this while in the middle of expansion, which needs to
|
||||
// know the limit before expanding.
|
||||
let _ = validate_and_find_value_str_builtin_attr(sym::recursion_limit, sess, krate_attrs);
|
||||
rustc_middle::middle::limits::get_recursion_limit(krate_attrs, sess)
|
||||
crate::limits::get_recursion_limit(krate_attrs, sess)
|
||||
}
|
||||
|
||||
/// Validate *all* occurrences of the given "[value-str]" built-in attribute and return the first find.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue