Appearance
| 1 | namespace Syntax.Process is | |
| 2 | // Whether the generic compare.value innate can meaningfully | |
| 3 | // compare operands of a given type. It lowers to a single ceq | |
| 4 | // instruction, which is a scalar comparison: correct for | |
| 5 | // primitive scalars, enums, and references. For any other value | |
| 6 | // type the runtime accepts the instruction but degrades it to a | |
| 7 | // shallow bitwise comparison - reference fields compare by | |
| 8 | // identity and bit patterns stand in for values - so == and != | |
| 9 | // over one are rejected at resolution with a pointer to =~. | |
| 10 | class VALUE_EQUALITY_OPERANDS is | |
| 11 | can_compare(type: Semantic.Types.Type) -> bool static is | |
| 12 | // a type parameter keeps == for now: the emitted | |
| 13 | // comparison is correct for primitive and reference | |
| 14 | // instantiations, and generic code has no alternative | |
| 15 | // operator to reach for. This arm must stay ahead of the | |
| 16 | // value-type test - every GenericArgument reports | |
| 17 | // is_value_type, so falling through would misclassify a | |
| 18 | // bare T as a non-primitive struct. | |
| 19 | if type.is_type_variable then | |
| 20 | return true | |
| 21 | fi | |
| 22 | ||
| 23 | if !type.is_value_type then | |
| 24 | return true | |
| 25 | fi | |
| 26 | ||
| 27 | // a value-type T? is a Nullable[T] struct | |
| 28 | if type.is_optional then | |
| 29 | return false | |
| 30 | fi | |
| 31 | ||
| 32 | let symbol = type.symbol | |
| 33 | ||
| 34 | return symbol.il_is_primitive_type \/ isa Semantic.Symbols.ENUM_STRUCT(symbol) | |
| 35 | si | |
| 36 | si | |
| 37 | si |