pub enum Bound {
Is(ScalarType),
Kind(CapKind),
}Expand description
What a catalog type variable is required to be.
Without a way to state this, sum would accept Vec[Bool] and
Vec[Float] — the first a nonsense addition of booleans, the second a
silent reinterpretation of float bits as an integer.
§Why the scalar shape is not a capability, and why the other one is
sum, product, min and max each lower to an ExtractScalar at
ScalarKind::Int followed by an IntBinOp or an IntCmp, so
CapKind::Numeric — which is Int, UInt, Byte
and Float — would bless Vec[Float].sum() and return the float’s bits
added as an integer. A capability is the wrong width for an Int-only
lowering.
The capabilities the catalog would otherwise want are already enforced from
the receiver’s type rather than per row, which is stronger: a Map key
must be hash-stable and a heap element orderable wherever that collection is
built, not only when a particular method is called
(Inferer::require_collection_invariants, ADR-057 Decision 3).
So the scalar arm is not a capability. The second arm is: sorted
orders its elements through the element descriptor’s compare callback, and
a Vec[T] whose T is a function value has none. That is CapKind::Ord,
and it is a fact about the row rather than about the receiver’s type — a
Vec is a perfectly good Vec of unorderable things right up until someone
sorts it — so require_collection_invariants is the wrong door for it and
the row has to say it itself.
The match on this enum in praxis_hir’s apply_bounds is exhaustive, so a
third arm is a compile error to add halfway rather than a silent omission.
Variants§
Is(ScalarType)
Exactly one scalar, and nothing else. Discharged by unification, so a
failure is the ordinary expected Int, found Bool reported at the method
name, and an element type nothing has named yet is pinned rather than
merely permitted — which is what v.map(f).sum() needs.
Kind(CapKind)
One capability, and any type that has it. Discharged through the
constraint channel, not by unification: a bound on a variable nothing
has pinned yet cannot be answered, and fn top(v) { v.sorted() } is
exactly that shape until a call site says what v holds. That is the
whole reason this arm is not spelled as a set of scalars.