| use std::fmt; | |
| use std::ops::{Div, Mul}; | |
| use rustc_macros::{Decodable_NoContext, Encodable_NoContext, 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_NoContext, Decodable_NoContext)] | |
| 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) | |
| } | |
| } |