Skip to content

Commit d3f927d

Browse files
committed
avoid PartialOrd on ScalarInt
we don't know their sign so we cannot, in general, order them properly
1 parent 42220f0 commit d3f927d

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

compiler/rustc_middle/src/mir/consts.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ impl<'tcx> Const<'tcx> {
244244
Const::Ty(c) => match c.kind() {
245245
ty::ConstKind::Value(valtree) if c.ty().is_primitive() => {
246246
// A valtree of a type where leaves directly represent the scalar const value.
247+
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
248+
// but the leaf value is the value they point to, not the reference itself!
247249
Some(valtree.unwrap_leaf().into())
248250
}
249251
_ => None,
@@ -255,7 +257,17 @@ impl<'tcx> Const<'tcx> {
255257

256258
#[inline]
257259
pub fn try_to_scalar_int(self) -> Option<ScalarInt> {
258-
self.try_to_scalar()?.try_to_int().ok()
260+
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
261+
match self {
262+
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
263+
Const::Ty(c) => match c.kind() {
264+
ty::ConstKind::Value(valtree) if c.ty().is_primitive() => {
265+
Some(valtree.unwrap_leaf())
266+
}
267+
_ => None,
268+
},
269+
_ => None,
270+
}
259271
}
260272

261273
#[inline]

compiler/rustc_middle/src/thir.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_hir::{BindingAnnotation, ByRef, HirId, MatchSource, RangeEnd};
1616
use rustc_index::newtype_index;
1717
use rustc_index::IndexVec;
1818
use rustc_middle::middle::region;
19-
use rustc_middle::mir::interpret::{AllocId, Scalar};
19+
use rustc_middle::mir::interpret::AllocId;
2020
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
2121
use rustc_middle::ty::adjustment::PointerCoercion;
2222
use rustc_middle::ty::layout::IntegerExt;
@@ -1009,18 +1009,17 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10091009

10101010
// This code is hot when compiling matches with many ranges. So we
10111011
// special-case extraction of evaluated scalars for speed, for types where
1012-
// raw data comparisons are appropriate. E.g. `unicode-normalization` has
1012+
// unsigned int comparisons are appropriate. E.g. `unicode-normalization` has
10131013
// many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
10141014
// in this way.
1015-
(Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b)))
1016-
if matches!(ty.kind(), ty::Uint(_) | ty::Char) =>
1017-
{
1018-
return Some(a.to_valtree().cmp(&b.to_valtree()));
1015+
(Finite(a), Finite(b)) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => {
1016+
if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) {
1017+
let sz = ty.primitive_size(tcx);
1018+
let a = a.assert_uint(sz);
1019+
let b = b.assert_uint(sz);
1020+
return Some(a.cmp(&b));
1021+
}
10191022
}
1020-
(
1021-
Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)),
1022-
Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(b)), _)),
1023-
) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => return Some(a.cmp(&b)),
10241023
_ => {}
10251024
}
10261025

compiler/rustc_middle/src/ty/consts/int.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl IntoDiagArg for ConstInt {
126126
///
127127
/// This is a packed struct in order to allow this type to be optimally embedded in enums
128128
/// (like Scalar).
129-
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
129+
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
130130
#[repr(packed)]
131131
pub struct ScalarInt {
132132
/// The first `size` bytes of `data` are the value.

compiler/rustc_middle/src/ty/consts/valtree.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::mir::interpret::Scalar;
33
use crate::ty::{self, Ty, TyCtxt};
44
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
55

6-
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
6+
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq)]
77
#[derive(HashStable)]
88
/// This datastructure is used to represent the value of constants used in the type system.
99
///

0 commit comments

Comments
 (0)