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

error{} != error{} #7533

Open
ghost opened this issue Dec 23, 2020 · 3 comments
Open

error{} != error{} #7533

ghost opened this issue Dec 23, 2020 · 3 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@ghost
Copy link

ghost commented Dec 23, 2020

Apparently, every time you use error{} as a generic type param, it creates a new unique type (incompatible with previous expressions of the same type).

This is probably "as designed" but I would still like to know for sure (the rules on how generic type identity works are somewhat mysterious to me). error{} is probably not the only case where it feels like it should work but doesn't.

fn Writer(comptime E: type) type {
    return struct {};
}

pub fn main() void {
    const writer: Writer(error{}) = Writer(error{}){};
}
./asdf.zig:6:52: error: expected type 'Writer(writer)', found 'Writer(error:6:26)'
    const writer: Writer(error{}) = Writer(error{}){};
                                                   ^
./asdf.zig:2:12: note: Writer(writer) declared here
    return struct {};
           ^
./asdf.zig:2:12: note: Writer(error:6:26) declared here
    return struct {};
           ^

Side note: the name it came up with, Writer(writer) is pretty strange.

I am aware of the workarounds:

    const Error = error{};
    const writer: Writer(Error) = Writer(Error){};
    // or
    const MyWriter = Writer(error{});
    const writer: MyWriter = MyWriter{};
@ikskuh
Copy link
Contributor

ikskuh commented Dec 23, 2020

I think the expected behaviour is that error{} == error{} should yield true. right now error types are compared as any other type, but i don' think that's the correct behaviour.

Error set types should be cached/hashed based on their content and have structural equality similar to integers.

This means that also error{A,B} == error{A}||error{B} shoud yield true which is not the case atm

@ghost
Copy link
Author

ghost commented Dec 23, 2020

Whoops, I didn't even think to try error{} == error{}. You're right that's the real issue here, I'll edit the issue title.

@ghost ghost changed the title error{} as generic type param creates new unique type every time error{} != error{} Dec 23, 2020
@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Dec 23, 2020
@Vexu Vexu added this to the 0.8.0 milestone Dec 23, 2020
@g-w1
Copy link
Contributor

g-w1 commented Dec 25, 2020

My pr #7092 which implements error set merging in stage2 impliments this correctly. The following test currently passes:
https://github.com/ziglang/zig/pull/7092/files#diff-fe87a84eb6da1b5d2b6692aaf4c096531e480add4c2c7d381e32f9095f5a56e5R392-R398

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants