Reorders the parsing code so the expressions are parsed in the same
order as in source and removes unnecessary cursor restores when parsing
function qualifiers.
Our "multiple definitions" check in the frontend was a little
overzealous! The only case which should actually be an error is when
there are multiple *strong* definitions.
In the future we will eliminate this frontend check entirely, because
it's redundant with the check the linker will perform---but for now it's
worth keeping since our linkers do not yet print useful source location
information for Zig exports.
Resolves: https://codeberg.org/ziglang/zig/issues/36678
Previously, the SPIR-V linker would merge every function's MIR into one module, then parsed
it in `BinaryModule`, and run three passes over it:
- `prune_unused` walked the module from its entry points to drop dead declarations
- `dedup_types` deduplicated types and constants
- `lower_invocation_globals` rewrote function signatures to pass a pointer to global
variables as function parameter
Now codegen emits instructions in the order it resolves them (not the spec specified order)
into one section per function. then the linker sorts them into the correct order while also
interning types, constants, strings, etc in the flush step.
Navs the frontend no longer references are now skipped using `Zcu.resolveReferences` instead
of a pass like `prune_unused`. Extern variables are also only loaded when an MIR references them.
`lower_invocation_globals` is gone too. non-`threadlocal` globals on SPIR-V targets are disallowed now.
Currently only vulkan supports them via the newly added `private` address space. See #36715
The new linker also supports incremental compilation now!
For generic code, it is far more useful to consider this equivalent to
`unreachable`. Meanwhile, it is difficult to accidentally write concrete
code which performs this operation, so very little is actually lost from
not having a compile error.
If we accept that this operation does not trigger a compile error, then
it already has the potential to invoke Illegal Behavior today, because
uninstantiable types have an unspecified size in memory, so the
dereference always potentially exceeds the pointer's provenance. (That
said, this only means it is *possible* for the operation to invoke IB,
so the langspec should nonetheless explicitly specify that dereferencing
a pointer to an uninstantiable type is itself Illegal Behavior.)
Storing uninstantiable types into memory does not require any specific
language rules, because that operation can never be reached anyway due
to it requiring an operand (the RHS of `a = b`) whose type is the store
type, which is (by definition) impossible for uninstantiable types.
Resolves: https://codeberg.org/ziglang/zig/issues/36247
A comptime-known `[]T` should behave as similarly as possible to a comptime-
known `*[n]T`. It is now possible to coerce the former to the latter if
their length matches.
A comptime-known `[]T` should behave as similarly as possible to a comptime-
known `*[n]T`. It is now possible to directly dereference both to an array.
Also adds checks for slices with undefined length in code paths where a
slice is dereferenced as an array which would previously crash.
and remove "release" from the enum tag names.
no functional change, however, despite the addition of
backwards-compatibile declarations in this patch, it is breaking because
expressions that use `==` or `!=` operators will not able to use the
deprecated names.
I predict these names to survive until the 1.0 tag without any more
breakage.
This commit implements the `@backingInt` and `@fromBackingInt` builtins.
These builtins are meant to replace the now-deprecated `@intFromEnum` and
`@enumFromInt` builtins.
`@backingInt` works with all enums and with bitpacks with *explicit* backing
integer types only. It also works with tagged unions, returning the backing
integer of the active tag value.
An `undefined` enum or bitpack yields an `undefined` backing integer.
The builtin is lowered to `bit_cast`.
`@fromBackingInt` infers its result type, which may be any enum or a bitpack
with an *explicit* backing integer type. It takes a parameter of exactly
that backing integer type.
For enums, passing a backing integer that is either `undefined` or would
yield an invalid tag value results in safety-checked Illegal Behavior.
For bitpacks, passing an `undefined` backing integer yields an `undefined`
bitpack.
The builtin is lowered to `bit_cast` or `bit_cast_safe` (more details below).
`@bitCast` now also performs a safety check for invalid tag values if its
destination type is an `enum`.
This commit also introduces a new AIR instruction, `bit_cast_safe`.
Similarly to `int_cast_safe`, it includes a safety check for invalid enum
tag values. When `@enumFromInt` is eventually removed, `int_cast_safe` won't
need to perform this safety check anymore.
Legalize only implements `expand_bit_cast_safe`, and no additional insts
to scalarize `bit_cast_safe` with vector/array operands. That is because
it can just reuse the existing scalarizations for regular `bit_cast`.
The safety check mandated by `bit_cast_safe` is only desired if the result
type is a scalar enum tag value, so the scalarization process is exactly
equivalent. The only difference is that we have to perform a safety check
on the result of the scalarization.
This means that there's no reason for a backend to want scalarization of
regular `bit_cast`, but not of `bit_cast_safe` (or the other way round).
If a backend is having trouble with the `bit_cast_safe` safety check it
should just use `expand_bit_cast_safe` instead.
Also adds a `std.meta.BackingInt()` function to conveniently get the result
type of `@backingInt` and for use in the langref.
Empty enums are uninstantiable, so their backing integer should be too.
This avoids a bunch of weird special cases during semantic analysis.
If you were previously using `enum {}`, your code should continue to work
fine.
If you were previously using `enum(uN) {}` (where `uN` is any integer type),
you'll probably want to use `enum(uN) { _ }` instead.
AstGen relies on this behavior, since it marks InvalidCharacter from parseFloat as unreachable after parseNumberLiteral returns float. Before this commit, there was a mismatch, since parseNumberLiteral was not failing on literals with a period in the exponent.
Fixes#36161