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:
parent
acb62737ac
commit
6fb6c19c96
11 changed files with 311 additions and 40 deletions
|
@ -247,8 +247,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
}
|
||||
_ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
|
||||
},
|
||||
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
|
||||
| Never | NonExhaustive | Hidden | Missing | PrivateUninhabited | Wildcard => &[],
|
||||
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
|
||||
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
|
||||
| PrivateUninhabited | Wildcard => &[],
|
||||
Or => {
|
||||
bug!("called `Fields::wildcards` on an `Or` ctor")
|
||||
}
|
||||
|
@ -275,8 +276,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
},
|
||||
Ref => 1,
|
||||
Slice(slice) => slice.arity(),
|
||||
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
|
||||
| Never | NonExhaustive | Hidden | Missing | PrivateUninhabited | Wildcard => 0,
|
||||
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
|
||||
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
|
||||
| PrivateUninhabited | Wildcard => 0,
|
||||
Or => bug!("The `Or` constructor doesn't have a fixed arity"),
|
||||
}
|
||||
}
|
||||
|
@ -546,6 +548,18 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F16) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
use rustc_apfloat::Float;
|
||||
let value = rustc_apfloat::ieee::Half::from_bits(bits);
|
||||
F16Range(value, value, RangeEnd::Included)
|
||||
}
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
|
@ -570,6 +584,18 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F128) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
use rustc_apfloat::Float;
|
||||
let value = rustc_apfloat::ieee::Quad::from_bits(bits);
|
||||
F128Range(value, value, RangeEnd::Included)
|
||||
}
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Ref(_, t, _) if t.is_str() => {
|
||||
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
||||
// with other `Deref` patterns. This could have been done in `const_to_pat`,
|
||||
|
@ -611,7 +637,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
match fty {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F16 => {
|
||||
use rustc_apfloat::ieee::Half;
|
||||
let lo = lo.map(Half::from_bits).unwrap_or(-Half::INFINITY);
|
||||
let hi = hi.map(Half::from_bits).unwrap_or(Half::INFINITY);
|
||||
F16Range(lo, hi, end)
|
||||
}
|
||||
ty::FloatTy::F32 => {
|
||||
use rustc_apfloat::ieee::Single;
|
||||
let lo = lo.map(Single::from_bits).unwrap_or(-Single::INFINITY);
|
||||
|
@ -624,7 +655,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let hi = hi.map(Double::from_bits).unwrap_or(Double::INFINITY);
|
||||
F64Range(lo, hi, end)
|
||||
}
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F128 => {
|
||||
use rustc_apfloat::ieee::Quad;
|
||||
let lo = lo.map(Quad::from_bits).unwrap_or(-Quad::INFINITY);
|
||||
let hi = hi.map(Quad::from_bits).unwrap_or(Quad::INFINITY);
|
||||
F128Range(lo, hi, end)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
||||
|
@ -837,7 +873,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
|
||||
`Missing` should have been processed in `apply_constructors`"
|
||||
),
|
||||
F32Range(..) | F64Range(..) | Opaque(..) | Or => {
|
||||
F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Opaque(..) | Or => {
|
||||
bug!("can't convert to pattern: {:?}", pat)
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue