diff options
| author | Ralf Jung <post@ralfj.de> | 2024-04-18 08:44:17 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-04-19 17:17:31 +0200 |
| commit | d3f927db874aaa82480cd2120e15a507e7cb9b15 (patch) | |
| tree | 977480a87bf4289cef9c3d652147b47e342bf2be | |
| parent | 42220f0930a0fb187a75edeeee91d525c326f56d (diff) | |
| download | rust-d3f927db874aaa82480cd2120e15a507e7cb9b15.tar.gz rust-d3f927db874aaa82480cd2120e15a507e7cb9b15.zip | |
avoid PartialOrd on ScalarInt
we don't know their sign so we cannot, in general, order them properly
| -rw-r--r-- | compiler/rustc_middle/src/mir/consts.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/int.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/valtree.rs | 2 |
4 files changed, 24 insertions, 13 deletions
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 0af012e90cb..b788cfde85e 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -244,6 +244,8 @@ impl<'tcx> Const<'tcx> { Const::Ty(c) => match c.kind() { ty::ConstKind::Value(valtree) if c.ty().is_primitive() => { // A valtree of a type where leaves directly represent the scalar const value. + // Just checking whether it is a leaf is insufficient as e.g. references are leafs + // but the leaf value is the value they point to, not the reference itself! Some(valtree.unwrap_leaf().into()) } _ => None, @@ -255,7 +257,17 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn try_to_scalar_int(self) -> Option<ScalarInt> { - self.try_to_scalar()?.try_to_int().ok() + // This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster. + match self { + Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x), + Const::Ty(c) => match c.kind() { + ty::ConstKind::Value(valtree) if c.ty().is_primitive() => { + Some(valtree.unwrap_leaf()) + } + _ => None, + }, + _ => None, + } } #[inline] diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 8763e94c8b0..d4573c9776c 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -16,7 +16,7 @@ use rustc_hir::{BindingAnnotation, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::newtype_index; use rustc_index::IndexVec; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::{AllocId, Scalar}; +use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::IntegerExt; @@ -1009,18 +1009,17 @@ impl<'tcx> PatRangeBoundary<'tcx> { // This code is hot when compiling matches with many ranges. So we // special-case extraction of evaluated scalars for speed, for types where - // raw data comparisons are appropriate. E.g. `unicode-normalization` has + // unsigned int comparisons are appropriate. E.g. `unicode-normalization` has // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared // in this way. - (Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b))) - if matches!(ty.kind(), ty::Uint(_) | ty::Char) => - { - return Some(a.to_valtree().cmp(&b.to_valtree())); + (Finite(a), Finite(b)) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => { + if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) { + let sz = ty.primitive_size(tcx); + let a = a.assert_uint(sz); + let b = b.assert_uint(sz); + return Some(a.cmp(&b)); + } } - ( - Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)), - Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(b)), _)), - ) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => return Some(a.cmp(&b)), _ => {} } diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 2bf2341cbc4..40ac87873a0 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -126,7 +126,7 @@ impl IntoDiagArg for ConstInt { /// /// This is a packed struct in order to allow this type to be optimally embedded in enums /// (like Scalar). -#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy, Eq, PartialEq, Hash)] #[repr(packed)] pub struct ScalarInt { /// The first `size` bytes of `data` are the value. diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index ffa0e89c473..96bc5515a56 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -3,7 +3,7 @@ use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq)] #[derive(HashStable)] /// This datastructure is used to represent the value of constants used in the type system. /// |
