Skip to main content

rustc_structures/
limit.rs

1use std::fmt;
2use std::ops::{Div, Mul};
3
4#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash};
6
7/// New-type wrapper around `usize` for representing limits. Ensures that comparisons against
8/// limits are consistent throughout the compiler.
9#[derive(#[automatically_derived]
impl ::core::clone::Clone for Limit {
    #[inline]
    fn clone(&self) -> Limit {
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Limit { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Limit {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Limit",
            &&self.0)
    }
}Debug)]
10#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Limit {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Limit(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Limit {
            fn encode(&self, __encoder: &mut __E) {
                let Limit(ref __binding_0) = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Limit {
            fn decode(__decoder: &mut __D) -> Self {
                Limit(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable_NoContext))]
11pub struct Limit(pub usize);
12
13impl Limit {
14    /// Create a new limit from a `usize`.
15    pub fn new(value: usize) -> Self {
16        Limit(value)
17    }
18
19    /// Create a new unlimited limit.
20    pub fn unlimited() -> Self {
21        Limit(usize::MAX)
22    }
23
24    /// Check that `value` is within the limit. Ensures that the same comparisons are used
25    /// throughout the compiler, as mismatches can cause ICEs, see #72540.
26    #[inline]
27    pub fn value_within_limit(&self, value: usize) -> bool {
28        value <= self.0
29    }
30}
31
32impl From<usize> for Limit {
33    fn from(value: usize) -> Self {
34        Self::new(value)
35    }
36}
37
38impl fmt::Display for Limit {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        self.0.fmt(f)
41    }
42}
43
44impl Div<usize> for Limit {
45    type Output = Limit;
46
47    fn div(self, rhs: usize) -> Self::Output {
48        Limit::new(self.0 / rhs)
49    }
50}
51
52impl Mul<usize> for Limit {
53    type Output = Limit;
54
55    fn mul(self, rhs: usize) -> Self::Output {
56        Limit::new(self.0 * rhs)
57    }
58}
59
60#[cfg(feature = "nightly")]
61impl rustc_error_messages::IntoDiagArg for Limit {
62    fn into_diag_arg(
63        self,
64        _: &mut Option<std::path::PathBuf>,
65    ) -> rustc_error_messages::DiagArgValue {
66        self.0.into_diag_arg(&mut None)
67    }
68}