Skip to content

Commit

Permalink
avoid PartialOrd on ScalarInt
Browse files Browse the repository at this point in the history
we don't know their sign so we cannot, in general, order them properly
  • Loading branch information
RalfJung committed Apr 19, 2024
1 parent 42220f0 commit d3f927d
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 13 deletions.
14 changes: 13 additions & 1 deletion compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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]
Expand Down
19 changes: 9 additions & 10 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)),
_ => {}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/consts/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/consts/valtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down

0 comments on commit d3f927d

Please sign in to comment.