Commit graph

614 commits

Author SHA1 Message Date
mlugg
3fcb4408a5 AstGen: improve 'file cannot be a tuple' source location
Instead of just reporting this on token 0, report it on the first
tuple-like field.
2025-02-25 22:28:47 +00:00
mlugg
5e20e9b449 Sema: allow @ptrCast of slices changing the length
Also, refactor `Sema.ptrCastFull` to not be a horrifying hellscape.
2025-02-23 08:28:58 +00:00
David Rubin
36fc2d2607 AstGen: make layout specifiers on opaque containers a compile error 2025-02-22 17:21:34 -05:00
Benjamin Thompson
a8d3760c5b
added compile_error test coverage for issue 17166 2025-02-21 07:00:37 +01:00
Alex Rønne Petersen
faccd79ca5
test: Update some compiler-internal type names in expected output. 2025-02-17 19:18:20 +01:00
Alex Rønne Petersen
9c015e6c2b
std.builtin: Remove CallingConvention.arm_(apcs,aapcs16_vfp).
* arm_apcs is the long dead "OABI" which we never had working support for.
* arm_aapcs16_vfp is for arm-watchos-none which is a dead target that we've
  dropped support for.
2025-02-17 19:17:56 +01:00
Tw
d7b93c7876 Sema: make source location in checkCallConvSupportsVarArgs more meaningful
As calling convention may not be specified explicitly in the source,
so use va_arg's location instead.

Signed-off-by: Tw <tw19881113@gmail.com>
2025-02-17 05:28:11 +01:00
Jacob Young
8159ff8b81 x86_64: implement error set and enum safety
This is all of the expected 0.14.0 progress on #21530, which can now be
postponed once this commit is merged.

This required rewriting the (un)wrap operations since the original
implementations were extremely buggy.

Also adds an easy way to retrigger Sema OPV bugs so that I don't have to
keep updating #22419 all the time.
2025-02-15 03:45:21 -05:00
mlugg
75ec7d863e
Sema: add missing validateRuntimeValue calls
Resolves: #13791
2025-02-06 01:11:10 +00:00
mlugg
456f3c026b
Sema: fix crash on @tagName of undefined enum literal
Resolves: #20826
2025-02-05 19:08:05 +00:00
mlugg
3ce857d054
Sema: fix incorrectly succeeding type resolution
Resolves: #21436
2025-02-05 18:31:39 +00:00
Matthew Lugg
f01f1e33c9
Merge pull request #22754 from mlugg/files-and-stuff
ZON and incremental bits
2025-02-05 12:17:13 +00:00
Will Lillis
cf059ee087
AstGen: improve error for invalid bytes in strings and comments 2025-02-05 11:10:11 +02:00
mlugg
bebfa036ba
test: remove failing case
Unfortunately, now that this error is more in line with other `@import`
errors, it isn't so easy to have a test case for.
2025-02-04 18:30:50 +00:00
Mason Remaley
13c6eb0d71
compiler,std: implement ZON support
This commit allows using ZON (Zig Object Notation) in a few ways.

* `@import` can be used to load ZON at comptime and convert it to a
  normal Zig value. In this case, `@import` must have a result type.
* `std.zon.parse` can be used to parse ZON at runtime, akin to the
  parsing logic in `std.json`.
* `std.zon.stringify` can be used to convert arbitrary data structures
  to ZON at runtime, again akin to `std.json`.
2025-02-03 09:14:37 +00:00
Will Lillis
953355ebea
fix: error on non-exhaustive enums with zero width backing type (#21374)
Co-authored-by: WillLillis <wlillis@umass.edu>
2025-02-02 03:36:16 +00:00
Andrew Kelley
963651bbf2
Merge pull request #22672 from jacobly0/x86_64-rewrite
x86_64: rewrite float conversions
2025-02-01 14:32:43 -08:00
mlugg
3924f173af compiler: do not propagate result type to try operand
This commit effectively reverts 9e683f0, and hence un-accepts #19777.
While nice in theory, this proposal turned out to have a few problems.

Firstly, supplying a result type implicitly coerces the operand to this
type -- that's the main point of result types! But for `try`, this is
actually a bad idea; we want a redundant `try` to be a compile error,
not to silently coerce the non-error value to an error union. In
practice, this didn't always happen, because the implementation was
buggy anyway; but when it did, it was really quite silly. For instance,
`try try ... try .{ ... }` was an accepted expression, with the inner
initializer being initially coerced to `E!E!...E!T`.

Secondly, the result type inference here didn't play nicely with
`return`. If you write `return try`, the operand would actually receive
a result type of `E!E!T`, since the `return` gave a result type of `E!T`
and the `try` wrapped it in *another* error union. More generally, the
problem here is that `try` doesn't know when it should or shouldn't
nest error unions. This occasionally broke code which looked like it
should work.

So, this commit prevents `try` from propagating result types through to
its operand. A key motivation for the original proposal here was decl
literals; so, as a special case, `try .foo(...)` is still an allowed
syntax form, caught by AstGen and specially lowered. This does open the
doors to allowing other special cases for decl literals in future, such
as `.foo(...) catch ...`, but those proposals are for another time.

Resolves: #21991
Resolves: #22633
2025-02-01 15:48:45 +00:00
Jacob Young
b9531f5de6 x86_64: rewrite float vector conversions 2025-01-31 23:00:34 -05:00
mlugg
107b65ec5d Sema: explain why we tried to call an extern fn at comptime
I recently saw a user hit the "comptime call of extern function" error,
and get confused because they didn't know why the scope was `comptime`.
So, use `explainWhyBlockIsComptime` on this and related errors to add
all the relevant notes.

The added test case shows the motivating situation.
2025-01-29 18:43:24 +00:00
mlugg
71d16106ad Sema: @memcpy changes
* The langspec definition of `@memcpy` has been changed so that the
  source and destination element types must be in-memory coercible,
  allowing all such calls to be raw copying operations, not actually
  applying any coercions.
* Implement aliasing check for comptime `@memcpy`; a compile error will
  now be emitted if the arguments alias.
* Implement more efficient comptime `@memcpy` by loading and storing a
  whole array at once, similar to how `@memset` is implemented.
2025-01-29 06:35:22 +00:00
Will Lillis
672bc8141f
fix: Only suggest try on destructure of error union if payload type can be destructured (#21510) 2025-01-26 19:38:07 +01:00
Andrew Kelley
d0d5ca2b6c
Merge pull request #22581 from jacobly0/x86_64-rewrite
x86_64: rewrite `@abs` on floats
2025-01-25 07:30:45 -08:00
Jacob Young
c7433212d1 x86_64: rewrite scalar and vector int @min and @max 2025-01-24 21:02:32 -05:00
Jacob Young
ba82d6e83e x86_64: fix typo and lower optimized insts 2025-01-24 20:56:11 -05:00
mlugg
5a6666db55
all: update for panic.unwrapError and panic.call signature changes 2025-01-24 22:33:23 +00:00
mlugg
83991efe10
compiler: yet more panic handler changes
* `std.builtin.Panic` -> `std.builtin.panic`, because it is a namespace.
* `root.Panic` -> `root.panic` for the same reason. There are type
  checks so that we still allow the legacy `pub fn panic` strategy in
  the 0.14.0 release.
* `std.debug.SimplePanic` -> `std.debug.simple_panic`, same reason.
* `std.debug.NoPanic` -> `std.debug.no_panic`, same reason.
* `std.debug.FormattedPanic` is now a function `std.debug.FullPanic`
  which takes as input a `panicFn` and returns a namespace with all the
  panic functions. This handles the incredibly common case of just
  wanting to override how the message is printed, whilst keeping nice
  formatted panics.
* Remove `std.builtin.panic.messages`; now, every safety panic has its
  own function. This reduces binary bloat, as calls to these functions
  no longer need to prepare any arguments (aside from the error return
  trace).
* Remove some legacy declarations, since a zig1.wasm update has
  happened. Most of these were related to the panic handler, but a quick
  grep for "zig1" brought up a couple more results too.

Also, add some missing type checks to Sema.

Resolves: #22584

formatted -> full
2025-01-24 19:29:51 +00:00
Matthew Lugg
0e815c652d
Merge pull request #22572 from jacobly0/new-error-trace
compiler: include error trace in all functions, implement for x86_64 backend
2025-01-22 16:48:27 +00:00
Jacob Young
d4b6a53327 x86_64: implement error return traces 2025-01-22 03:44:13 -05:00
mlugg
e864c38cc3
Sema: fix crash when inline loop condition is not comptime-known 2025-01-22 04:18:43 +00:00
mlugg
8470b6ea37
Zcu: fix switch prong source location resolution
Resolves: #22343
2025-01-22 04:11:02 +00:00
mlugg
0ec6b2dd88 compiler: simplify generic functions, fix issues with inline calls
The original motivation here was to fix regressions caused by #22414.
However, while working on this, I ended up discussing a language
simplification with Andrew, which changes things a little from how they
worked before #22414.

The main user-facing change here is that any reference to a prior
function parameter, even if potentially comptime-known at the usage
site or even not analyzed, now makes a function generic. This applies
even if the parameter being referenced is not a `comptime` parameter,
since it could still be populated when performing an inline call. This
is a breaking language change.

The detection of this is done in AstGen; when evaluating a parameter
type or return type, we track whether it referenced any prior parameter,
and if so, we mark this type as being "generic" in ZIR. This will cause
Sema to not evaluate it until the time of instantiation or inline call.

A lovely consequence of this from an implementation perspective is that
it eliminates the need for most of the "generic poison" system. In
particular, `error.GenericPoison` is now completely unnecessary, because
we identify generic expressions earlier in the pipeline; this simplifies
the compiler and avoids redundant work. This also entirely eliminates
the concept of the "generic poison value". The only remnant of this
system is the "generic poison type" (`Type.generic_poison` and
`InternPool.Index.generic_poison_type`). This type is used in two
places:

* During semantic analysis, to represent an unknown result type.
* When storing generic function types, to represent a generic parameter/return type.

It's possible that these use cases should instead use `.none`, but I
leave that investigation to a future adventurer.

One last thing. Prior to #22414, inline calls were a little inefficient,
because they re-evaluated even non-generic parameter types whenever they
were called. Changing this behavior is what ultimately led to #22538.
Well, because the new logic will mark a type expression as generic if
there is any change its resolved type could differ in an inline call,
this redundant work is unnecessary! So, this is another way in which the
new design reduces redundant work and complexity.

Resolves: #22494
Resolves: #22532
Resolves: #22538
2025-01-21 02:41:42 +00:00
mlugg
8bcb578507 Sema: fix is_non_null_ptr handling for runtime-known pointers
We can still often determine a comptime result based on the type, even
if the pointer is runtime-known.

Also, we previously used load -> is non null instead of AIR
`is_non_null_ptr` if the pointer is comptime-known, but that's a bad
heuristic. Instead, we should check for the pointer to be
comptime-known, *and* for the load to be comptime-known, and only in
that case should we call `Sema.analyzeIsNonNull`.

Resolves: #22556
2025-01-21 00:33:32 +00:00
mlugg
9804cc8bc6
all: update to std.builtin.Type.{Pointer,Array,StructField} field renames 2025-01-16 12:49:58 +00:00
mlugg
d00e05f186
all: update to std.builtin.Type.Pointer.Size field renames
This was done by regex substitution with `sed`. I then manually went
over the entire diff and fixed any incorrect changes.

This diff also changes a lot of `callconv(.C)` to `callconv(.c)`, since
my regex happened to also trigger here. I opted to leave these changes
in, since they *are* a correct migration, even if they're not the one I
was trying to do!
2025-01-16 12:46:29 +00:00
mlugg
4b910e525d Sema: more validation for builtin decl types
Also improve the source locations when this validation fails.

Resolves: #22465
2025-01-14 22:44:18 +00:00
mlugg
5322459a0b Sema: fix UB in error reporting
And add test coverage for the compile error in question.
2025-01-14 21:17:46 +00:00
mlugg
27274d4fde Type: struct {} does not have a well-defined layout
`Type.hasWellDefinedLayout` was in disagreement with pointer loading
logic about auto-layout structs with zero fields, `struct {}`. For
consistency, these types should not have a well-defined layout.

This is technically a breaking change.
2025-01-14 20:27:49 +00:00
xdBronch
fb43e91b22
Sema: disallow non scalar sentinels in array types and reified types (#22473) 2025-01-13 05:28:53 +00:00
mlugg
04c9f50aec compiler: improve "... contains reference to comptime var" errors
`Sema.explainWhyValueContainsReferenceToComptimeVar` (concise name!)
adds notes to an error explaining how to get from a given `Value` to a
pointer to some `comptime var` (or a comptime field). Previously, this
error could be very opaque in any case where it wasn't obvious where the
comptime var pointer came from; particularly for type captures. Now, the
error notes explain this to the user.
2025-01-11 08:54:47 +00:00
mlugg
e9bd2d45d4
Sema: rewrite semantic analysis of function calls
This rewrite improves some error messages, hugely simplifies the logic,
and fixes several bugs. One of these bugs is technically a new rule
which Andrew and I agreed on: if a parameter has a comptime-only type
but is not declared `comptime`, then the corresponding call argument
should not be *evaluated* at comptime; only resolved. Implementing this
required changing how function types work a little, which in turn
required allowing a new kind of function coercion for some generic use
cases: function coercions are now allowed to implicitly *remove*
`comptime` annotations from parameters with comptime-only types. This is
okay because removing the annotation affects only the call site.

Resolves: #22262
2025-01-09 06:46:47 +00:00
mlugg
b4da8eef2a Zir: split up start and end of range in for_len
The old lowering was kind of neat, but it unintentionally allowed the
syntax `for (123) |_| { ... }`, and there wasn't really a way to fix
that. So, instead, we include both the start and the end of the range in
the `for_len` instruction (each operand to `for` now has *two* entries
in this multi-op instruction). This slightly increases the size of ZIR
for loops of predominantly indexables, but the difference is small
enough that it's not worth complicating ZIR to try and fix it.
2025-01-03 22:28:37 +00:00
mlugg
5333d2443a Sema: fix invalid coercion *[n:x]T -> *[m]T for n != m
The change in `Sema.coerceExtra` is just to avoid an unhelpful error
message, covered by the added test case.

Resolves: #22373
2025-01-01 16:20:40 +00:00
mlugg
9ff80d7950
cases: update to new compile error wordings 2024-12-31 09:55:04 +00:00
mlugg
07b936c95f
cases: add cases for runtime code in comptime scopes 2024-12-31 09:55:04 +00:00
mlugg
3afda4322c
compiler: analyze type and value of global declaration separately
This commit separates semantic analysis of the annotated type vs value
of a global declaration, therefore allowing recursive and mutually
recursive values to be declared.

Every `Nav` which undergoes analysis now has *two* corresponding
`AnalUnit`s: `.{ .nav_val = n }` and `.{ .nav_ty = n }`. The `nav_val`
unit is responsible for *fully resolving* the `Nav`: determining its
value, linksection, addrspace, etc. The `nav_ty` unit, on the other
hand, resolves only the information necessary to construct a *pointer*
to the `Nav`: its type, addrspace, etc. (It does also analyze its
linksection, but that could be moved to `nav_val` I think; it doesn't
make any difference).

Analyzing a `nav_ty` for a declaration with no type annotation will just
mark a dependency on the `nav_val`, analyze it, and finish. Conversely,
analyzing a `nav_val` for a declaration *with* a type annotation will
first mark a dependency on the `nav_ty` and analyze it, using this as
the result type when evaluating the value body.

The `nav_val` and `nav_ty` units always have references to one another:
so, if a `Nav`'s type is referenced, its value implicitly is too, and
vice versa. However, these dependencies are trivial, so, to save memory,
are only known implicitly by logic in `resolveReferences`.

In general, analyzing ZIR `decl_val` will only analyze `nav_ty` of the
corresponding `Nav`. There are two exceptions to this. If the
declaration is an `extern` declaration, then we immediately ensure the
`Nav` value is resolved (which doesn't actually require any more
analysis, since such a declaration has no value body anyway).
Additionally, if the resolved type has type tag `.@"fn"`, we again
immediately resolve the `Nav` value. The latter restriction is in place
for two reasons:

* Functions are special, in that their externs are allowed to trivially
  alias; i.e. with a declaration `extern fn foo(...)`, you can write
  `const bar = foo;`. This is not allowed for non-function externs, and
  it means that function types are the only place where it is possible
  for a declaration `Nav` to have a `.@"extern"` value without actually
  being declared `extern`. We need to identify this situation
  immediately so that the `decl_ref` can create a pointer to the *real*
  extern `Nav`, not this alias.
* In certain situations, such as taking a pointer to a `Nav`, Sema needs
  to queue analysis of a runtime function if the value is a function. To
  do this, the function value needs to be known, so we need to resolve
  the value immediately upon `&foo` where `foo` is a function.

This restriction is simple to codify into the eventual language
specification, and doesn't limit the utility of this feature in
practice.

A consequence of this commit is that codegen and linking logic needs to
be more careful when looking at `Nav`s. In general:

* When `updateNav` or `updateFunc` is called, it is safe to assume that
  the `Nav` being updated (the owner `Nav` for `updateFunc`) is fully
  resolved.
* Any `Nav` whose value is/will be an `@"extern"` or a function is fully
  resolved; see `Nav.getExtern` for a helper for a common case here.
* Any other `Nav` may only have its type resolved.

This didn't seem to be too tricky to satisfy in any of the existing
codegen/linker backends.

Resolves: #131
2024-12-24 02:18:41 +00:00
mlugg
18362ebe13
Zir: refactor declaration instruction representation
The new representation is often more compact. It is also more
straightforward to understand: for instance, `extern` is represented on
the `declaration` instruction itself rather than using a special
instruction. The same applies to `var`, making both of these far more
compact.

This commit also separates the type and value bodies of a `declaration`
instruction. This is a prerequisite for #131.

In general, `declaration` now directly encodes details of the syntax
form used, and the embedded ZIR bodies are for actual expressions. The
only exception to this is functions, where ZIR is effectively designed
as if we had #1717. `extern fn` declarations are modeled as
`extern const` with a function type, and normal `fn` definitions are
modeled as `const` with a `func{,_fancy,_inferred}` instruction. This
may change in the future, but improving on this was out of scope for
this commit.
2024-12-23 21:09:17 +00:00
mlugg
eac87ea8d6
compiler: disallow align etc annotations on comptime-only globals
This includes function aliases, but not function declarations.

Also, re-introduce a target check for function alignment which was
inadvertently removed in the prior commit.
2024-12-19 03:21:56 +00:00
mlugg
7408679234
compiler: disallow callconv etc from depending on function parameters
Resolves: #22261
2024-12-18 23:06:35 +00:00
mlugg
f154cd1fdc
Sema: disallow unsafe in-memory coercions
The error messages here aren't amazing yet, but this is an improvement
on status quo, because the current behavior allows false negative
compile errors, so effectively miscompiles.

Resolves: #15874
2024-12-16 14:53:54 +00:00