bensu / zig-derive-error-set-example

Example to reproduce unexpected behavior from the zig compiler under `src/main.zig`.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

zig: derived error sets inference

Example to reproduce unexpected behavior from the zig compiler under src/main.zig:

const std = @import("std");

// We want to hide this from the user
const InternalError = error{Internal};

// We want to expose this to the user
pub const PublicError = error{Public};

fn internal_function() !u32 {
    if (true) {
        return error.Internal;
    } else {
        return error.PublicError;
    }
    return 1;
}

// Handles the Internal error but exposes the Public error
fn public_api() PublicError!u32 {
    if (internal_function()) |result| {
        return result;
    } else |err| switch (err) {
        error.Internal => return 0,
        // err can no longer be error.Internal
        else => return err,
    }
}

pub fn main() !void {
    const a = public_api();
    try std.debug.assert(a == 0);
}

test "simple test" {
    const a = public_api();
    try std.testing.expectEqual(a, 0);
}

We get this error when running zig test:

$ zig test src/main.zig

src/main.zig:24:24: error: expected type 'error{Public}', found '@typeInfo(@typeInfo(@TypeOf(main.internal_function)).Fn.return_type.?).ErrorUnion.error_set'
        else => return err,
                       ^~~
src/main.zig:24:24: note: 'error.Internal' not a member of destination error set
referenced by:
    test.simple test: src/main.zig:34:15
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

I would've expected the compiler to figure out that err can no longer be error.Internal and remove that from the derived error set.

About

Example to reproduce unexpected behavior from the zig compiler under `src/main.zig`.


Languages

Language:Zig 100.0%