Skip to content

Commit ac60db2

Browse files
committed
do use ty::Const in patterns and abstract consts
1 parent b38077e commit ac60db2

File tree

15 files changed

+105
-127
lines changed

15 files changed

+105
-127
lines changed

compiler/rustc_middle/src/thir.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ pub enum PatKind<'tcx> {
661661
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
662662
/// `PartialEq` and `Eq`.
663663
Constant {
664-
value: mir::ConstantKind<'tcx>,
664+
value: ty::Const<'tcx>,
665665
},
666666

667667
Range(PatRange<'tcx>),
@@ -691,8 +691,8 @@ pub enum PatKind<'tcx> {
691691

692692
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
693693
pub struct PatRange<'tcx> {
694-
pub lo: mir::ConstantKind<'tcx>,
695-
pub hi: mir::ConstantKind<'tcx>,
694+
pub lo: ty::Const<'tcx>,
695+
pub hi: ty::Const<'tcx>,
696696
pub end: RangeEnd,
697697
}
698698

@@ -736,7 +736,11 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
736736
Some(adt_def.variant(variant_index))
737737
}
738738
_ => self.ty.ty_adt_def().and_then(|adt| {
739-
if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
739+
if !adt.is_enum() {
740+
Some(adt.non_enum_variant())
741+
} else {
742+
None
743+
}
740744
}),
741745
};
742746

compiler/rustc_middle/src/thir/abstract_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub enum CastKind {
2222
/// A node of an `AbstractConst`.
2323
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
2424
pub enum Node<'tcx> {
25-
Leaf(mir::ConstantKind<'tcx>),
25+
Leaf(ty::Const<'tcx>),
2626
Binop(mir::BinOp, NodeId, NodeId),
2727
UnaryOp(mir::UnOp, NodeId),
2828
FunctionCall(NodeId, &'tcx [NodeId]),

compiler/rustc_middle/src/thir/visit.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,8 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
9494
visitor.visit_expr(&visitor.thir()[value])
9595
}
9696
}
97-
<<<<<<< HEAD
9897
ConstBlock { did: _, substs: _ } => {}
9998
Repeat { value, count: _ } => {
100-
=======
101-
ConstBlock { value } => visitor.visit_constant(value),
102-
Repeat { value, count } => {
103-
>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const)
10499
visitor.visit_expr(&visitor.thir()[value]);
105100
}
106101
Array { ref fields } | Tuple { ref fields } => {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ static_assert_size!(ConstKind<'_>, 40);
7676
impl<'tcx> ConstKind<'tcx> {
7777
#[inline]
7878
pub fn try_to_value(self) -> Option<ConstValue<'tcx>> {
79-
if let ConstKind::Value(val) = self { Some(val) } else { None }
79+
if let ConstKind::Value(val) = self {
80+
Some(val)
81+
} else {
82+
None
83+
}
8084
}
8185

8286
#[inline]
@@ -126,6 +130,7 @@ impl<'tcx> ConstKind<'tcx> {
126130
#[inline]
127131
/// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary
128132
/// return `None`.
133+
// FIXME(@lcnr): Completely rework the evaluation/normalization system for `ty::Const` once valtrees are merged.
129134
pub fn try_eval(
130135
self,
131136
tcx: TyCtxt<'tcx>,

compiler/rustc_mir_build/src/build/matches/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,13 +964,13 @@ enum TestKind<'tcx> {
964964
///
965965
/// For `bool` we always generate two edges, one for `true` and one for
966966
/// `false`.
967-
options: FxIndexMap<ConstantKind<'tcx>, u128>,
967+
options: FxIndexMap<ty::Const<'tcx>, u128>,
968968
},
969969

970970
/// Test for equality with value, possibly after an unsizing coercion to
971971
/// `ty`,
972972
Eq {
973-
value: ConstantKind<'tcx>,
973+
value: ty::Const<'tcx>,
974974
// Integer types are handled by `SwitchInt`, and constants with ADT
975975
// types are converted back into patterns, so this can only be `&str`,
976976
// `&[T]`, `f32` or `f64`.

compiler/rustc_mir_build/src/build/matches/simplify.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
228228
_ => (None, 0),
229229
};
230230
if let Some((min, max, sz)) = range {
231-
if let (Some(lo), Some(hi)) = (lo.try_to_bits(sz), hi.try_to_bits(sz)) {
231+
if let (Some(lo), Some(hi)) =
232+
(lo.val().try_to_bits(sz), hi.val().try_to_bits(sz))
233+
{
232234
// We want to compare ranges numerically, but the order of the bitwise
233235
// representation of signed integers does not match their numeric order.
234236
// Thus, to correct the ordering, we need to shift the range of signed

compiler/rustc_mir_build/src/build/matches/test.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8686
test_place: &PlaceBuilder<'tcx>,
8787
candidate: &Candidate<'pat, 'tcx>,
8888
switch_ty: Ty<'tcx>,
89-
options: &mut FxIndexMap<ConstantKind<'tcx>, u128>,
89+
options: &mut FxIndexMap<ty::Const<'tcx>, u128>,
9090
) -> bool {
9191
let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
9292
return false;
@@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
264264
);
265265
} else if let [success, fail] = *make_target_blocks(self) {
266266
assert_eq!(value.ty(), ty);
267-
let expect = self.literal_operand(test.span, value);
267+
let expect = self.literal_operand(test.span, value.into());
268268
let val = Operand::Copy(place);
269269
self.compare(block, success, fail, source_info, BinOp::Eq, expect, val);
270270
} else {
@@ -277,8 +277,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
277277
let target_blocks = make_target_blocks(self);
278278

279279
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
280-
let lo = self.literal_operand(test.span, lo);
281-
let hi = self.literal_operand(test.span, hi);
280+
let lo = self.literal_operand(test.span, lo.into());
281+
let hi = self.literal_operand(test.span, hi.into());
282282
let val = Operand::Copy(place);
283283

284284
let [success, fail] = *target_blocks else {
@@ -366,11 +366,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
366366
block: BasicBlock,
367367
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
368368
source_info: SourceInfo,
369-
value: ConstantKind<'tcx>,
369+
value: ty::Const<'tcx>,
370370
place: Place<'tcx>,
371371
mut ty: Ty<'tcx>,
372372
) {
373-
let mut expect = self.literal_operand(source_info.span, value);
373+
let mut expect = self.literal_operand(source_info.span, value.into());
374374
let mut val = Operand::Copy(place);
375375

376376
// If we're using `b"..."` as a pattern, we need to insert an
@@ -760,11 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
760760
span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern)
761761
}
762762

763-
fn const_range_contains(
764-
&self,
765-
range: PatRange<'tcx>,
766-
value: ConstantKind<'tcx>,
767-
) -> Option<bool> {
763+
fn const_range_contains(&self, range: PatRange<'tcx>, value: ty::Const<'tcx>) -> Option<bool> {
768764
use std::cmp::Ordering::*;
769765

770766
let tcx = self.tcx;
@@ -781,7 +777,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
781777
fn values_not_contained_in_range(
782778
&self,
783779
range: PatRange<'tcx>,
784-
options: &FxIndexMap<ConstantKind<'tcx>, u128>,
780+
options: &FxIndexMap<ty::Const<'tcx>, u128>,
785781
) -> Option<bool> {
786782
for &val in options.keys() {
787783
if self.const_range_contains(range, val)? {

compiler/rustc_mir_build/src/build/misc.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
use crate::build::Builder;
55

6+
use rustc_middle::mir;
67
use rustc_middle::mir::*;
78
use rustc_middle::ty::{self, Ty};
89
use rustc_span::{Span, DUMMY_SP};
@@ -25,7 +26,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2526

2627
/// Convenience function for creating a literal operand, one
2728
/// without any user type annotation.
28-
crate fn literal_operand(&mut self, span: Span, literal: ConstantKind<'tcx>) -> Operand<'tcx> {
29+
crate fn literal_operand(
30+
&mut self,
31+
span: Span,
32+
literal: mir::ConstantKind<'tcx>,
33+
) -> Operand<'tcx> {
2934
let constant = Box::new(Constant { span, user_ty: None, literal });
3035
Operand::Constant(constant)
3136
}

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_hir as hir;
22
use rustc_index::vec::Idx;
33
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
4-
use rustc_middle::mir::{self, Field};
4+
use rustc_middle::mir::Field;
55
use rustc_middle::thir::{FieldPat, Pat, PatKind};
66
use rustc_middle::ty::print::with_no_trimmed_paths;
77
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
@@ -22,7 +22,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
2222
#[instrument(level = "debug", skip(self))]
2323
pub(super) fn const_to_pat(
2424
&self,
25-
cv: mir::ConstantKind<'tcx>,
25+
cv: ty::Const<'tcx>,
2626
id: hir::HirId,
2727
span: Span,
2828
mir_structural_match_violation: bool,
@@ -152,11 +152,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
152152
ty.is_structural_eq_shallow(self.infcx.tcx)
153153
}
154154

155-
fn to_pat(
156-
&mut self,
157-
cv: mir::ConstantKind<'tcx>,
158-
mir_structural_match_violation: bool,
159-
) -> Pat<'tcx> {
155+
fn to_pat(&mut self, cv: ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
160156
trace!(self.treat_byte_string_as_slice);
161157
// This method is just a wrapper handling a validity check; the heavy lifting is
162158
// performed by the recursive `recur` method, which is not meant to be
@@ -250,7 +246,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
250246

251247
fn field_pats(
252248
&self,
253-
vals: impl Iterator<Item = mir::ConstantKind<'tcx>>,
249+
vals: impl Iterator<Item = ty::Const<'tcx>>,
254250
) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
255251
vals.enumerate()
256252
.map(|(idx, val)| {
@@ -263,7 +259,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
263259
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
264260
fn recur(
265261
&self,
266-
cv: mir::ConstantKind<'tcx>,
262+
cv: ty::Const<'tcx>,
267263
mir_structural_match_violation: bool,
268264
) -> Result<Pat<'tcx>, FallbackToConstRef> {
269265
let id = self.id;
@@ -369,7 +365,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
369365
PatKind::Wild
370366
}
371367
ty::Adt(adt_def, substs) if adt_def.is_enum() => {
372-
let destructured = tcx.destructure_mir_constant(param_env.and(cv));
368+
let destructured = tcx.destructure_const(param_env.and(cv));
373369
PatKind::Variant {
374370
adt_def: *adt_def,
375371
substs,
@@ -380,12 +376,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
380376
}
381377
}
382378
ty::Tuple(_) | ty::Adt(_, _) => {
383-
let destructured = tcx.destructure_mir_constant(param_env.and(cv));
379+
let destructured = tcx.destructure_const(param_env.and(cv));
384380
PatKind::Leaf { subpatterns: self.field_pats(destructured.fields.iter().copied())? }
385381
}
386382
ty::Array(..) => PatKind::Array {
387383
prefix: tcx
388-
.destructure_mir_constant(param_env.and(cv))
384+
.destructure_const(param_env.and(cv))
389385
.fields
390386
.iter()
391387
.map(|val| self.recur(*val, false))
@@ -416,12 +412,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
416412
// arrays.
417413
ty::Array(..) if !self.treat_byte_string_as_slice => {
418414
let old = self.behind_reference.replace(true);
419-
let array = tcx.deref_mir_constant(self.param_env.and(cv));
415+
let array = tcx.deref_const(self.param_env.and(cv));
420416
let val = PatKind::Deref {
421417
subpattern: Pat {
422418
kind: Box::new(PatKind::Array {
423419
prefix: tcx
424-
.destructure_mir_constant(param_env.and(array))
420+
.destructure_const(param_env.and(array))
425421
.fields
426422
.iter()
427423
.map(|val| self.recur(*val, false))
@@ -442,12 +438,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
442438
// pattern.
443439
ty::Slice(elem_ty) => {
444440
let old = self.behind_reference.replace(true);
445-
let array = tcx.deref_mir_constant(self.param_env.and(cv));
441+
let array = tcx.deref_const(self.param_env.and(cv));
446442
let val = PatKind::Deref {
447443
subpattern: Pat {
448444
kind: Box::new(PatKind::Slice {
449445
prefix: tcx
450-
.destructure_mir_constant(param_env.and(array))
446+
.destructure_const(param_env.and(array))
451447
.fields
452448
.iter()
453449
.map(|val| self.recur(*val, false))
@@ -516,7 +512,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
516512
// we fall back to a const pattern. If we do not do this, we may end up with
517513
// a !structural-match constant that is not of reference type, which makes it
518514
// very hard to invoke `PartialEq::eq` on it as a fallback.
519-
let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) {
515+
let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
520516
Ok(subpattern) => PatKind::Deref { subpattern },
521517
Err(_) => PatKind::Constant { value: cv },
522518
};

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rustc_data_structures::captures::Captures;
5252
use rustc_index::vec::Idx;
5353

5454
use rustc_hir::{HirId, RangeEnd};
55-
use rustc_middle::mir::{self, Field};
55+
use rustc_middle::mir::Field;
5656
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
5757
use rustc_middle::ty::layout::IntegerExt;
5858
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
@@ -136,30 +136,20 @@ impl IntRange {
136136
fn from_const<'tcx>(
137137
tcx: TyCtxt<'tcx>,
138138
param_env: ty::ParamEnv<'tcx>,
139-
value: mir::ConstantKind<'tcx>,
139+
value: ty::Const<'tcx>,
140140
) -> Option<IntRange> {
141141
let ty = value.ty();
142142
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
143143
let val = (|| {
144-
match value {
145-
mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => {
146-
// For this specific pattern we can skip a lot of effort and go
147-
// straight to the result, after doing a bit of checking. (We
148-
// could remove this branch and just fall through, which
149-
// is more general but much slower.)
150-
if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) {
151-
return Some(bits);
152-
}
144+
if let ty::ConstKind::Value(ConstValue::Scalar(scalar)) = value.val() {
145+
// For this specific pattern we can skip a lot of effort and go
146+
// straight to the result, after doing a bit of checking. (We
147+
// could remove this branch and just fall through, which
148+
// is more general but much slower.)
149+
if let Ok(bits) = scalar.to_bits_or_ptr_internal(target_size) {
150+
return Some(bits);
153151
}
154-
mir::ConstantKind::Ty(c) => match c.val() {
155-
ty::ConstKind::Value(_) => bug!(
156-
"encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val"
157-
),
158-
_ => {}
159-
},
160-
_ => {}
161152
}
162-
163153
// This is a more general form of the previous case.
164154
value.try_eval_bits(tcx, param_env, ty)
165155
})()?;
@@ -244,8 +234,8 @@ impl IntRange {
244234
let (lo, hi) = (lo ^ bias, hi ^ bias);
245235

246236
let env = ty::ParamEnv::empty().and(ty);
247-
let lo_const = mir::ConstantKind::from_bits(tcx, lo, env);
248-
let hi_const = mir::ConstantKind::from_bits(tcx, hi, env);
237+
let lo_const = ty::Const::from_bits(tcx, lo, env);
238+
let hi_const = ty::Const::from_bits(tcx, hi, env);
249239

250240
let kind = if lo == hi {
251241
PatKind::Constant { value: lo_const }
@@ -640,9 +630,9 @@ pub(super) enum Constructor<'tcx> {
640630
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
641631
IntRange(IntRange),
642632
/// Ranges of floating-point literal values (`2.0..=5.2`).
643-
FloatRange(mir::ConstantKind<'tcx>, mir::ConstantKind<'tcx>, RangeEnd),
633+
FloatRange(ty::Const<'tcx>, ty::Const<'tcx>, RangeEnd),
644634
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
645-
Str(mir::ConstantKind<'tcx>),
635+
Str(ty::Const<'tcx>),
646636
/// Array and slice patterns.
647637
Slice(Slice),
648638
/// Constants that must not be matched structurally. They are treated as black
@@ -839,7 +829,8 @@ impl<'tcx> Constructor<'tcx> {
839829
}
840830
}
841831
(Str(self_val), Str(other_val)) => {
842-
// FIXME: there's probably a more direct way of comparing for equality
832+
// FIXME Once valtrees are available we can directly use the bytes
833+
// in the `Str` variant of the valtree for the comparison here.
843834
match compare_const_vals(
844835
pcx.cx.tcx,
845836
*self_val,

0 commit comments

Comments
 (0)