diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c0f7ea8df49e4..a7bfffbc38ae9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -211,10 +211,6 @@ pub fn register_plugins<'a>( }); } - sess.time("recursion_limit", || { - middle::limits::update_limits(sess, &krate); - }); - let mut lint_store = rustc_lint::new_lint_store( sess.opts.debugging_opts.no_interleave_lints, sess.unstable_options(), @@ -311,9 +307,11 @@ pub fn configure_and_expand( // Create the config for macro expansion let features = sess.features_untracked(); + let recursion_limit = + rustc_middle::middle::limits::get_recursion_limit(&krate.attrs, &sess); let cfg = rustc_expand::expand::ExpansionConfig { features: Some(&features), - recursion_limit: sess.recursion_limit(), + recursion_limit, trace_mac: sess.opts.debugging_opts.trace_macros, should_test: sess.opts.test, span_debug: sess.opts.debugging_opts.span_debug, @@ -872,6 +870,13 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { tcx.ensure().check_mod_unstable_api_usage(module); tcx.ensure().check_mod_const_bodies(module); }); + }, + { + // We force these querie to run, + // since they might not otherwise get called. + // This marks the corresponding crate-level attributes + // as used, and ensures that their values are valid. + tcx.ensure().limits(()); } ); }); diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs index 91c81c367a16f..f1c4529b8552b 100644 --- a/compiler/rustc_middle/src/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs @@ -245,6 +245,8 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { } } +impl rustc_session::HashStableContext for StableHashingContext<'a> {} + pub fn hash_stable_trait_impls<'a>( hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher, diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 601198fd0de04..c4bfd0ebb2fde 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -10,38 +10,46 @@ //! just peeks and looks for that attribute. use crate::bug; -use rustc_ast as ast; -use rustc_data_structures::sync::OnceCell; +use crate::ty; +use rustc_ast::Attribute; use rustc_session::Session; +use rustc_session::{Limit, Limits}; use rustc_span::symbol::{sym, Symbol}; use std::num::IntErrorKind; -pub fn update_limits(sess: &Session, krate: &ast::Crate) { - update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128); - update_limit(sess, krate, &sess.move_size_limit, sym::move_size_limit, 0); - update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576); - update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000); +pub fn provide(providers: &mut ty::query::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, 0), + type_length_limit: get_limit( + tcx.hir().krate_attrs(), + tcx.sess, + sym::type_length_limit, + 1048576, + ), + const_eval_limit: get_limit( + tcx.hir().krate_attrs(), + tcx.sess, + sym::const_eval_limit, + 1_000_000, + ), + } +} + +pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit { + get_limit(krate_attrs, sess, sym::recursion_limit, 128) } -fn update_limit( - sess: &Session, - krate: &ast::Crate, - limit: &OnceCell + std::fmt::Debug>, - name: Symbol, - default: usize, -) { - for attr in &krate.attrs { +fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: usize) -> Limit { + for attr in krate_attrs { if !sess.check_name(attr, name) { continue; } if let Some(s) = attr.value_str() { match s.as_str().parse() { - Ok(n) => { - limit.set(From::from(n)).unwrap(); - return; - } + Ok(n) => return Limit::new(n), Err(e) => { let mut err = sess.struct_span_err(attr.span, "`limit` must be a non-negative integer"); @@ -68,5 +76,5 @@ fn update_limit( } } } - limit.set(From::from(default)).unwrap(); + return Limit::new(default); } diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index a369e85306b36..b370ec152e8ec 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -32,3 +32,7 @@ pub mod privacy; pub mod region; pub mod resolve_lifetime; pub mod stability; + +pub fn provide(providers: &mut crate::ty::query::Providers) { + limits::provide(providers); +} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 23ee0e0506272..3db413194b313 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1712,4 +1712,8 @@ rustc_queries! { query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "conservatively checking if {:?} is privately uninhabited", key } } + + query limits(key: ()) -> Limits { + desc { "looking up limits" } + } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 257912ad57e4f..932187e15f4ab 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -53,6 +53,7 @@ use rustc_middle::ty::OpaqueTypeKey; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames}; use rustc_session::lint::{Level, Lint}; +use rustc_session::Limit; use rustc_session::Session; use rustc_span::def_id::StableCrateId; use rustc_span::source_map::MultiSpan; @@ -1569,6 +1570,22 @@ impl<'tcx> TyCtxt<'tcx> { def_kind => (def_kind.article(), def_kind.descr(def_id)), } } + + pub fn type_length_limit(self) -> Limit { + self.limits(()).type_length_limit + } + + pub fn recursion_limit(self) -> Limit { + self.limits(()).recursion_limit + } + + pub fn move_size_limit(self) -> Limit { + self.limits(()).move_size_limit + } + + pub fn const_eval_limit(self) -> Limit { + self.limits(()).const_eval_limit + } } /// A trait implemented for all `X<'a>` types that can be safely and diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 6b1ec1b0646ae..dbb5064c4f546 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -221,7 +221,7 @@ fn layout_raw<'tcx>( ty::tls::with_related_context(tcx, move |icx| { let (param_env, ty) = query.into_parts(); - if !tcx.sess.recursion_limit().value_within_limit(icx.layout_depth) { + if !tcx.recursion_limit().value_within_limit(icx.layout_depth) { tcx.sess.fatal(&format!("overflow representing the type `{}`", ty)); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7036c05a593e8..f9dad42a4b7c5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1987,6 +1987,7 @@ pub fn provide(providers: &mut ty::query::Providers) { util::provide(providers); print::provide(providers); super::util::bug::provide(providers); + super::middle::provide(providers); *providers = ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, type_uninhabited_from: inhabitedness::type_uninhabited_from, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c59394a23d044..cb326996111b7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1437,7 +1437,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { } fn print_type(mut self, ty: Ty<'tcx>) -> Result { - let type_length_limit = self.tcx.sess.type_length_limit(); + let type_length_limit = self.tcx.type_length_limit(); if type_length_limit.value_within_limit(self.printed_type_count) { self.printed_type_count += 1; self.pretty_print_type(ty) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 2ac121fec7ee0..875453bb80bb2 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -49,6 +49,7 @@ use rustc_serialize::opaque; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_session::utils::NativeLibKind; use rustc_session::CrateDisambiguator; +use rustc_session::Limits; use rustc_target::spec::PanicStrategy; use rustc_ast as ast; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 24a9cea6d2187..17acb508de35b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -206,8 +206,9 @@ impl<'tcx> TyCtxt<'tcx> { mut ty: Ty<'tcx>, normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>, ) -> Ty<'tcx> { + let recursion_limit = self.recursion_limit(); for iteration in 0.. { - if !self.sess.recursion_limit().value_within_limit(iteration) { + if !recursion_limit.value_within_limit(iteration) { return self.ty_error_with_message( DUMMY_SP, &format!("reached the recursion limit finding the struct tail for {}", ty), diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 7a7dbe50e72f9..c1c26d4e810d0 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -98,7 +98,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>( tcx, root_span, param_env, - CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), + CompileTimeInterpreter::new(tcx.const_eval_limit()), MemoryExtra { can_access_statics }, ) } @@ -300,7 +300,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx, tcx.def_span(def.did), key.param_env, - CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), + CompileTimeInterpreter::new(tcx.const_eval_limit()), // Statics (and promoteds inside statics) may access other statics, because unlike consts // they do not have to behave "as if" they were evaluated at runtime. MemoryExtra { can_access_statics: is_static }, diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index 992e32e298f8e..279f414e7fef1 100644 --- a/compiler/rustc_mir/src/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs @@ -393,7 +393,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, frame: Frame<'mir, 'tcx>, ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { // Enforce stack size limit. Add 1 because this is run before the new frame is pushed. - if !ecx.tcx.sess.recursion_limit().value_within_limit(ecx.stack().len() + 1) { + if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) { throw_exhaust!(StackFrameLimitReached) } else { Ok(frame) diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 801e4b1e47850..227abeb7e7cc7 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::layout::{self, TyAndLayout}; use rustc_middle::ty::{ self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, }; +use rustc_session::Limit; use rustc_span::{Pos, Span}; use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout}; @@ -39,6 +40,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// The virtual memory system. pub memory: Memory<'mir, 'tcx, M>, + + /// The recursion limit (cached from `tcx.recursion_limit(())`) + pub recursion_limit: Limit, } // The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread @@ -388,6 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { tcx: tcx.at(root_span), param_env, memory: Memory::new(tcx, memory_extra), + recursion_limit: tcx.recursion_limit(), } } diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 4bd431dcc6a3c..ced35d47b1102 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -200,6 +200,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFold use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; +use rustc_session::Limit; use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP}; use rustc_target::abi::Size; use smallvec::SmallVec; @@ -294,6 +295,7 @@ pub fn collect_crate_mono_items( let mut visited = MTLock::new(FxHashSet::default()); let mut inlining_map = MTLock::new(InliningMap::new()); + let recursion_limit = tcx.recursion_limit(); { let visited: MTRef<'_, _> = &mut visited; @@ -307,6 +309,7 @@ pub fn collect_crate_mono_items( dummy_spanned(root), visited, &mut recursion_depths, + recursion_limit, inlining_map, ); }); @@ -350,6 +353,7 @@ fn collect_items_rec<'tcx>( starting_point: Spanned>, visited: MTRef<'_, MTLock>>>, recursion_depths: &mut DefIdMap, + recursion_limit: Limit, inlining_map: MTRef<'_, MTLock>>, ) { if !visited.lock_mut().insert(starting_point.node) { @@ -409,8 +413,13 @@ fn collect_items_rec<'tcx>( debug_assert!(should_codegen_locally(tcx, &instance)); // Keep track of the monomorphization recursion depth - recursion_depth_reset = - Some(check_recursion_limit(tcx, instance, starting_point.span, recursion_depths)); + recursion_depth_reset = Some(check_recursion_limit( + tcx, + instance, + starting_point.span, + recursion_depths, + recursion_limit, + )); check_type_length_limit(tcx, instance); rustc_data_structures::stack::ensure_sufficient_stack(|| { @@ -455,7 +464,7 @@ fn collect_items_rec<'tcx>( record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map); for neighbour in neighbors { - collect_items_rec(tcx, neighbour, visited, recursion_depths, inlining_map); + collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map); } if let Some((def_id, depth)) = recursion_depth_reset { @@ -523,6 +532,7 @@ fn check_recursion_limit<'tcx>( instance: Instance<'tcx>, span: Span, recursion_depths: &mut DefIdMap, + recursion_limit: Limit, ) -> (DefId, usize) { let def_id = instance.def_id(); let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); @@ -539,7 +549,7 @@ fn check_recursion_limit<'tcx>( // Code that needs to instantiate the same function recursively // more than the recursion limit is assumed to be causing an // infinite expansion. - if !tcx.sess.recursion_limit().value_within_limit(adjusted_recursion_depth) { + if !recursion_limit.value_within_limit(adjusted_recursion_depth) { let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32); let error = format!("reached the recursion limit while instantiating `{}`", shrunk); let mut err = tcx.sess.struct_span_fatal(span, &error); @@ -577,7 +587,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { // which means that rustc basically hangs. // // Bail out in these cases to avoid that bad user experience. - if !tcx.sess.type_length_limit().value_within_limit(type_length) { + if !tcx.type_length_limit().value_within_limit(type_length) { let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32); let msg = format!("reached the type-length limit while instantiating `{}`", shrunk); let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg); @@ -814,7 +824,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) { self.super_operand(operand, location); - let limit = self.tcx.sess.move_size_limit(); + let limit = self.tcx.move_size_limit().0; if limit == 0 { return; } diff --git a/compiler/rustc_mir/src/transform/inline/cycle.rs b/compiler/rustc_mir/src/transform/inline/cycle.rs index 295f3ec70dc78..c9eafafff57cd 100644 --- a/compiler/rustc_mir/src/transform/inline/cycle.rs +++ b/compiler/rustc_mir/src/transform/inline/cycle.rs @@ -5,6 +5,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, subst::SubstsRef, InstanceDef, TyCtxt}; +use rustc_session::Limit; // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking // this query riddiculously often. @@ -30,7 +31,7 @@ crate fn mir_callgraph_reachable( ); #[instrument( level = "debug", - skip(tcx, param_env, target, stack, seen, recursion_limiter, caller) + skip(tcx, param_env, target, stack, seen, recursion_limiter, caller, recursion_limit) )] fn process( tcx: TyCtxt<'tcx>, @@ -40,6 +41,7 @@ crate fn mir_callgraph_reachable( stack: &mut Vec>, seen: &mut FxHashSet>, recursion_limiter: &mut FxHashMap, + recursion_limit: Limit, ) -> bool { trace!(%caller); for &(callee, substs) in tcx.mir_inliner_callees(caller.def) { @@ -96,11 +98,20 @@ crate fn mir_callgraph_reachable( if seen.insert(callee) { let recursion = recursion_limiter.entry(callee.def_id()).or_default(); trace!(?callee, recursion = *recursion); - if tcx.sess.recursion_limit().value_within_limit(*recursion) { + if recursion_limit.value_within_limit(*recursion) { *recursion += 1; stack.push(callee); let found_recursion = ensure_sufficient_stack(|| { - process(tcx, param_env, callee, target, stack, seen, recursion_limiter) + process( + tcx, + param_env, + callee, + target, + stack, + seen, + recursion_limiter, + recursion_limit, + ) }); if found_recursion { return true; @@ -122,6 +133,7 @@ crate fn mir_callgraph_reachable( &mut Vec::new(), &mut FxHashSet::default(), &mut FxHashMap::default(), + tcx.recursion_limit(), ) } diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 8d00a9a959e7a..9a82ae3fc1090 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -24,3 +24,8 @@ pub use session::*; pub mod output; pub use getopts; + +/// Requirements for a `StableHashingContext` to be used in this crate. +/// This is a hack to allow using the `HashStable_Generic` derive macro +/// instead of implementing everything in `rustc_middle`. +pub trait HashStableContext {} diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index f792e31986779..70dddfb67046a 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -22,6 +22,7 @@ use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_lint_defs::FutureBreakage; +use rustc_macros::HashStable_Generic; pub use rustc_span::crate_disambiguator::CrateDisambiguator; use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, Span}; use rustc_span::{edition::Edition, RealFileName}; @@ -66,7 +67,7 @@ pub enum CtfeBacktrace { /// New-type wrapper around `usize` for representing limits. Ensures that comparisons against /// limits are consistent throughout the compiler. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, HashStable_Generic)] pub struct Limit(pub usize); impl Limit { @@ -111,6 +112,20 @@ impl Mul for Limit { } } +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub struct Limits { + /// The maximum recursion limit for potentially infinitely recursive + /// operations such as auto-dereference and monomorphization. + pub recursion_limit: Limit, + /// The size at which the `large_assignments` lint starts + /// being emitted. + pub move_size_limit: Limit, + /// The maximum length of types during monomorphization. + pub type_length_limit: Limit, + /// The maximum blocks a const expression can evaluate. + pub const_eval_limit: Limit, +} + /// Represents the data associated with a compilation /// session for a single crate. pub struct Session { @@ -144,20 +159,6 @@ pub struct Session { lint_store: OnceCell>, - /// The maximum recursion limit for potentially infinitely recursive - /// operations such as auto-dereference and monomorphization. - pub recursion_limit: OnceCell, - - /// The size at which the `large_assignments` lint starts - /// being emitted. - pub move_size_limit: OnceCell, - - /// The maximum length of types during monomorphization. - pub type_length_limit: OnceCell, - - /// The maximum blocks a const expression can evaluate. - pub const_eval_limit: OnceCell, - incr_comp_session: OneThread>, /// Used for incremental compilation tests. Will only be populated if /// `-Zquery-dep-graph` is specified. @@ -347,25 +348,6 @@ impl Session { self.crate_types.set(crate_types).expect("`crate_types` was initialized twice") } - #[inline] - pub fn recursion_limit(&self) -> Limit { - self.recursion_limit.get().copied().unwrap() - } - - #[inline] - pub fn move_size_limit(&self) -> usize { - self.move_size_limit.get().copied().unwrap() - } - - #[inline] - pub fn type_length_limit(&self) -> Limit { - self.type_length_limit.get().copied().unwrap() - } - - pub fn const_eval_limit(&self) -> Limit { - self.const_eval_limit.get().copied().unwrap() - } - pub fn struct_span_warn>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn(sp, msg) } @@ -1391,10 +1373,6 @@ pub fn build_session( crate_disambiguator: OnceCell::new(), features: OnceCell::new(), lint_store: OnceCell::new(), - recursion_limit: OnceCell::new(), - move_size_limit: OnceCell::new(), - type_length_limit: OnceCell::new(), - const_eval_limit: OnceCell::new(), incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), cgu_reuse_tracker, prof, diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index ac2e0ebae3273..969962e55b0df 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { } // If we have reached the recursion limit, error gracefully. - if !tcx.sess.recursion_limit().value_within_limit(self.state.steps.len()) { + if !tcx.recursion_limit().value_within_limit(self.state.steps.len()) { if !self.silence_errors { report_autoderef_recursion_limit_error(tcx, self.span, self.state.cur_ty); } @@ -217,7 +217,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) { // We've reached the recursion limit, error gracefully. - let suggested_limit = tcx.sess.recursion_limit() * 2; + let suggested_limit = tcx.recursion_limit() * 2; let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", ty); let error_id = (DiagnosticMessageId::ErrorId(55), Some(span), msg); let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5c35b515f3d02..dd84a81a65121 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2310,7 +2310,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { - let current_limit = self.tcx.sess.recursion_limit(); + let current_limit = self.tcx.recursion_limit(); let suggested_limit = current_limit * 2; err.help(&format!( "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)", diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 352829234a41a..0e685205069cb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -344,7 +344,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { Reveal::UserFacing => ty, Reveal::All => { - let recursion_limit = self.tcx().sess.recursion_limit(); + let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { let obligation = Obligation::with_depth( self.cause.clone(), @@ -726,7 +726,7 @@ fn project_type<'cx, 'tcx>( ) -> Result, ProjectionTyError<'tcx>> { debug!(?obligation, "project_type"); - if !selcx.tcx().sess.recursion_limit().value_within_limit(obligation.recursion_depth) { + if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) { debug!("project: overflow!"); // This should really be an immediate error, but some existing code // relies on being able to recover from this. diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index eb7ea8715c297..6673e021bf308 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -116,7 +116,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { Reveal::UserFacing => ty, Reveal::All => { - let recursion_limit = self.tcx().sess.recursion_limit(); + let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.anon_depth) { let obligation = Obligation::with_depth( self.cause.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6cecff4b89d9d..708688fa8a69d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -993,7 +993,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, ) -> Result<(), OverflowError> { - if !self.infcx.tcx.sess.recursion_limit().value_within_limit(obligation.recursion_depth) { + if !self.infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) { match self.query_mode { TraitQueryMode::Standard => { self.infcx().report_overflow_error(error_obligation, true); diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 9d5b9d7357fc4..4a41dfe01431e 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -163,7 +163,7 @@ fn dtorck_constraint_for_ty<'tcx>( ) -> Result<(), NoSolution> { debug!("dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", span, for_ty, depth, ty); - if !tcx.sess.recursion_limit().value_within_limit(depth) { + if !tcx.recursion_limit().value_within_limit(depth) { constraints.overflows.push(ty); return Ok(()); } diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index bc8f10e15db8c..d837af85d58ae 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -63,7 +63,7 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> { seen_tys, query_ty: ty, unchecked_tys: vec![(ty, 0)], - recursion_limit: tcx.sess.recursion_limit(), + recursion_limit: tcx.recursion_limit(), adt_components, } } diff --git a/src/test/ui/recursion_limit/empty.rs b/src/test/ui/recursion_limit/empty.rs index 31ff9c1e3a72e..59dae106c0001 100644 --- a/src/test/ui/recursion_limit/empty.rs +++ b/src/test/ui/recursion_limit/empty.rs @@ -2,5 +2,7 @@ #![recursion_limit = ""] //~ ERROR `limit` must be a non-negative integer //~| `limit` must be a non-negative integer + //~| ERROR `limit` must be a non-negative integer + //~| `limit` must be a non-negative integer fn main() {} diff --git a/src/test/ui/recursion_limit/empty.stderr b/src/test/ui/recursion_limit/empty.stderr index bcd1d27e59b56..cb5c0c35a5ebf 100644 --- a/src/test/ui/recursion_limit/empty.stderr +++ b/src/test/ui/recursion_limit/empty.stderr @@ -6,5 +6,13 @@ LL | #![recursion_limit = ""] | | | `limit` must be a non-negative integer -error: aborting due to previous error +error: `limit` must be a non-negative integer + --> $DIR/empty.rs:3:1 + | +LL | #![recursion_limit = ""] + | ^^^^^^^^^^^^^^^^^^^^^--^ + | | + | `limit` must be a non-negative integer + +error: aborting due to 2 previous errors diff --git a/src/test/ui/recursion_limit/invalid_digit.rs b/src/test/ui/recursion_limit/invalid_digit.rs index 759d69d0af20d..03df3e7a92713 100644 --- a/src/test/ui/recursion_limit/invalid_digit.rs +++ b/src/test/ui/recursion_limit/invalid_digit.rs @@ -2,5 +2,6 @@ #![recursion_limit = "-100"] //~ ERROR `limit` must be a non-negative integer //~| not a valid integer - + //~| ERROR `limit` must be a non-negative integer + //~| not a valid integer fn main() {} diff --git a/src/test/ui/recursion_limit/invalid_digit.stderr b/src/test/ui/recursion_limit/invalid_digit.stderr index e6fd6b72a0900..4dc93ad5f67b3 100644 --- a/src/test/ui/recursion_limit/invalid_digit.stderr +++ b/src/test/ui/recursion_limit/invalid_digit.stderr @@ -6,5 +6,13 @@ LL | #![recursion_limit = "-100"] | | | not a valid integer -error: aborting due to previous error +error: `limit` must be a non-negative integer + --> $DIR/invalid_digit.rs:3:1 + | +LL | #![recursion_limit = "-100"] + | ^^^^^^^^^^^^^^^^^^^^^------^ + | | + | not a valid integer + +error: aborting due to 2 previous errors diff --git a/src/test/ui/recursion_limit/overflow.rs b/src/test/ui/recursion_limit/overflow.rs index 8eee2792b2383..c733ba6b93ce5 100644 --- a/src/test/ui/recursion_limit/overflow.rs +++ b/src/test/ui/recursion_limit/overflow.rs @@ -3,5 +3,7 @@ #![recursion_limit = "999999999999999999999999"] //~^ ERROR `limit` must be a non-negative integer //~| `limit` is too large +//~| ERROR `limit` must be a non-negative integer +//~| `limit` is too large fn main() {} diff --git a/src/test/ui/recursion_limit/overflow.stderr b/src/test/ui/recursion_limit/overflow.stderr index f6ed76c1ebc0e..2f622d28b45a1 100644 --- a/src/test/ui/recursion_limit/overflow.stderr +++ b/src/test/ui/recursion_limit/overflow.stderr @@ -6,5 +6,13 @@ LL | #![recursion_limit = "999999999999999999999999"] | | | `limit` is too large -error: aborting due to previous error +error: `limit` must be a non-negative integer + --> $DIR/overflow.rs:3:1 + | +LL | #![recursion_limit = "999999999999999999999999"] + | ^^^^^^^^^^^^^^^^^^^^^--------------------------^ + | | + | `limit` is too large + +error: aborting due to 2 previous errors