aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
AgeCommit message (Collapse)Author
2024-12-05compiler: allow files with AstGen errors to undergo semantic analysismlugg
This commit enhances AstGen to introduce a form of error resilience which allows valid ZIR to be emitted even when AstGen errors occur. When a non-fatal AstGen error (e.g. `appendErrorNode`) occurs, ZIR generation is not affected; the error is added to `astgen.errors` and ultimately to the errors stored in `extra`, but that doesn't stop us getting valid ZIR. Fatal AstGen errors (e.g. `failNode`) are a bit trickier. These errors return `error.AnalysisFail`, which is propagated up the stack. In theory, any parent expression can catch this error and handle it, continuing ZIR generation whilst throwing away whatever was lost. For now, we only do this in one place: when creating declarations. If a call to `fnDecl`, `comptimeDecl`, `globalVarDecl`, etc, returns `error.AnalysisFail`, the `declaration` instruction is still created, but its body simply contains the new `extended(astgen_error())` instruction, which instructs Sema to terminate semantic analysis with a transitive error. This means that a fatal AstGen error causes the innermost declaration containing the error to fail, but the rest of the file remains intact. If a source file contains parse errors, or an `error.AnalysisFail` happens when lowering the top-level struct (e.g. there is an error in one of its fields, or a name has multiple declarations), then lowering for the entire file fails. Alongside the existing `Zir.hasCompileErrors` query, this commit introduces `Zir.loweringFailed`, which returns `true` only in this case. The end result here is that files with AstGen failures will almost always still emit valid ZIR, and hence can undergo semantic analysis on the parts of the file which are (from AstGen's perspective) valid. This is a noteworthy improvement to UX, but the main motivation here is actually incremental compilation. Previously, AstGen failures caused lots of semantic analysis work to be thrown out, because all `AnalUnit`s in the file required re-analysis so as to trigger necessary transitive failures and remove stored compile errors which would no longer make sense (because a fresh compilation of this code would not emit those errors, as the units those errors applied to would fail sooner due to referencing a failed file). Now, this case only applies when a file has severe top-level errors, which is far less common than something like having an unused variable. Lastly, this commit changes a few errors in `AstGen` to become fatal when they were previously non-fatal and vice versa. If there is still a reasonable way to continue AstGen and lower to ZIR after an error, it is non-fatal; otherwise, it is fatal. For instance, `comptime const`, while redundant syntax, has a clear meaning we can lower; on the other hand, using an undeclared identifer has no sane lowering, so must trigger a fatal error.
2024-12-03sema: add a missing errdeferAlex Kladov
This fix doesn't matter at all in the grand scheme of things, but I think the story behind it is perhaps curious, as it might point at a design flaw in the Sema's error reporting API. So, a story: On lobsters, there's a rather heated discussion on the merits on RAII vs defer. I don't really like participating in heating discussions, but also sort of can't stop thinking about this. My own personal experience with Zig's defer and errdefer is that they are fiddly to get right consistency --- if a program has a lot of resource management to do, I _always_ mess up at least one defer/errdefer. I've found my internal peace by just avoiding spread-out, "pox" resource management, and instead centralizing resource ownership under one of the following patterns: * Either the thing is acquired and released in main * Or main allocates N instances of thing, and then the rest of the code explicitly juggles this finite pool of N. Notably, this juggling typically doesn't involve defer/errdefer at all, as, at this level of precision, there are no `try`s left, so you only code the happy path * Or there's some sort of arena thing, where a bunch of resources have a single owner, the user's don' bother cleaning up their resources, and instead the owner does it once at the end. So I wanted to make a lobster.rs comment in the vein of "yeah, if your program is mostly about resource management, then Zig could be kinda a pain, but that's friction tells you something: perhaps your program shouldn't be about resource management, and instead it should be doing what it is supposed to do?". And, as an evidence for my claim, I wanted to point out some large body of Zig code which doesn't have a lot of errdefers. So, I cracked opened Sema.zig, `ctrl+f` for `defer`, saw whopping 400 something occupancies, and my heart skipped a bit. Looking at the occurrences, _some_ of them were non-resource-related usages of defer. But a lot of them were the following pattern: ```zig const msg = try sema.errMsg(src, "comptime control flow inside runtime block", .{}); errdefer msg.destroy(sema.gpa); ``` This is exactly the thing that I know _I_ can't get right consistently! So, at this point, I made a prediction that at least one of `errdefer`s is missing. So, I looked at the first few `const msg = try` and of course found one without `errdefer`. I am at 0.8 that, even with this PR applied, the claim will still stand --- there will be `errdefer` missing. So it feels like some API re-design is in order, to make sure individual error messages are not resources. Could Sema just own all partially-constructed error messages, and, at a few known safe-points: * if the control flow is normal, assert that there are no in-progress error messages * if we are throwing an error, go and release messages immediately? I am unlikely to do the actual refactor here, but I think it's worth highlighting the overall pattern here. PS: I am only 0.9 sure that what I've found is indeed a bug! I don't understand the code, I did a dumb text search, so I _could_ have made a fool of myself here :P
2024-11-28sema: hotpath `++` and `**` for array-pointersDavid Rubin
2024-11-27sema: make `++` and `**` return immutable pointersDavid Rubin
2024-11-24dwarf: fix stepping through an inline loop containing one statementJacob Young
Previously, stepping from the single statement within the loop would always exit the loop because all of the code unrolled from the loop is associated with the same line and treated by the debugger as one line.
2024-11-23compiler: Disallow align(0) everywhere in the language.Alex Rønne Petersen
Thus leaving the design space for this alignment value open, e.g. for packing.
2024-11-20Fix peer type resolution with allowzero pointersxdBronch
2024-11-16Sema: fix peer resolution alignment between slice and empty structJacob Young
An empty struct that coerces to an empty array should not force `align(1)` on the resulting slice type.
2024-11-09Merge pull request #21937 from Snektron/spirv-vulkan-ptrsRobin Voetter
spirv: miscellaneous vulkan + zig stuff
2024-11-09Sema: fix wording in error messageWooster
It's an FQN, not an actual file name.
2024-11-08add storage_buffer address spaceRobin Voetter
2024-11-08spirv: assembler hacky constant placeholdersRobin Voetter
2024-11-08spirv: forbid pointer arithmeticRobin Voetter
2024-11-02Sema: Disallow calling functions with certain special calling conventions.Alex Rønne Petersen
2024-11-01Merge pull request #21861 from alichraghi/masterRobin Voetter
spirv: push constants and small fixes
2024-11-01spirv: Uniform/PushConstant variablesAli Cheraghi
- Rename GPU address spaces to match with SPIR-V spec. - Emit `Block` Decoration for Uniform/PushConstant variables. - Don't emit `OpTypeForwardPointer` for non-opencl targets. (there's still a false-positive about recursive structs) Signed-off-by: Ali Cheraghi <alichraghi@proton.me>
2024-10-31compiler: remove anonymous struct types, unify all tuplesmlugg
This commit reworks how anonymous struct literals and tuples work. Previously, an untyped anonymous struct literal (e.g. `const x = .{ .a = 123 }`) was given an "anonymous struct type", which is a special kind of struct which coerces using structural equivalence. This mechanism was a holdover from before we used RLS / result types as the primary mechanism of type inference. This commit changes the language so that the type assigned here is a "normal" struct type. It uses a form of equivalence based on the AST node and the type's structure, much like a reified (`@Type`) type. Additionally, tuples have been simplified. The distinction between "simple" and "complex" tuple types is eliminated. All tuples, even those explicitly declared using `struct { ... }` syntax, use structural equivalence, and do not undergo staged type resolution. Tuples are very restricted: they cannot have non-`auto` layouts, cannot have aligned fields, and cannot have default values with the exception of `comptime` fields. Tuples currently do not have optimized layout, but this can be changed in the future. This change simplifies the language, and fixes some problematic coercions through pointers which led to unintuitive behavior. Resolves: #16865
2024-10-29Merge pull request #21826 from Snektron/spirv-vulkanRobin Voetter
spirv: vulkan setup
2024-10-28Sema: add missing coercion to bool for condbr_inlinemlugg
Also, start using labeled switch statements when dispatching maybe-runtime instructions like condbr to comptime-only variants like condbr_inline. This can't be merged until we get a zig1.wasm update due to #21385. Resolves: #21405
2024-10-27spirv: forbid merging logical pointersRobin Voetter
Under some architecture/operating system combinations it is forbidden to return a pointer from a merge, as these pointers must point to a location at compile time. This adds a check for those cases when returning a pointer from a block merge.
2024-10-25Merge pull request #21796 from Rexicon226/var-argsMatthew Lugg
fix callconv resolution for varargs
2024-10-25Merge pull request #21710 from alexrp/function-alignmentAlex Rønne Petersen
Some improvements to the compiler's handling of function alignment
2024-10-25use `cCallingConvention` instead of `.C` in SemaDavid Rubin
using `.C` in Sema is incorrect since it will be resolved under the target that Zig was compiled with, not the target build configuration. This is easily solved by just calling `cCallingConvention` on the target to resolve it.
2024-10-24Sema: fix check for whether current AnalUnit is a test functionVeikka Tuominen
Closes #21159
2024-10-23combine codegen work queue and linker task queueAndrew Kelley
these tasks have some shared data dependencies so they cannot be done simultaneously. Future work should untangle these data dependencies so that more can be done in parallel. for now this commit ensures correctness by making linker input parsing and codegen tasks part of the same queue.
2024-10-23rework linker inputsAndrew Kelley
* Compilation.objects changes to Compilation.link_inputs which stores objects, archives, windows resources, shared objects, and strings intended to be put directly into the dynamic section. Order is now preserved between all of these kinds of linker inputs. If it is determined the order does not matter for a particular kind of linker input, that item should be moved to a different array. * rename system_libs to windows_libs * untangle library lookup from CLI types * when doing library lookup, instead of using access syscalls, go ahead and open the files and keep the handles around for passing to the cache system and the linker. * during library lookup and cache file hashing, use positioned reads to avoid affecting the file seek position. * library directories are opened in the CLI and converted to Directory objects, warnings emitted for those that cannot be opened.
2024-10-23Merge pull request #21758 from kcbanner/dll_storage_classAndrew Kelley
Add `is_dll_import` to @extern, to support `__declspec(dllimport)` with the MSVC ABI
2024-10-22Change `ExternOptions.dll_storage_class` to `is_dll_import`kcbanner
It wouldn't make sense to have passe `.export` here, and that was in fact a compile error - so simply make this a bool instead.
2024-10-22Cause a compilation error to occur if using @extern with is_dll_import in a ↵kcbanner
comptime scope. Add a note about thread local / dll import being the cause.
2024-10-22Add support for specifying `dll_storage_class` in @externkcbanner
2024-10-20compiler: Remove uses of defaultFunctionAlignment() in the frontend.Alex Rønne Petersen
minFunctionAlignment() is something we can know ahead of time for any given target because it's a matter of ABI. However, defaultFunctionAlignment() is a matter of optimization and every backend can do it differently depending on any number of factors. For example, LLVM will base the choice on the CPU model in its aarch64 backend. So just don't use this value in the frontend.
2024-10-19Sema: add and improve some callconv compile errorsmlugg
2024-10-19compiler: avoid unreasonable eval branch quotasmlugg
Using `@FieldType` (#21702).
2024-10-19Sema: minor cleanupmlugg
2024-10-19std.Target: rename `defaultCCallingConvention` and `Cpu.Arch.fromCallconv`mlugg
2024-10-19test: update for `CallingConvention` changesmlugg
This also includes some compiler and std changes to correct error messages which weren't properly updated before.
2024-10-19compiler: remove @setAlignStackmlugg
This commit finishes implementing #21209 by removing the `@setAlignStack` builtin in favour of `CallingConvention` payloads. The x86_64 backend is updated to use the stack alignment given in the calling convention (the LLVM backend was already updated in a previous commit). Resolves: #21209
2024-10-19std: update for new `CallingConvention`mlugg
The old `CallingConvention` type is replaced with the new `NewCallingConvention`. References to `NewCallingConvention` in the compiler are updated accordingly. In addition, a few parts of the standard library are updated to use the new type correctly.
2024-10-19compiler: introduce new `CallingConvention`mlugg
This commit begins implementing accepted proposal #21209 by making `std.builtin.CallingConvention` a tagged union. The stage1 dance here is a little convoluted. This commit introduces the new type as `NewCallingConvention`, keeping the old `CallingConvention` around. The compiler uses `std.builtin.NewCallingConvention` exclusively, but when fetching the type from `std` when running the compiler (e.g. with `getBuiltinType`), the name `CallingConvention` is used. This allows a prior build of Zig to be used to build this commit. The next commit will update `zig1.wasm`, and then the compiler and standard library can be updated to completely replace `CallingConvention` with `NewCallingConvention`. The second half of #21209 is to remove `@setAlignStack`, which will be implemented in another commit after updating `zig1.wasm`.
2024-10-16std.Target: Move isLib{C,Cxx}LibName() to std.zig.target.Alex Rønne Petersen
These are really answering questions about the Zig compiler's capacity to provide a libc/libc++ implementation. As such, std.zig.target seems like a more fitting place for these.
2024-10-16std.Target: Rename is_lib{c,cxx}_lib_name() to isLib{C,Cxx}LibName().Alex Rønne Petersen
2024-10-16incremental: introduce `file` dependencies to handle AstGen failuresmlugg
The re-analysis here is a little coarse; it'd be nice in the future to have a way for an AstGen failure to preserve *all* analysis which depends on the last success, and just hide the compile errors which depend on it somehow. But I'm not sure how we'd achieve that, so this works fine for now. Resolves: #21223
2024-10-16Zcu: cache output of `resolveReferences` between callsmlugg
This not only simplifies the error bundling logic, but also improves efficiency by allowing the result to be cached between, for instance, multiple calls to `totalErrorCount`.
2024-10-14Sema: fail if analyzing return in `noreturn`-declared function before ↵gabeuehlein
coercing `undefined` Just switches logic around in coerceExtra to check for returning in a noreturn function before coercing undefined to anything
2024-10-10Sema: implement @splat for arraysmlugg
Resolves: #20433
2024-10-07Sema: add missing runtime value validation to global mutable variablesmlugg
Resolves: #20365
2024-10-07Sema: add missing runtime value validation to @memcpy and @memsetmlugg
2024-10-04remove `@fence` (#21585)David Rubin
closes #11650
2024-10-04Adds new cpu architectures propeller1 and propeller2. (#21563)Felix Queißner
* Adds new cpu architectures propeller1 and propeller2. These cpu architectures allow targeting the Parallax Propeller 1 and Propeller 2, which are both very special microcontrollers with 512 registers and 8 cpu cores. Resolves #21559 * Adds std.elf.EM.PROPELLER and std.elf.EM.PROPELLER2 * Fixes missing switch prongs in src/codegen/llvm.zig * Fixes order in std.Target.Arch --------- Co-authored-by: Felix "xq" Queißner <git@random-projects.net>
2024-09-26Sema: better utility function semanticsAndrew Kelley
better names, return error instead of panicking, better diagnostics, use the standard APIs for resolving values