1
Fork 0

Replace f16 and f128 pattern matching stubs with real implementations

This section of code depends on `rustc_apfloat` rather than our internal
types, so this is one potential ICE that we should be able to melt now.

This also fixes some missing range and match handling in `rustc_middle`.
This commit is contained in:
Trevor Gross 2024-03-26 06:01:09 -04:00
parent acb62737ac
commit 6fb6c19c96
11 changed files with 311 additions and 40 deletions

View file

@ -182,7 +182,7 @@ use std::iter::once;
use smallvec::SmallVec;
use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS};
use rustc_apfloat::ieee::{DoubleS, HalfS, IeeeFloat, QuadS, SingleS};
use rustc_index::bit_set::{BitSet, GrowableBitSet};
use rustc_index::IndexVec;
@ -692,8 +692,10 @@ pub enum Constructor<Cx: PatCx> {
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
IntRange(IntRange),
/// Ranges of floating-point literal values (`2.0..=5.2`).
F16Range(IeeeFloat<HalfS>, IeeeFloat<HalfS>, RangeEnd),
F32Range(IeeeFloat<SingleS>, IeeeFloat<SingleS>, RangeEnd),
F64Range(IeeeFloat<DoubleS>, IeeeFloat<DoubleS>, RangeEnd),
F128Range(IeeeFloat<QuadS>, IeeeFloat<QuadS>, RangeEnd),
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
Str(Cx::StrLit),
/// Constants that must not be matched structurally. They are treated as black boxes for the
@ -735,8 +737,10 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
Constructor::UnionField => Constructor::UnionField,
Constructor::Bool(b) => Constructor::Bool(*b),
Constructor::IntRange(range) => Constructor::IntRange(*range),
Constructor::F16Range(lo, hi, end) => Constructor::F16Range(lo.clone(), *hi, *end),
Constructor::F32Range(lo, hi, end) => Constructor::F32Range(lo.clone(), *hi, *end),
Constructor::F64Range(lo, hi, end) => Constructor::F64Range(lo.clone(), *hi, *end),
Constructor::F128Range(lo, hi, end) => Constructor::F128Range(lo.clone(), *hi, *end),
Constructor::Str(value) => Constructor::Str(value.clone()),
Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
Constructor::Or => Constructor::Or,
@ -812,6 +816,14 @@ impl<Cx: PatCx> Constructor<Cx> {
(Bool(self_b), Bool(other_b)) => self_b == other_b,
(IntRange(self_range), IntRange(other_range)) => self_range.is_subrange(other_range),
(F16Range(self_from, self_to, self_end), F16Range(other_from, other_to, other_end)) => {
self_from.ge(other_from)
&& match self_to.partial_cmp(other_to) {
Some(Ordering::Less) => true,
Some(Ordering::Equal) => other_end == self_end,
_ => false,
}
}
(F32Range(self_from, self_to, self_end), F32Range(other_from, other_to, other_end)) => {
self_from.ge(other_from)
&& match self_to.partial_cmp(other_to) {
@ -828,6 +840,17 @@ impl<Cx: PatCx> Constructor<Cx> {
_ => false,
}
}
(
F128Range(self_from, self_to, self_end),
F128Range(other_from, other_to, other_end),
) => {
self_from.ge(other_from)
&& match self_to.partial_cmp(other_to) {
Some(Ordering::Less) => true,
Some(Ordering::Equal) => other_end == self_end,
_ => false,
}
}
(Str(self_val), Str(other_val)) => {
// FIXME Once valtrees are available we can directly use the bytes
// in the `Str` variant of the valtree for the comparison here.
@ -906,8 +929,10 @@ impl<Cx: PatCx> Constructor<Cx> {
Bool(b) => write!(f, "{b}")?,
// Best-effort, will render signed ranges incorrectly
IntRange(range) => write!(f, "{range:?}")?,
F16Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
F128Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
Str(value) => write!(f, "{value:?}")?,
Opaque(..) => write!(f, "<constant pattern>")?,
Or => {