use std::fmt; use std::ops::{Div, Mul}; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; /// New-type wrapper around `usize` for representing limits. Ensures that comparisons against /// limits are consistent throughout the compiler. #[derive(Clone, Copy, Debug, HashStable_Generic, Encodable, Decodable)] pub struct Limit(pub usize); impl Limit { /// Create a new limit from a `usize`. pub fn new(value: usize) -> Self { Limit(value) } /// Create a new unlimited limit. pub fn unlimited() -> Self { Limit(usize::MAX) } /// Check that `value` is within the limit. Ensures that the same comparisons are used /// throughout the compiler, as mismatches can cause ICEs, see #72540. #[inline] pub fn value_within_limit(&self, value: usize) -> bool { value <= self.0 } } impl From for Limit { fn from(value: usize) -> Self { Self::new(value) } } impl fmt::Display for Limit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl Div for Limit { type Output = Limit; fn div(self, rhs: usize) -> Self::Output { Limit::new(self.0 / rhs) } } impl Mul for Limit { type Output = Limit; fn mul(self, rhs: usize) -> Self::Output { Limit::new(self.0 * rhs) } } impl IntoDiagArg for Limit { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { self.to_string().into_diag_arg(&mut None) } }