Skip to main content

rustc_interface/
limits.rs

1//! Registering limits:
2//! - recursion_limit: there are various parts of the compiler that must impose arbitrary limits
3//!   on how deeply they recurse to prevent stack overflow.
4//! - move_size_limit
5//! - type_length_limit
6//! - pattern_complexity_limit
7//!
8//! Users can override these limits via an attribute on the crate like
9//! `#![recursion_limit="22"]`. This pass just looks for those attributes.
10
11use rustc_hir::limit::Limit;
12use rustc_hir::{Attribute, find_attr};
13use rustc_middle::query::Providers;
14use rustc_session::Limits;
15
16pub(crate) fn provide(providers: &mut Providers) {
17    providers.limits = |tcx, ()| {
18        let attrs = tcx.hir_krate_attrs();
19        Limits {
20            recursion_limit: get_recursion_limit(tcx.hir_krate_attrs()),
21            move_size_limit: {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(MoveSizeLimit { limit, .. }) => {
                    break 'done Some(*limit);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, MoveSizeLimit { limit, .. } => *limit)
22                .unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))),
23            type_length_limit: {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(TypeLengthLimit { limit, .. }) =>
                    {
                    break 'done Some(*limit);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, TypeLengthLimit { limit, .. } => *limit)
24                .unwrap_or(Limit::new(2usize.pow(24))),
25            pattern_complexity_limit:
26                {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(PatternComplexityLimit { limit,
                    .. }) => {
                    break 'done Some(*limit);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, PatternComplexityLimit { limit, .. } => *limit)
27                    .unwrap_or(Limit::unlimited()),
28        }
29    }
30}
31
32// This one is separate because it must be read prior to macro expansion.
33pub(crate) fn get_recursion_limit(attrs: &[Attribute]) -> Limit {
34    {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(RecursionLimit { limit, .. }) =>
                    {
                    break 'done Some(*limit);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, RecursionLimit { limit, .. } => *limit).unwrap_or(Limit::new(128))
35}