do use ty::Const in patterns and abstract consts

This commit is contained in:
b-naber
2022-03-09 13:56:12 +01:00
parent b38077ea0b
commit ac60db231c
15 changed files with 105 additions and 127 deletions

View File

@@ -964,13 +964,13 @@ enum TestKind<'tcx> {
///
/// For `bool` we always generate two edges, one for `true` and one for
/// `false`.
options: FxIndexMap<ConstantKind<'tcx>, u128>,
options: FxIndexMap<ty::Const<'tcx>, u128>,
},
/// Test for equality with value, possibly after an unsizing coercion to
/// `ty`,
Eq {
value: ConstantKind<'tcx>,
value: ty::Const<'tcx>,
// Integer types are handled by `SwitchInt`, and constants with ADT
// types are converted back into patterns, so this can only be `&str`,
// `&[T]`, `f32` or `f64`.

View File

@@ -228,7 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => (None, 0),
};
if let Some((min, max, sz)) = range {
if let (Some(lo), Some(hi)) = (lo.try_to_bits(sz), hi.try_to_bits(sz)) {
if let (Some(lo), Some(hi)) =
(lo.val().try_to_bits(sz), hi.val().try_to_bits(sz))
{
// We want to compare ranges numerically, but the order of the bitwise
// representation of signed integers does not match their numeric order.
// Thus, to correct the ordering, we need to shift the range of signed

View File

@@ -86,7 +86,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
test_place: &PlaceBuilder<'tcx>,
candidate: &Candidate<'pat, 'tcx>,
switch_ty: Ty<'tcx>,
options: &mut FxIndexMap<ConstantKind<'tcx>, u128>,
options: &mut FxIndexMap<ty::Const<'tcx>, u128>,
) -> bool {
let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
return false;
@@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
} else if let [success, fail] = *make_target_blocks(self) {
assert_eq!(value.ty(), ty);
let expect = self.literal_operand(test.span, value);
let expect = self.literal_operand(test.span, value.into());
let val = Operand::Copy(place);
self.compare(block, success, fail, source_info, BinOp::Eq, expect, val);
} else {
@@ -277,8 +277,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let target_blocks = make_target_blocks(self);
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
let lo = self.literal_operand(test.span, lo);
let hi = self.literal_operand(test.span, hi);
let lo = self.literal_operand(test.span, lo.into());
let hi = self.literal_operand(test.span, hi.into());
let val = Operand::Copy(place);
let [success, fail] = *target_blocks else {
@@ -366,11 +366,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block: BasicBlock,
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
source_info: SourceInfo,
value: ConstantKind<'tcx>,
value: ty::Const<'tcx>,
place: Place<'tcx>,
mut ty: Ty<'tcx>,
) {
let mut expect = self.literal_operand(source_info.span, value);
let mut expect = self.literal_operand(source_info.span, value.into());
let mut val = Operand::Copy(place);
// If we're using `b"..."` as a pattern, we need to insert an
@@ -760,11 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern)
}
fn const_range_contains(
&self,
range: PatRange<'tcx>,
value: ConstantKind<'tcx>,
) -> Option<bool> {
fn const_range_contains(&self, range: PatRange<'tcx>, value: ty::Const<'tcx>) -> Option<bool> {
use std::cmp::Ordering::*;
let tcx = self.tcx;
@@ -781,7 +777,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn values_not_contained_in_range(
&self,
range: PatRange<'tcx>,
options: &FxIndexMap<ConstantKind<'tcx>, u128>,
options: &FxIndexMap<ty::Const<'tcx>, u128>,
) -> Option<bool> {
for &val in options.keys() {
if self.const_range_contains(range, val)? {

View File

@@ -3,6 +3,7 @@
use crate::build::Builder;
use rustc_middle::mir;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};
use rustc_span::{Span, DUMMY_SP};
@@ -25,7 +26,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Convenience function for creating a literal operand, one
/// without any user type annotation.
crate fn literal_operand(&mut self, span: Span, literal: ConstantKind<'tcx>) -> Operand<'tcx> {
crate fn literal_operand(
&mut self,
span: Span,
literal: mir::ConstantKind<'tcx>,
) -> Operand<'tcx> {
let constant = Box::new(Constant { span, user_ty: None, literal });
Operand::Constant(constant)
}