@@ -29,8 +29,10 @@ use rustc_target::spec::{Target, TargetTriple, TlsModel};
2929
3030use std:: cell:: { self , RefCell } ;
3131use std:: env;
32+ use std:: fmt;
3233use std:: io:: Write ;
3334use std:: num:: NonZeroU32 ;
35+ use std:: ops:: { Div , Mul } ;
3436use std:: path:: PathBuf ;
3537use std:: str:: FromStr ;
3638use std:: sync:: Arc ;
@@ -55,6 +57,46 @@ pub enum CtfeBacktrace {
5557 Immediate ,
5658}
5759
60+ /// New-type wrapper around `usize` for representing limits. Ensures that comparisons against
61+ /// limits are consistent throughout the compiler.
62+ #[ derive( Clone , Copy , Debug ) ]
63+ pub struct Limit ( pub usize ) ;
64+
65+ impl Limit {
66+ /// Create a new limit from a `usize`.
67+ pub fn new ( value : usize ) -> Self {
68+ Limit ( value)
69+ }
70+
71+ /// Check that `value` is within the limit. Ensures that the same comparisons are used
72+ /// throughout the compiler, as mismatches can cause ICEs, see #72540.
73+ pub fn value_within_limit ( & self , value : usize ) -> bool {
74+ value <= self . 0
75+ }
76+ }
77+
78+ impl fmt:: Display for Limit {
79+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
80+ write ! ( f, "{}" , self . 0 )
81+ }
82+ }
83+
84+ impl Div < usize > for Limit {
85+ type Output = Limit ;
86+
87+ fn div ( self , rhs : usize ) -> Self :: Output {
88+ Limit :: new ( self . 0 / rhs)
89+ }
90+ }
91+
92+ impl Mul < usize > for Limit {
93+ type Output = Limit ;
94+
95+ fn mul ( self , rhs : usize ) -> Self :: Output {
96+ Limit :: new ( self . 0 * rhs)
97+ }
98+ }
99+
58100/// Represents the data associated with a compilation
59101/// session for a single crate.
60102pub struct Session {
@@ -89,13 +131,13 @@ pub struct Session {
89131
90132 /// The maximum recursion limit for potentially infinitely recursive
91133 /// operations such as auto-dereference and monomorphization.
92- pub recursion_limit : OnceCell < usize > ,
134+ pub recursion_limit : OnceCell < Limit > ,
93135
94136 /// The maximum length of types during monomorphization.
95- pub type_length_limit : OnceCell < usize > ,
137+ pub type_length_limit : OnceCell < Limit > ,
96138
97139 /// The maximum blocks a const expression can evaluate.
98- pub const_eval_limit : OnceCell < usize > ,
140+ pub const_eval_limit : OnceCell < Limit > ,
99141
100142 incr_comp_session : OneThread < RefCell < IncrCompSession > > ,
101143 /// Used for incremental compilation tests. Will only be populated if
@@ -255,15 +297,15 @@ impl Session {
255297 self . crate_types . set ( crate_types) . expect ( "`crate_types` was initialized twice" )
256298 }
257299
258- pub fn recursion_limit ( & self ) -> usize {
300+ pub fn recursion_limit ( & self ) -> Limit {
259301 self . recursion_limit . get ( ) . copied ( ) . unwrap ( )
260302 }
261303
262- pub fn type_length_limit ( & self ) -> usize {
304+ pub fn type_length_limit ( & self ) -> Limit {
263305 self . type_length_limit . get ( ) . copied ( ) . unwrap ( )
264306 }
265307
266- pub fn const_eval_limit ( & self ) -> usize {
308+ pub fn const_eval_limit ( & self ) -> Limit {
267309 self . const_eval_limit . get ( ) . copied ( ) . unwrap ( )
268310 }
269311
0 commit comments