Clean up some things that should have been taken care of in the
original PR:
- Use `Scalar::float` helper.
- Use `Scalar` associated constants in match patterns.
- Use `Scalar`'s `PartialEq` implementation.
- Clean up identifier paths.
Identify reachable function expressions, constant expressions, and
types using a single pass over each arena, taking advantage of the
fact that expressions and types may only refer to other entries that
precede them within their arena. Only walking the statement tree still
requires a worklist/recursion.
In addition to presumably being faster, this change slightly reduces
the number of non-comment lines of code in `src/compact`.
Introduce a new struct type, `Scalar`, combining a `ScalarKind` and a
`Bytes` width, and use this whenever such pairs of values are passed
around.
In particular, use `Scalar` in `TypeInner` variants `Scalar`, `Vector`,
`Atomic`, and `ValuePointer`.
Introduce associated `Scalar` constants `I32`, `U32`, `F32`, `BOOL`
and `F64`, for common cases.
Introduce a helper function `Scalar::float` for constructing `Float`
scalars of a given width, for dealing with `TypeInner::Matrix`, which
only supplies the scalar width of its elements, not a kind.
Introduce helper functions on `Literal` and `TypeInner`, to produce
the `Scalar` describing elements' values.
Use `Scalar` in `wgpu_core::validation::NumericType` as well.
Introduce a new struct `Scalar`, holding a scalar kind and width, and
use it as appropriate in the WGSL front end. This consolidates
many (kind, width) pairs, and lets us name the two components.
Ideally, `Scalar` would be used throughout Naga, but this would be a large
change, touching hundreds of use sites. This patch begins by
introducing `Scalar` to the WGSL front end only.
This appears to match other backends, and fixes
fix the case where expressions which were named in earlier
functions are used in local variable declarations
Replace the `TypedExpression` struct, used to distinguish between WGSL
pointers and references since Naga has only `Pointer`, with an enum,
`Typed`, with variants for references and plain types. This cleans up
a bunch of code, since the struct's `is_reference` field basically
served as a detached enum discriminant. This also prepares the code
for adding abstract types.
When an error snapshot test fails and we generate a diff comparing the
expected output with the actual output, treat the expected output as
the diff "from", and the actual output as the diff "to" - not the
reverse.