# Replace \`anytype\` with \`infer T\`(or \`@Infer(T)\`)

**URL:** <https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200>\
**Category:** Brainstorming\
**Tags:** language\
**Created:** [April 27, 2026, 2:43pm UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200 "2026-04-27T14:43:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Verafahn](https://ziggit.dev/user_avatar/ziggit.dev/verafahn/32/9285_2.png) [@Verafahn](https://ziggit.dev/u/Verafahn)\
**Post date:** [April 27, 2026, 2:43pm UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/1 "2026-04-27T14:43:38Z")

</div>

`infer T` and `@Infer(T)` are completely equivalent, taking `infer T` as an example only:

## Feature

The difference from other schemes is that this allows the result position semantics to also take effect in the user function:

```zig
fn userFunc() infer T {
    // `T`, like an `anytype` parameter, depends on the location of the function call.
}

```

Moreover, treating `infer T` as a type placeholder can achieve the effect of type deconstruction:

```zig
fn func(a: []infer T) void {
    ...
}

```

## particulars

Its basic characteristics satisfy `@TypeOf(infer T) == type`. The content of `T` is derived from the context. (~~Only `@TypeOf(infer _)` can be compiled, and `@TypeOf(infer _) == type`~~ or prohibit the independent appearance of `infer`.)

Specifically, as a type placeholder, `infer T` itself is a type (similar to `u32` which is also a type). After successful deduction, `T` is a concrete type that can be used as a type value at compile time (e.g. `var x: T=...`). `infer T` cannot be used as a parameter for `@TypeOf()`(~~if not allow `@TypeOf(infer _)`~~) because it is not an expression.

Since `infer T` is considered as a type as a whole, `infer` has the highest priority in the type expression. (`@Infer(T)` does not have this issue.)

In theory, only `infer _` can compile and pass when the type cannot be deduced (because it has already been discarded). Semantically speaking, `infer _` and the current `anytype` are equivalent.

`infer _` should be used as a placeholder for the discarded part of the type. For example:

```zig
fn func(a: struct{infer _, infer T}) void {
    ...
}
func(.{10, @as(u32, 20)}); -> T == u32

```

In many cases, it can provide clearer parameter requirements than `anytype`/`anyvalue`/or others. For example, the function interface of the allocator:

```zig
pub fn destroy(self: Allocator, ptr: anytype) void {
    ...
}

pub fn free(self: Allocator, memory: anytype) void {
    ...
}

```

👇

```zig
pub fn destroy(self: Allocator, ptr: *infer T) void {
    ...
}

pub fn free(self: Allocator, memory: []infer T) void {
    ...
}

```

## Other

### Identifier reuse

For example:  
~~_The compiler checks whether the inference results of inference types with the same name are consistent._~~

```zig
pub fn swap(a: *infer T, b: *infer T) void {
    ...
}

```

Or  
_Prohibit duplicate names and manually check in the code._ (More in line with Zig.)

```zig
pub fn swap(a: *infer T, b: *infer U) void {
    std.debug.assert(T == U);
    ...
}

```

### Allow the position of `infer`

Only Function Signatures OR ~~Function Signature and Expression~~.

If available in the expression, `infer T` may be a more intuitive way of type deconstruction than `@typeInfo(T)`:

```zig
fn func(a: u32) f32 {
    ...
}

// @typeInfo
const T = @typeInfo(@TypeOf(func)).@"fn".return_type.?;

// infer
fn(u32)infer T = @TypeOf(func);

```

**Alternative solutions for expression deconstruction:**  
Package this feature as a function:

```zig
fn func(a: u32) f32 {
    ...
}

fn GetRetType(f: fn(u32) infer T) type {
    return T;
}

const U = GetRetType(func); -> U == f32

```

### ~~Inverse inference of generic functions~~

For example:

```zig
fn Gen(comptime T: type) type {
    return struct {...};
}

fn func(gen: Gen(infer T)) void {
    ...
}

func(Gen(u32)); -> T == u32
func(Gen(Gen(u32))); -> T == Gen(u32)

```

This function cannot be achieved through `@typeInfo`.

_Due to the fact that one result of a function may correspond to multiple inputs, this feature cannot be implemented._

## Ending

Original idea: [If you had one wish for zig, what would it be? - #23 by Dok8tavo](https://ziggit.dev/t/if-you-had-one-wish-for-zig-what-would-it-be/15069/23)

@Dok8tavo

---

<div class="post-metadata">

**Author:** ![chrboesch](https://ziggit.dev/user_avatar/ziggit.dev/chrboesch/32/438_2.png) [@chrboesch](https://ziggit.dev/u/chrboesch)\
**Post date:** [April 27, 2026, 2:54pm UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/2 "2026-04-27T14:54:21Z")

</div>

Why don’t you contribute your idea to this discussion: [Anytype is getting renamed to anyval (!) - #35 by alanza](https://ziggit.dev/t/anytype-is-getting-renamed-to-anyval/15126/35)

---

<div class="post-metadata">

**Author:** ![Verafahn](https://ziggit.dev/user_avatar/ziggit.dev/verafahn/32/9285_2.png) [@Verafahn](https://ziggit.dev/u/Verafahn)\
**Post date:** [April 27, 2026, 3:10pm UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/3 "2026-04-27T15:10:26Z")

</div>

Thanks for the heads-up. However, `infer T` is more than just a rename — its design goes beyond what `anytype` covers. **I think it deserves a separate discussion.** I’ll check out the thread you mentioned. Thanks!

---

<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:** [April 28, 2026, 12:53am UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/4 "2026-04-28T00:53:42Z")

</div>

I can’t find the issue but `infer T` (excluding your expression deconstruction) was officially proposed and **rejected**.

And there were many similar and also very different proposals to replace `anytype` that were also rejected.

---

<div class="post-metadata">

**Author:** ![npc1054657282](https://ziggit.dev/user_avatar/ziggit.dev/npc1054657282/32/5790_2.png) [@npc1054657282](https://ziggit.dev/u/npc1054657282)\
**Post date:** [April 28, 2026, 2:58am UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/5 "2026-04-28T02:58:36Z")

</div>

It should be [this issue](https://github.com/ziglang/zig/issues/9260).

But, well, it seems that it is now [being reconsidered in another form](https://codeberg.org/ziglang/zig/issues/32099).

---

<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:** [April 28, 2026, 3:00am UTC](https://ziggit.dev/t/replace-anytype-with-infer-t-or-infer-t/15200/6 "2026-04-28T03:00:48Z")

</div>

so its just `infer T` but with capture syntax, which kind of makes sense since you are “capturing the type of a value/expression”
