//! 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_data_structures::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)),
    )
}
