aboutsummaryrefslogtreecommitdiff
path: root/src/AstGen.zig
AgeCommit message (Collapse)Author
2023-09-22AstGen: fix @export with undeclared identifier crashingWooster
This required a third `if (found_already == null)` in another place in AstGen.zig for this special case of `@export`. Fixes #17188
2023-09-21InternPool: implement getStructTypeAndrew Kelley
This also modifies AstGen so that struct types use 1 bit each from the flags to communicate if there are nonzero inits, alignments, or comptime fields. This allows adding a struct type to the InternPool without looking ahead in memory to find out the answers to these questions, which is easier for CPUs as well as for me, coding this logic right now.
2023-09-17AstGen: allow closure over known-runtime values within @TypeOfmlugg
AstGen emits an error when a closure over a known-runtime value crosses a namespace boundary. This usually makes sense: however, this usage is actually valid if the capture is within a `@TypeOf` operand. Sema already has a special case to allow such closure within `@TypeOf` when AstGen could not determine a value to be runtime-known. This commit simply introduces analagous logic to AstGen to allow `var`s to cross namespace boundaries within `@TypeOf`.
2023-09-15compiler: start using destructure syntaxmlugg
2023-09-15compiler: implement destructuring syntaxmlugg
This change implements the following syntax into the compiler: ```zig const x: u32, var y, foo.bar = .{ 1, 2, 3 }; ``` A destructure expression may only appear within a block (i.e. not at comtainer scope). The LHS consists of a sequence of comma-separated var decls and/or lvalue expressions. The RHS is a normal expression. A new result location type, `destructure`, is used, which contains result pointers for each component of the destructure. This means that when the RHS is a more complicated expression, peer type resolution is not used: each result value is individually destructured and written to the result pointers. RLS is always used for destructure expressions, meaning every `const` on the LHS of such an expression creates a true stack allocation. Aside from anonymous array literals, Sema is capable of destructuring the following types: * Tuples * Arrays * Vectors A destructure may be prefixed with the `comptime` keyword, in which case the entire destructure is evaluated at comptime: this means all `var`s in the LHS are `comptime var`s, every lvalue expression is evaluated at comptime, and the RHS is evaluated at comptime. If every LHS is a `const`, this is not allowed: as with single declarations, the user should instead mark the RHS as `comptime`. There are a few subtleties in the grammar changes here. For one thing, if every LHS is an lvalue expression (rather than a var decl), a destructure is considered an expression. This makes, for instance, `if (cond) x, y = .{ 1, 2 };` valid Zig code. A destructure is allowed in almost every context where a standard assignment expression is permitted. The exception is `switch` prongs, which cannot be destructures as the comma is ambiguous with the end of the prong. A follow-up commit will begin utilizing this syntax in the Zig compiler. Resolves: #498
2023-09-15AstGen: do not forward result pointers through @asmlugg
The `coerce_result_ptr` instruction is highly problematic and leads to unintentional memory reinterpretation in some cases. It is more correct to simply not forward result pointers through this builtin. `coerce_result_ptr` is still used for struct and array initializations, where it can still cause issues. Eliminating this usage will be a future change. Resolves: #16991
2023-09-07AstGen: fix missing array type validationVeikka Tuominen
Closes #17084
2023-09-05AstGen: fix error on missing function prototype nameVeikka Tuominen
Closes #17070
2023-08-28compiler: provide result type for @memset valuemlugg
Resolves: #16986
2023-08-28Sema: allow cast builtins on vectorsmlugg
The following cast builtins did not previously work on vectors, and have been made to: * `@floatCast` * `@ptrFromInt` * `@intFromPtr` * `@floatFromInt` * `@intFromFloat` * `@intFromBool` Resolves: #16267
2023-08-22compiler: move unions into InternPoolAndrew Kelley
There are a couple concepts here worth understanding: Key.UnionType - This type is available *before* resolving the union's fields. The enum tag type, number of fields, and field names, field types, and field alignments are not available with this. InternPool.UnionType - This one can be obtained from the above type with `InternPool.loadUnionType` which asserts that the union's enum tag type has been resolved. This one has all the information available. Additionally: * ZIR: Turn an unused bit into `any_aligned_fields` flag to help semantic analysis know whether a union has explicit alignment on any fields (usually not). * Sema: delete `resolveTypeRequiresComptime` which had the same type signature and near-duplicate logic to `typeRequiresComptime`. - Make opaque types not report comptime-only (this was inconsistent between the two implementations of this function). * Implement accepted proposal #12556 which is a breaking change.
2023-08-21AstGen: disallow '-0' integer literalmlugg
The intent here is ambiguous: this resolves to the comptime_int '0', but it's likely the user meant to use a floating-point literal. Resolves: #16890
2023-08-20AstGen: add result location analysis passmlugg
The main motivation for this change is eliminating the `block_ptr` result location and corresponding `store_to_block_ptr` ZIR instruction. This is achieved through a simple pass over the AST before AstGen which determines, for AST nodes which have a choice on whether to provide a result location, which choice to make, based on whether the result pointer is consumed non-trivially. This eliminates so much logic from AstGen that we almost break even on line count! AstGen no longer has to worry about instruction rewriting based on whether or not a result location was consumed: it always knows what to do ahead of time, which simplifies a *lot* of logic. This also incidentally fixes a few random AstGen bugs related to result location handling, leading to the changes in `test/` and `lib/std/`. This opens the door to future RLS improvements by making them much easier to implement correctly, and fixes many bugs. Most ZIR is made more compact after this commit, mainly due to not having redundant `store_to_block_ptr` instructions lying around, but also due to a few bugs in the old system which are implicitly fixed here.
2023-08-15InternPool: preserve indices of builtin types when resolvedmlugg
Some builtin types have a special InternPool index (e.g. `.type_info_type`) so that AstGen can refer to them before semantic analysis. Unfortunately, this previously led to a second index existing to refer to the type once it was resolved, complicating Sema by having the concept of an "unresolved" type index. This change makes Sema modify these InternPool indices in-place to contain the expanded representation when resolved. The analysis of the corresponding decls is caught in `Module.semaDecl`, and a field is set on Sema telling it which index to place struct/union/enum types at. This system could break if `std.builtin` contained complex decls which evaluate multiple struct types, but this will be caught by the assertions in `InternPool.resolveBuiltinType`. The AstGen result types which were disabled in 6917a8c have been re-enabled. Resolves: #16603
2023-08-12AstGen: cleanup `@as` invasionJacob Young
2023-08-12AstGen: fix src loc for invalid switch expression rls coercionsJacob Young
2023-08-12AstGen: fix src loc for invalid coercion in breaksJacob Young
2023-08-12AstGen: fix src loc for invalid coercions in tuple literalsJacob Young
2023-08-12AstGen: fix src loc for invalid if expression rls coercionsJacob Young
Closes #12509
2023-08-09compiler: fix crash on invalid result type for `@splat`mlugg
This introduces a new ZIR instruction, `vec_elem_type`. Co-Authored-By: Ali Chraghi <alichraghi@proton.me> Resolves: #16567
2023-08-09AstGen: handle `ty` result location for struct and array init correctlymlugg
Well, this was a journey! The original issue I was trying to fix is covered by the new behavior test in array.zig: in essence, `ty` and `coerced_ty` result locations were not correctly propagated. While fixing this, I noticed a similar bug in struct inits: the type was propagated to *fields* fine, but the actual struct init was unnecessarily anonymous, which could lead to unnecessary copies. Note that the behavior test added in struct.zig was already passing - the bug here didn't change any easy-to-test behavior - but I figured I'd add it anyway. This is a little harder than it seems, because the result type may not itself be an array/struct type: it could be an optional / error union wrapper. A new ZIR instruction is introduced to unwrap these. This is also made a little tricky by the fact that it's possible for result types to be unknown at the time of semantic analysis (due to `anytype` parameters), leading to generic poison. In these cases, we must essentially downgrade to an anonymous initialization. Fixing these issues exposed *another* bug, related to type resolution in Sema. That issue is now tracked by #16603. As a temporary workaround for this bug, a few result locations for builtin function operands have been disabled in AstGen. This is technically a breaking change, but it's very minor: I doubt it'll cause any breakage in the wild.
2023-07-27frontend: make fn calls byval; fix false positive isNonErrAndrew Kelley
This commit does two things which seem unrelated at first, but, together, solve a miscompilation, and potentially slightly speed up compiler perf, at the expense of making #2765 trickier to implement in the future. Sema: avoid returning a false positive for whether an inferred error set is comptime-known to be empty. AstGen: mark function calls as not being interested in a result location. This prevents the test case "ret_ptr doesn't cause own inferred error set to be resolved" from being regressed. If we want to accept and implement #2765 in the future, it will require solving this problem a different way, but the principle of YAGNI tells us to go ahead with this change. Old ZIR looks like this: %97 = ret_ptr() %101 = store_node(%97, %100) %102 = load(%97) %103 = ret_is_non_err(%102) New ZIR looks like this: %97 = ret_type() %101 = as_node(%97, %100) %102 = ret_is_non_err(%101) closes #15669
2023-07-26AstGen: fix missing deferred refJacob Young
Closes #16524
2023-07-25frontend: forbid packed and extern tuplesAndrew Kelley
2023-07-25AstGen: avoid unnecessary mutable localAndrew Kelley
2023-07-21fix some whitespace formatting in `switch`sr00ster91
If you view this commit with `git show -w`, there is no diff.
2023-07-18AstGen: idiomatic use of switchAndrew Kelley
2023-07-12Remove len parameter from splat builtin functionantlilja
Resolve the result type of the splat builtin instead of requiring a length parameter.
2023-07-11Fixes wrong error location for unionInit when first parameter is not a type ↵Anton Lilja
(#16384)
2023-07-10AstGen: make sure for range start and end are usizesr00ster91
Fixes #16311 The actual cause of #16311 is the `start_is_zero` special case: ```zig const range_len = if (end_val == .none or start_is_zero) end_val else try parent_gz.addPlNode(.sub, input, Zir.Inst.Bin{ .lhs = end_val, .rhs = start_val, }); ``` It only happens if the range start is 0. In that case we would not perform any type checking. Only in the other cases coincidentally `.sub` performs type checking in Sema, but the errors are still rather poor: ``` $ zig test x.zig x.zig:9:15: error: invalid operands to binary expression: 'Pointer' and 'Pointer' for ("abc".."def") |val| { ~~~~~^~~~~~~ ``` Note how it's the same as if I use `-`: ``` x.zig:9:11: error: invalid operands to binary expression: 'Pointer' and 'Pointer' "abc" - "def"; ~~~~~~^~~~~~~ ``` Now after this PR, the errors are much clearer for both range start and end: ``` x.zig:9:10: error: expected type 'usize', found '*const [3:0]u8' for ("abc".."def") |val| { ^~~~~ ``` This is why I decided to use `.ty` instead of `.coerced_ty` for both range start and end rather than just perform type checking in that `end_val == .none or start_is_zero` case.
2023-06-26AstGen: fix result locations for elements of typed array initmlugg
Resolves: #16226
2023-06-25Merge pull request #16192 from mlugg/builtins-infer-dest-ty-fixesAndrew Kelley
Follow-up to cast builtin result type inference
2023-06-25AstGen: add source location to certain const initializersJacob Young
Before: assign_local_bad_coercion.zig:5:1: error: expected type 'u32', found 'u64' export fn constEntry() u32 { ^~~~~~ assign_local_bad_coercion.zig:11:19: error: expected type 'u32', found 'u64' var x: u32 = g(); ~^~ After: assign_local_bad_coercion.zig:6:21: error: expected type 'u32', found 'u64' const x: u32 = g(); ~^~ assign_local_bad_coercion.zig:11:19: error: expected type 'u32', found 'u64' var x: u32 = g(); ~^~
2023-06-25compiler: allow cast builtins to coerce result to error union or optionalmlugg
Also improves some error messages
2023-06-25AstGen: use usize as result type of for loop range operandsmlugg
2023-06-24all: migrate code to new cast builtin syntaxmlugg
Most of this migration was performed automatically with `zig fmt`. There were a few exceptions which I had to manually fix: * `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten * `@truncate`'s fixup is incorrect for vectors * Test cases are not formatted, and their error locations change
2023-06-24compiler: remove destination type from cast builtinsmlugg
Resolves: #5909
2023-06-19all: zig fmt and rename "@XToY" to "@YFromX"Eric Joldasov
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-19compiler: rename "@XToY" to "@YFromX", zig fmt: rewrite themEric Joldasov
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-13Eliminate switch_cond[_ref] ZIR tagsmlugg
This finishes the process of consolidating switch expressions in ZIR into as simple and compact a representation as is possible. There are now just two ZIR tags dedicated to switch expressions: switch_block and switch_block_ref, with the latter being for an operand passed by reference.
2023-06-13Eliminate switch_capture_tag ZIR instructionmlugg
This is a follow-up to a previous commit which eliminated switch_capture and switch_capture_ref. All captures are now handled directly by `switch_block`, which has also eliminated some unnecessary Block data in Sema.
2023-06-13Eliminate switch_capture and switch_capture_ref ZIR tagsmlugg
These tags are unnecessary, as this information can be more efficiently encoded within the switch_block instruction itself. We also use a neat little trick to avoid needing a dummy instruction (like is used for errdefer captures): since the switch_block itself cannot otherwise be referenced within a prong, we can repurpose its index within prongs to refer to the captured value.
2023-06-13Move switch case value coercion from AstGen to Semamlugg
This is in preparation for #2473. Also fixes a bug where switching on bools allows invalid case combinations.
2023-06-13Zir: remove unnecessary switch_capture_multi instructionsmlugg
By indexing from the very first switch case rather than into scalar and multi cases separately, the instructions for capturing in multi cases become unnecessary, freeing up 2 ZIR tags.
2023-06-10AstGen: generate tests with anyerror!voidAndrew Kelley
rather than inferred error sets. This avoids extra unnecessary work for the compiler since inferred error sets are unique types.
2023-06-10InternPool: port most of value tagsJacob Young
2023-06-10stage2: move enum types into the InternPoolAndrew Kelley
Unlike unions and structs, enums are actually *encoded* into the InternPool directly, rather than using the SegmentedList trick. This results in them being quite compact, and greatly improved the ergonomics of using enum types throughout the compiler. It did however require introducing a new concept to the InternPool which is an "incomplete" item - something that is added to gain a permanent Index, but which is then mutated in place. This was necessary because enum tag values and tag types may reference the namespaces created by the enum itself, which required constructing the namespace, decl, and calling analyzeDecl on the decl, which required the decl value, which required the enum type, which required an InternPool index to be assigned and for it to be meaningful. The API for updating enums in place turned out to be quite slick and efficient - the methods directly populate pre-allocated arrays and return the information necessary to output the same compilation errors as before.
2023-06-10stage2: move all integer types to InternPoolAndrew Kelley
2023-06-10stage2: start the InternPool transitionAndrew Kelley
Instead of doing everything at once which is a hopelessly large task, this introduces a piecemeal transition that can be done in small increments at a time. This is a minimal changeset that keeps the compiler compiling. It only uses the InternPool for a small set of types. Behavior tests are not passing. Air.Inst.Ref and Zir.Inst.Ref are separated into different enums but compile-time verified to have the same fields in the same order. The large set of changes is mainly to deal with the fact that most Type and Value methods now require a Module to be passed in, so that the InternPool object can be accessed.
2023-06-10AstGen: handle ref_table for paramsmlugg
This is kind of similar to 1a4b0d9. In this case, we need to handle ref_table when appending the body of param instructions. Resolves: #15952