Skip to content

Can't resolve inferred error set for function that returns conditional expression #4672

Closed
@ghost

Description

const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    const file = try openDataFile(allocator, .read);
    file.close();
}

fn openDataFile(
    allocator: *std.mem.Allocator,
    mode: enum { read, write },
) !std.fs.File {
    return switch (mode) {
        .read => std.fs.cwd().openFile("aaa", .{}),
        .write => std.fs.cwd().createFile("aaa", .{}),
    };
}
./asdf12.zig:12:10: error: cannot resolve inferred error set '@TypeOf(openDataFile).ReturnType.ErrorSet': function 'openDataFile' not fully analyzed yet
) !std.fs.File {
         ^
./asdf12.zig:5:18: note: referenced here
    const file = try openDataFile(allocator, .read);
                 ^

It also fails using return if (mode == .read) ... else ...;.

I can get it to work by adding trys:

  • return try switch (mode) { ... };
  • return switch (mode) { .read => try ... , .write => try ... };

Or by returning inside the switch statement:

  • switch (mode) { .read => return ..., .write => return ... }

Or by assigning the conditional expression then returning the variable:

  • const x = switch (mode) { .read => ... , .write => ... }; return x;

It becomes weirder if I have another try in the function. Now it does compile, but the compiler doesn't know about the possible error values from the return expression.

const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    const file = openDataFile(allocator, .read) catch |err| {
        if (err == error.FileNotFound) {
            std.debug.warn("oh\n", .{});
        }
        return err;
    };
    file.close();
}

fn openDataFile(
    allocator: *std.mem.Allocator,
    mode: enum { read, write },
) !std.fs.File {
    const file_path = try std.fs.path.join(
        allocator,
        &[_][]const u8 { "one", "two" },
    );

    return switch (mode) {
        .read => std.fs.cwd().openFile(file_path, .{}),
        .write => std.fs.cwd().createFile(file_path, .{}),
    };
}
./asdf12.zig:6:17: error: error sets '@TypeOf(openDataFile).ReturnType.ErrorSet' and 'error{FileNotFound}' have no common errors
        if (err == error.FileNotFound) {
                ^

Note: I think this is a recent (as in the last week or two?) regression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorstage1The process of building from source via WebAssembly and the C backend.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions