# What are we expecting in 0.17?

**URL:** <https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438>\
**Category:** Explain\
**Tags:** language\
**Created:** [September 1, 2026, 7:07pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438 "2026-09-01T19:07:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![IbrahimOuhamou](https://ziggit.dev/user_avatar/ziggit.dev/ibrahimouhamou/32/2344_2.png) [@IbrahimOuhamou](https://ziggit.dev/u/IbrahimOuhamou)\
**Post date:** [September 1, 2026, 7:07pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/1 "2026-09-01T19:07:17Z")

</div>

a long time has passed since 0.16, I didn’t really find that many compilation errors upgrading from 0.16 (except ‘++’ and ‘\*\*’)

it doesn’t have to be accurate, just what comes to mind

---

<div class="post-metadata">

**Author:** ![Plebosaur](https://ziggit.dev/user_avatar/ziggit.dev/plebosaur/32/6857_2.png) [@Plebosaur](https://ziggit.dev/u/Plebosaur)\
**Post date:** [September 1, 2026, 7:13pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/2 "2026-09-01T19:13:02Z")

</div>

For me the main ones in the migration were:

1. `void` can’t be initialized with `.{}` or `void{}`, use `{}`
2. @Vector is disallowed in extern unions, just use an array and use coercion. Example:

```zig
// Before
const Food = extern union {
     breakdown: struct {...},
     arr: [8]f32,
     vec: @Vector(8, f32),
};
// To add a.vec = b.vec + c.vec;

// After
const Food = extern union {
     breakdown: struct {...},
     arr: [8]f32,

     pub fn vec(self: @This()) @Vector(8, f32) {
          return self.arr;
     }
}
// To add a.arr = b.vec() + c.vec();

```

1. @Bitcast no longer works on extern structs, you can implement a userland bitcast for those use cases:

```zig
// My best friend has returned!
fn bitCast(T: type, value: anytype) T {
    const N = @sizeOf(T);
    if (@sizeOf(@TypeOf(value)) != N) @compileError("Bitcast must have equal sizes");

    var ans: T = undefined;
    const ansBytes: *[N]u8 = @ptrCast(&ans);
    ansBytes.* = @as(*const [N]u8, @ptrCast(&value)).*;
    return ans;
}

// Example
const S = extern struct{
    a: f32,
    b: f32,
};

// To convert to [2]f32:
// const C = bitCast([2]f32, myVariable);

```

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [September 1, 2026, 8:51pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/3 "2026-09-01T20:51:25Z")

</div>

The main thing I’m aware of this release cycle is that the `make` and the `configure` steps of `zig build` are now separate processes. Also the elements of the `OptimizeMode` enum were renamed, which mostly only affects you if you were writing `mode == .Debug`.

I’m not an expert, but: the `configure` step (which includes running your `build.zig` logic) is compiled in debug mode (so safety gains and also if you’re on `x86_64`, you benefit from the speed of the self-hosted backend), while the `maker` is compiled in `ReleaseSafe` (I think? which is also now just `safe` maybe?), so you get some speed gains, the configure and make steps being separated is good for the possibility of further sandboxing arbitrary (build) code execution down the line, and more of the compiler can be shipped as source code, which helps binary and tarball size (since typically that source code was coming your way anyway) and i’m told also makes tinkering on the compiler a bit easier.

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [September 1, 2026, 8:59pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/4 "2026-09-01T20:59:29Z")

</div>

The groundwork for the compiler server, api to interact for 3rd party tooling, which should make zls (and others) much better.

(you won’t see improvement in this release, currently it only provides parity with existing ways to get info)

---

<div class="post-metadata">

**Author:** ![IbrahimOuhamou](https://ziggit.dev/user_avatar/ziggit.dev/ibrahimouhamou/32/2344_2.png) [@IbrahimOuhamou](https://ziggit.dev/u/IbrahimOuhamou)\
**Post date:** [September 1, 2026, 9:51pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/5 "2026-09-01T21:51:39Z")

</div>

> [@alanza](#):
>
> which includes running your `build.zig` logic

someday, insha’Allah, hopefully, I will ask how zig.build is executed, for some reason I always postpone asking the question

> [@Plebosaur](#):
>
> @Bitcast no longer works on extern structs, you can implement a userland bitcast for those use cases:

oh, thanks. did not expect things related to `extern` to ever change (since the C ABI is old and stable), I think I should give actually learn about it

> [@vulpesx](#):
>
> you won’t see improvement in this release

isn’t the evented io being implemented, and the translate-c is supposed to work with gtk on .17? but the team working on the backend makes me feel happy, maybe because it means it’s getting more and more stable (getting closer to its last shape)

anyways, thanks for your responses, I was afraid I was missing something or using some deprecated features without checking the docs

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [September 1, 2026, 10:04pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/6 "2026-09-01T22:04:24Z")

</div>

> [@IbrahimOuhamou](#):
>
> isn’t the evented io being implemented, and the translate-c is supposed to work with gtk on .17? but the team working on the backend makes me feel happy, maybe because it means it’s getting more and more stable (getting closer to its last shape)

Neither evented Io nor the backends have anything to do with what I was talking about.

I mean the new API to interact with the compiler for tools like zls, won’t provide a noticeable improvement to zls in 0.17, but future releases will enable zls, and other tools, to do more.

Other features may be noticeably improved.

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [September 1, 2026, 10:14pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/7 "2026-09-01T22:14:33Z")

</div>

Devlog is a good preview:

> **[Devlog
      ⚡
      Zig Programming Language](https://ziglang.org/devlog/2026/)**

---

<div class="post-metadata">

**Author:** ![IbrahimOuhamou](https://ziggit.dev/user_avatar/ziggit.dev/ibrahimouhamou/32/2344_2.png) [@IbrahimOuhamou](https://ziggit.dev/u/IbrahimOuhamou)\
**Post date:** [September 1, 2026, 10:46pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/8 "2026-09-01T22:46:47Z")

</div>

I love reading those, but I did not want to bother you guys from the Zig team with this question.  
though if you could allow me to ask a favor from you man, can you someday -only on your free time and if you feel like it- tell us why adding `Canceled` to `Io.Reader` is objectively wrong, because from what I understand from your talks, I believed it was already included. so now I do feel like I’m missing on some very important information. thanks, and sorry for the bother (I hate bothering people, not shy)

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [September 1, 2026, 11:43pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/9 "2026-09-01T23:43:25Z")

</div>

Let me turn the question around for you: why not add `error.OutOfMemory` to `Io.Reader`?

---

<div class="post-metadata">

**Author:** ![IbrahimOuhamou](https://ziggit.dev/user_avatar/ziggit.dev/ibrahimouhamou/32/2344_2.png) [@IbrahimOuhamou](https://ziggit.dev/u/IbrahimOuhamou)\
**Post date:** [September 2, 2026, 7:31am UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/10 "2026-09-02T07:31:52Z")

</div>

because it does not belong to it… unexpectedly, that helped me understand.  
so “it was not designed to have [responsibility for] this error in first place” 'k, got it

note: I feel silly because I only just read the contents of `Io.Reader.Error`. now the rest of this post seems pointless, anyways, thanks for the answer

---

<div class="post-metadata">

**Author:** ![ecejeff](https://ziggit.dev/letter_avatar_proxy/v4/letter/e/a88e4f/32.png) [@ecejeff](https://ziggit.dev/u/ecejeff)\
**Post date:** [September 2, 2026, 10:59am UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/11 "2026-09-02T10:59:08Z")

</div>

> [@andrewrk](#):
>
> Let me turn the question around for you: why not add `error.OutOfMemory` to `Io.Reader`?

Surely it does belong in some situations? Just like reader functions are infallible in some situations? Shouldn’t it be solved by some kind of metaprogramming to include the exact error set in the exact reader?

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [September 2, 2026, 11:49am UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/12 "2026-09-02T11:49:22Z")

</div>

> [@ecejeff](#):
>
> Surely it does belong in some situations? Just like reader functions are infallible in some situations? Shouldn’t it be solved by some kind of metaprogramming to include the exact error set in the exact reader?

The reader/writer APIs used to be generic, they were a mess because of it.

The new APIs do support arbitrary errors, in the form of the vague `error.ReadFailed`/`error.WriteFailed`; it is then up to the implementation to provide something more useful through some other means, and this is fine in practice since you just don’t need to care about implementation-specific errors unless you have access to the implementation already (surely there is an exception, but I haven’t found it).

For `error.OutOfMemory` specifically, only (in std) `Writer.Allocating` would use it, and doesnt have any other error, so `error.WriteFailed` always means `error.OutOfMemory`, no need to do any special handling there.

---

<div class="post-metadata">

**Author:** ![ecejeff](https://ziggit.dev/letter_avatar_proxy/v4/letter/e/a88e4f/32.png) [@ecejeff](https://ziggit.dev/u/ecejeff)\
**Post date:** [September 2, 2026, 12:23pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/13 "2026-09-02T12:23:32Z")

</div>

> [@vulpesx](#):
>
> The reader/writer APIs used to be generic, they were a mess because of it.

They used to be generic, but they weren’t a mess because of that specifically. They were a mess because it wasn’t the right abstraction. See Andrew Kelley’s talk [Don’t Forget To Flush](https://www.youtube.com/watch?v=f30PceqQWko) if you’d like more details. Including the buffer in the interface (aka above the vtable) is a profound and highly beneficial change. The new implementation also allows a single instance of the machine code, which has performance benefits because of instruction caches.

I’m suggesting being generic only on the return error type. I’m not suggesting monomorphizing the entirety of the Reader (which would throw away those performance improvements). A cast of `anyerror` to the specific error set shouldn’t have to duplicate the machine code.

This sort of generalization has president in the standard library in at least once place I can point to: [Queue](https://ziglang.org/documentation/0.16.0/std/#std.Io.Queue) and [TypeErasedQueue](https://ziglang.org/documentation/0.16.0/std/#std.Io.TypeErasedQueue). There are probably many other examples.

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [September 2, 2026, 12:29pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/14 "2026-09-02T12:29:31Z")

</div>

Sorry, that was an oversimplification; I am aware of the specifics, the generics were more of an issue of how zig does them, and because readers/writers get nested, resulting in hard to specify types, or overuse of `anytype`. And ofc, the api was just poorly designed.

My point was you’d be introducing back the pain of generics, that wasn’t the main issue, but it was a major pain point. Being more specific and scoped with generics does lessen the issue, but nested generics will always be a pain in zig.

---

<div class="post-metadata">

**Author:** ![ecejeff](https://ziggit.dev/letter_avatar_proxy/v4/letter/e/a88e4f/32.png) [@ecejeff](https://ziggit.dev/u/ecejeff)\
**Post date:** [September 2, 2026, 12:45pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/15 "2026-09-02T12:45:37Z")

</div>

Zig already has an error system that’s a joy to work with. Why does Reader introduce a worse error system? Usually friction in Zig is intentional. It’s to save the user from a pitfall they might not otherwise know about.

I don’t believe this friction is intentional. I also don’t believe there’s no way to remove this friction.

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [September 2, 2026, 1:17pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/16 "2026-09-02T13:17:43Z")

</div>

Suppose the return type is the only thing that’s generic about `Io.Writer` and that you are trying to write some data that gets compressed or not based on runtime information and then written to a file.

In status quo `std`, I believe there either is or was a deflate implementation (I haven’t used it). Assuming it is there, when you want to compress things, you can patch it into your `Io.Writer` chain and you’re good to focus on the logic of your program.

If the error return type is generic, suddenly it gets much harder to provide a plug-and-play deflate implementation in this way, because it matters where the deflate bit got its data from (because the possible errors it has to react to are different). And now you have to work with code paths of different types (literally) at runtime based on whether you’re compressing or not.

This is the pitfall you sound like you might not otherwise know about.

---

<div class="post-metadata">

**Author:** ![ecejeff](https://ziggit.dev/letter_avatar_proxy/v4/letter/e/a88e4f/32.png) [@ecejeff](https://ziggit.dev/u/ecejeff)\
**Post date:** [September 2, 2026, 1:28pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/17 "2026-09-02T13:28:59Z")

</div>

> [@alanza](#):
>
> If the error return type is generic, suddenly it gets much harder to provide a plug-and-play deflate implementation in this way, because it matters where the deflate bit got its data from (because the possible errors it has to react to are different). And now you have to work with code paths of different types (literally) at runtime based on whether you’re compressing or not.

Can you explain why it’s much harder? To me it seems like the generic error set of the deflate Writer would need to be the union of the underlying Writer’s generic error set and any deflate specific errors (`error.OutOfMemory`?). Surely these are the exact errors the program needs to handle?

---

<div class="post-metadata">

**Author:** ![vancluever](https://ziggit.dev/user_avatar/ziggit.dev/vancluever/32/4911_2.png) [@vancluever](https://ziggit.dev/u/vancluever)\
**Post date:** [September 2, 2026, 4:12pm UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/18 "2026-09-02T16:12:28Z")

</div>

> [@IbrahimOuhamou](#):
>
> isn’t the evented io being implemented, and the translate-c is supposed to work with gtk on .17?

BTW, you can get GTK translating on 0.16.0 using my backported translate-c:

> [@An up-to-date backport of translate-c for 0.16.0](https://ziggit.dev/t/an-up-to-date-backport-of-translate-c-for-0-16-0/16667):
>
> Hey folks, I’ve noticed a few people posting here about having issues with translate-c since 0.16.0. I’ve been actively helping out with resolving some of the outstanding issues with Aro and translate-c as we work to update Ghostty to 0.16.0. I’m currently maintaining a branch with mostly up-to-date versions of both that you can try out [here](https://codeberg.org/vancluever/translate-c/src/branch/vancluever-0.16.x). This is the version that powers the in-flight [update PR](https://github.com/ghostty-org/ghostty/pull/12726) (almost done!). Feel free to check it out, with the caveat that it might change at any time (fet…

We use it in Ghostty and there have been no issues since it got merged late July. I’m updating the fork today!

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [September 3, 2026, 1:27am UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/19 "2026-09-03T01:27:01Z")

</div>

sure, that’s a fair point! It sounds like you would like

```zig
pub fn Writer(comptime Error: type) type {
    return struct {
        // body is status quo except with Writer.Error replaced with Error?
    };
}

```

I would not like this. For one thing, now we’re paying _twice_.

One time that we are paying is in binary size. Functions are monomorphized = reinstantiated and recompiled based on their comptime captures, so `std.Io.Writer.writeAll` now is compiled for every time `Writer(E)` is called with a different value of `E`.

And then to make matters worse, in order to provide something that is sort of like an interface, we either wind up having to have a `VTable` as well in order to let code outside of the standard library provide implementations of `drain`, or we return to the previous status quo and make `Writer` _also_ depend at comptime on the functions that would be in its `VTable`.

Now imagine a situation where you have to store a `Writer` on your context struct—but again, precisely the type of the writer it is depends on runtime information. Now we’re back to wanting to reinvent the previous status quo of `AnyWriter` so that our program passes type-checks! A sad and sorry state of affairs indeed.

---

<div class="post-metadata">

**Author:** ![KilianHanich](https://ziggit.dev/user_avatar/ziggit.dev/kilianhanich/32/8254_2.png) [@KilianHanich](https://ziggit.dev/u/KilianHanich)\
**Post date:** [September 3, 2026, 1:50am UTC](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438/20 "2026-09-03T01:50:21Z")

</div>

While we are at the topic, could I please request a review of my [PR#31579](https://codeberg.org/ziglang/zig/pulls/31579)?  
It would be nice if that manages to land before 0.17 since it’s not really big.

[Next page](https://ziggit.dev/t/what-are-we-expecting-in-0-17/17438.md?page=2)
