//! 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 rustc_hir::limit::Limit; use rustc_hir::{Attribute, find_attr}; use rustc_middle::query::Providers; use rustc_session::{Limits, Session}; pub(crate) fn provide(providers: &mut Providers) { providers.limits = |tcx, ()| { let attrs = tcx.hir_krate_attrs(); Limits { recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess), move_size_limit: find_attr!(attrs, MoveSizeLimit { limit, .. } => *limit) .unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))), type_length_limit: find_attr!(attrs, TypeLengthLimit { limit, .. } => *limit) .unwrap_or(Limit::new(2usize.pow(24))), pattern_complexity_limit: find_attr!(attrs, PatternComplexityLimit { limit, .. } => *limit) .unwrap_or(Limit::unlimited()), } } } // This one is separate because it must be read prior to macro expansion. pub(crate) fn get_recursion_limit(attrs: &[Attribute], sess: &Session) -> Limit { let limit_from_crate = find_attr!(attrs, RecursionLimit { limit, .. } => limit.0).unwrap_or(128); Limit::new( sess.opts .unstable_opts .min_recursion_limit .map_or(limit_from_crate, |min| min.max(limit_from_crate)), ) }