Obligation checking Eq for floating point types may never succeed

This commit is contained in:
Ayaz Hafiz 2022-12-01 10:02:37 -06:00
parent 0bae0aafb6
commit 590535a42b
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 60 additions and 2 deletions

View file

@ -488,10 +488,19 @@ struct NotDerivable {
struct Descend(bool);
enum FPDerivable {
/// Whether the floating point type is derivable is based on its ground or unbound type.
Descend,
/// The FP type is never derivable.
No(NotDerivableContext),
}
trait DerivableVisitor {
const ABILITY: Symbol;
const ABILITY_SLICE: SubsSlice<Symbol>;
const IS_FLOATING_POINT_DERIVABLE: FPDerivable;
#[inline(always)]
fn is_derivable_builtin_opaque(_symbol: Symbol) -> bool {
false
@ -717,14 +726,24 @@ trait DerivableVisitor {
EmptyTagUnion => Self::visit_empty_tag_union(var)?,
},
Alias(
Symbol::NUM_NUM | Symbol::NUM_INTEGER | Symbol::NUM_FLOATINGPOINT,
Symbol::NUM_NUM | Symbol::NUM_INTEGER,
_alias_variables,
real_var,
AliasKind::Opaque,
) => {
// Numbers: always decay until a ground is hit.
// Unbound numbers and integers: always decay until a ground is hit,
// since all of our builtin abilities currently support integers.
stack.push(real_var);
}
Alias(Symbol::NUM_FLOATINGPOINT, _alias_variables, real_var, AliasKind::Opaque) => {
match Self::IS_FLOATING_POINT_DERIVABLE {
FPDerivable::Descend => {
// Decay to a ground
stack.push(real_var)
}
FPDerivable::No(context) => return Err(NotDerivable { var, context }),
}
}
Alias(opaque, _alias_variables, _real_var, AliasKind::Opaque) => {
if obligation_cache
.check_opaque_and_read(abilities_store, opaque, Self::ABILITY)
@ -769,6 +788,8 @@ impl DerivableVisitor for DeriveEncoding {
const ABILITY: Symbol = Symbol::ENCODE_ENCODING;
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_ENCODING;
const IS_FLOATING_POINT_DERIVABLE: FPDerivable = FPDerivable::Descend;
#[inline(always)]
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
is_builtin_number_alias(symbol)
@ -848,6 +869,8 @@ impl DerivableVisitor for DeriveDecoding {
const ABILITY: Symbol = Symbol::DECODE_DECODING;
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_DECODING;
const IS_FLOATING_POINT_DERIVABLE: FPDerivable = FPDerivable::Descend;
#[inline(always)]
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
is_builtin_number_alias(symbol)
@ -938,6 +961,8 @@ impl DerivableVisitor for DeriveHash {
const ABILITY: Symbol = Symbol::HASH_HASH_ABILITY;
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_HASH;
const IS_FLOATING_POINT_DERIVABLE: FPDerivable = FPDerivable::Descend;
#[inline(always)]
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
is_builtin_number_alias(symbol)
@ -1028,6 +1053,9 @@ impl DerivableVisitor for DeriveEq {
const ABILITY: Symbol = Symbol::BOOL_EQ;
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_EQ;
const IS_FLOATING_POINT_DERIVABLE: FPDerivable =
FPDerivable::No(NotDerivableContext::Eq(NotDerivableEq::FloatingPoint));
#[inline(always)]
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
is_builtin_int_alias(symbol) || is_builtin_dec_alias(symbol)