Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Anonymous enums can't be used with return type type #3707

Closed
MasterQ32 opened this issue Nov 17, 2019 · 6 comments
Closed

Bug: Anonymous enums can't be used with return type type #3707

MasterQ32 opened this issue Nov 17, 2019 · 6 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@MasterQ32
Copy link
Contributor

Okay, this is a weird one. Somehow zig messes up enum literals when the type is declared local as a function parameter instead of "standalone" type. This also only happens when the return type is type, other types seem to work well (i32, void, []const u8):

const RetType = type; // replace with "void" and it compiles

pub fn foo(a: enum{a,b}) RetType { unreachable; }

pub fn main() void {
    foo(.a);
}
/tmp/fail.zig:7:9: error: expected type 'enum:4:15', found 'enum:4:15'
    foo(.a);
        ^
/tmp/fail.zig:4:15: note: enum:4:15 declared here
pub fn foo(a: enum{a,b}) RetType { unreachable; }
              ^
/tmp/fail.zig:4:15: note: enum:4:15 declared here
pub fn foo(a: enum{a,b}) RetType { unreachable; }
              ^
/tmp/fail.zig:7:8: note: referenced here
    foo(.a);

Zig Version: 0.5.0+a11da3773

@MasterQ32 MasterQ32 changed the title Issue with anonymous enums and return type type Bug: Anonymous enums can't be used with return type type Nov 17, 2019
@daurnimator daurnimator added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Nov 17, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone Nov 27, 2019
@mikdusan
Copy link
Member

mikdusan commented Jan 11, 2020

This also only happens when the return type is type

It seems making the fn comptime is the confounder:

fn foo(comptime a: enum{a,b}) void { unreachable; }

pub fn main() void {
    foo(.a);
}

@MasterQ32
Copy link
Contributor Author

This bug still persists, but i could narrow it down a bit:

// making the parameter comptime enforces the error,
// making it runtime removes it.
pub fn foo(comptime a: enum{a,b}) void { unreachable; }

pub fn main() void {
    foo(.a);
}

Looks like the bug is somewhere in the comptime resolution of enum literals to enum type

@andrewrk
Copy link
Member

I believe the solution to this is going to be auditing how the comptime evaluation of parameter types are cached. This is related to #846. I want anonymous enums to also work in generic functions, after a comptime parameter. So this will require examining what "dependencies" from comptime parameters are used, and using only those as the cache key. That makes #846 a prerequisite to solving this bug. It also means that @typeInfo on generic function parameters and return type will get more useful.

@Rocknest
Copy link
Contributor

export fn entry() void {
    repro(.a, 1);
}

fn repro(msg: enum {a, b}, comptime here_a_bug: u8) void {
    switch (msg) {
        .a => {},
        .b => {},
    }
}

@Vexu
Copy link
Member

Vexu commented Sep 8, 2021

This will work with in the self-hosted compiler which is expected to ship with 0.9.0. In the meanwhile you should be able to workaround this by putting the enum in a separate declaration instead of having it as the parameter type.

@Vexu
Copy link
Member

Vexu commented Dec 28, 2022

This worked earlier already but 2cfa716 added a similar enough test.

@Vexu Vexu closed this as completed Dec 28, 2022
@andrewrk andrewrk modified the milestones: 0.12.0, 0.11.0 Dec 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

6 participants