| use std::fmt; | |
| use std::ops::{Div, Mul}; | |
| use rustc_error_messages::{DiagArgValue, IntoDiagArg}; | |
| use rustc_macros::{Decodable, Encodable, StableHash}; | |
| /// New-type wrapper around `usize` for representing limits. Ensures that comparisons against | |
| /// limits are consistent throughout the compiler. | |
| #[derive(Clone, Copy, Debug, StableHash, 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<usize> 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<usize> for Limit { | |
| type Output = Limit; | |
| fn div(self, rhs: usize) -> Self::Output { | |
| Limit::new(self.0 / rhs) | |
| } | |
| } | |
| impl Mul<usize> 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<std::path::PathBuf>) -> DiagArgValue { | |
| self.to_string().into_diag_arg(&mut None) | |
| } | |
| } |