about summary refs log tree commit diff
path: root/compiler/rustc_hir/src
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-08-24 13:25:36 +0200
committerJana Dönszelmann <jana@donsz.nl>2025-09-08 15:07:12 -0700
commit6087d89004eda5e1f6406182b9866497ecb22e99 (patch)
tree6b99769152229cbbf7259514f36d10f7a42a645e /compiler/rustc_hir/src
parentb82171de5fe2a13a12f35ce4368ef34a477f55c4 (diff)
downloadrust-6087d89004eda5e1f6406182b9866497ecb22e99.tar.gz
rust-6087d89004eda5e1f6406182b9866497ecb22e99.zip
fixup limit handling code
Diffstat (limited to 'compiler/rustc_hir/src')
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs9
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs2
-rw-r--r--compiler/rustc_hir/src/attrs/pretty_printing.rs4
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/limit.rs63
5 files changed, 73 insertions, 6 deletions
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index c4e068ad425..b4c1b61b9b5 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -14,6 +14,7 @@ pub use rustc_target::spec::SanitizerSet;
 use thin_vec::ThinVec;
 
 use crate::attrs::pretty_printing::PrintAttribute;
+use crate::limit::Limit;
 use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};
 
 #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)]
@@ -566,7 +567,7 @@ pub enum AttributeKind {
     MayDangle(Span),
 
     /// Represents `#[move_size_limit]`
-    MoveSizeLimit { attr_span: Span, limit_span: Span, limit: usize },
+    MoveSizeLimit { attr_span: Span, limit_span: Span, limit: Limit },
 
     /// Represents `#[must_use]`.
     MustUse {
@@ -600,7 +601,7 @@ pub enum AttributeKind {
     Path(Symbol, Span),
 
     /// Represents `#[pattern_complexity_limit]`
-    PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: usize },
+    PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: Limit },
 
     /// Represents `#[pointee]`
     Pointee(Span),
@@ -618,7 +619,7 @@ pub enum AttributeKind {
     PubTransparent(Span),
 
     /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute)
-    RecursionLimit { attr_span: Span, limit_span: Span, limit: usize },
+    RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit },
 
     /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
     Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
@@ -671,7 +672,7 @@ pub enum AttributeKind {
     TypeConst(Span),
 
     /// Represents `#[type_length_limit]`
-    TypeLengthLimit { attr_span: Span, limit_span: Span, limit: usize },
+    TypeLengthLimit { attr_span: Span, limit_span: Span, limit: Limit },
 
     /// Represents `#[rustc_unsafe_specialization_marker]`.
     UnsafeSpecializationMarker(Span),
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index 89ba1e0d7de..0e208be3497 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -92,7 +92,7 @@ impl AttributeKind {
             TargetFeature { .. } => No,
             TrackCaller(..) => Yes,
             TypeConst(..) => Yes,
-            TypeLengthLimit { .. } => Yes,
+            TypeLengthLimit { .. } => No,
             UnsafeSpecializationMarker(..) => No,
             UnstableFeatureBound(..) => No,
             Used { .. } => No,
diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs
index a4c2beb689d..d13cd3fd1da 100644
--- a/compiler/rustc_hir/src/attrs/pretty_printing.rs
+++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs
@@ -9,6 +9,8 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
 use rustc_target::spec::SanitizerSet;
 use thin_vec::ThinVec;
 
+use crate::limit::Limit;
+
 /// This trait is used to print attributes in `rustc_hir_pretty`.
 ///
 /// For structs and enums it can be derived using [`rustc_macros::PrintAttribute`].
@@ -146,7 +148,7 @@ macro_rules! print_tup {
 
 print_tup!(A B C D E F G H);
 print_skip!(Span, (), ErrorGuaranteed);
-print_disp!(u16, bool, NonZero<u32>, usize);
+print_disp!(u16, bool, NonZero<u32>, Limit);
 print_debug!(
     Symbol,
     Ident,
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 78fc63753a2..eb630fc8018 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -25,6 +25,7 @@ mod hir;
 pub use rustc_hir_id::{self as hir_id, *};
 pub mod intravisit;
 pub mod lang_items;
+pub mod limit;
 pub mod lints;
 pub mod pat_util;
 mod stability;
diff --git a/compiler/rustc_hir/src/limit.rs b/compiler/rustc_hir/src/limit.rs
new file mode 100644
index 00000000000..7e6d23f51bd
--- /dev/null
+++ b/compiler/rustc_hir/src/limit.rs
@@ -0,0 +1,63 @@
+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<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)
+    }
+}