@@ -29,8 +29,10 @@ use rustc_target::spec::{Target, TargetTriple, TlsModel};
29
29
30
30
use std:: cell:: { self , RefCell } ;
31
31
use std:: env;
32
+ use std:: fmt;
32
33
use std:: io:: Write ;
33
34
use std:: num:: NonZeroU32 ;
35
+ use std:: ops:: { Div , Mul } ;
34
36
use std:: path:: PathBuf ;
35
37
use std:: str:: FromStr ;
36
38
use std:: sync:: Arc ;
@@ -55,6 +57,46 @@ pub enum CtfeBacktrace {
55
57
Immediate ,
56
58
}
57
59
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
+
58
100
/// Represents the data associated with a compilation
59
101
/// session for a single crate.
60
102
pub struct Session {
@@ -89,13 +131,13 @@ pub struct Session {
89
131
90
132
/// The maximum recursion limit for potentially infinitely recursive
91
133
/// operations such as auto-dereference and monomorphization.
92
- pub recursion_limit : OnceCell < usize > ,
134
+ pub recursion_limit : OnceCell < Limit > ,
93
135
94
136
/// The maximum length of types during monomorphization.
95
- pub type_length_limit : OnceCell < usize > ,
137
+ pub type_length_limit : OnceCell < Limit > ,
96
138
97
139
/// The maximum blocks a const expression can evaluate.
98
- pub const_eval_limit : OnceCell < usize > ,
140
+ pub const_eval_limit : OnceCell < Limit > ,
99
141
100
142
incr_comp_session : OneThread < RefCell < IncrCompSession > > ,
101
143
/// Used for incremental compilation tests. Will only be populated if
@@ -255,15 +297,15 @@ impl Session {
255
297
self . crate_types . set ( crate_types) . expect ( "`crate_types` was initialized twice" )
256
298
}
257
299
258
- pub fn recursion_limit ( & self ) -> usize {
300
+ pub fn recursion_limit ( & self ) -> Limit {
259
301
self . recursion_limit . get ( ) . copied ( ) . unwrap ( )
260
302
}
261
303
262
- pub fn type_length_limit ( & self ) -> usize {
304
+ pub fn type_length_limit ( & self ) -> Limit {
263
305
self . type_length_limit . get ( ) . copied ( ) . unwrap ( )
264
306
}
265
307
266
- pub fn const_eval_limit ( & self ) -> usize {
308
+ pub fn const_eval_limit ( & self ) -> Limit {
267
309
self . const_eval_limit . get ( ) . copied ( ) . unwrap ( )
268
310
}
269
311
0 commit comments