Skip to content

Inline loop over functions where one returns empty error set gives compiler error #1957

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

Closed
Hejsil opened this issue Feb 13, 2019 · 2 comments
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@Hejsil
Copy link
Contributor

Hejsil commented Feb 13, 2019

I would expect this to work, but it doesn't.

const T1 = struct {
    pub fn v() error{}!usize {
        return usize(0);
    }
};

const T2 = struct {
    pub fn v() error{Error}!usize {
        return usize(1);
    }
};

test "" {
    const ts = []type{
        T1,
        T2,
    };
    inline for (ts) |T|
        _ = try T.v();
}
test.zig:19:13: error: control flow attempts to use compile-time variable at runtime
        _ = try T.v();
            ^
test.zig:18:12: note: compile-time variable assigned here
    inline for (ts) |T|
@Hejsil
Copy link
Contributor Author

Hejsil commented Feb 13, 2019

Flipping the order of T1 and T2 in ts makes the code work.

@andrewrk andrewrk added this to the 0.4.0 milestone Feb 15, 2019
@andrewrk andrewrk added the bug Observed behavior contradicts documented or intended behavior label Feb 15, 2019
@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Apr 8, 2019
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Sep 24, 2019
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Dec 31, 2019
@jeffkdev
Copy link

I'll add another test case for this one. Looks like there are a few different open bugs for this error, but this issue seems to be the most similar. Running zig test on the below code I get:
error: control flow attempts to use compile-time variable at runtime try serialize(@field(value, fieldType.name), output);

I found that removing the bool type in Vec3 so all code paths for the inline-for loop will have the same error type will let it compile. Also specifying the error set manually will workaround the issue as well.

const std = @import("std");
const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator;

// Workaround #1: Change return type to specific error set
//pub fn serialize(value: var, output: *ArrayList(u8)) error{OutOfMemory}!void {
pub fn serialize(value: var, output: *ArrayList(u8)) !void {
    switch (@typeInfo(@TypeOf(value))) {
        .Int, .Float,  => {
            try output.appendSlice(std.mem.asBytes(&value).*[0..]);
        },
        .Struct => {
            const T = @TypeOf(value);
            inline for (@typeInfo(T).Struct.fields) |fieldType| {
                // Workaround #2:  instead of 'try' handle error
                // serialize(@field(value, fieldType.name), output) catch unreachable;
                try serialize(@field(value, fieldType.name), output);
            }        
        },
        .Bool => { },
        else => @compileError("Unable to serialize type'" ++ @typeName(@TypeOf(value)) ++ "'"),
    }
}

test "Test" {
    const alloactor = std.testing.allocator;
    const Vec2 = struct {
        x: i32,
        y: i32,
    };
    const Vec3 = struct {
        // Workaround #3: remove bool type (comment out line)
        some_bool: bool = false,
        x: i32,
        y: i32,
        z: i32,
    };

    const vec2 = Vec2{.x=1, .y=2};
    const vec3 = Vec3{.x=1, .y=2,.z=3};
    var buffer1 = ArrayList(u8).init(alloactor);
    defer buffer1.deinit();

    var buffer2 = ArrayList(u8).init(alloactor);
    defer buffer2.deinit();

    try serialize(vec2, &buffer1);
    try serialize(vec3, &buffer2);

    std.testing.expectEqualSlices(u8, buffer1.items, buffer2.items[0..8]);
}

@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 10, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
Vexu added a commit to Vexu/zig that referenced this issue Dec 28, 2022
Vexu added a commit to Vexu/zig that referenced this issue Dec 28, 2022
Vexu added a commit to Vexu/zig that referenced this issue Dec 28, 2022
Vexu added a commit to Vexu/zig that referenced this issue Dec 29, 2022
@andrewrk andrewrk modified the milestones: 0.12.0, 0.11.0 Dec 29, 2022
TUSF pushed a commit to TUSF/zig that referenced this issue May 9, 2024
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
Projects
None yet
Development

No branches or pull requests

3 participants