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

Allow coercion of structs with field names that are the exact same #23048

Closed
wooster0 opened this issue Mar 2, 2025 · 9 comments
Closed

Allow coercion of structs with field names that are the exact same #23048

wooster0 opened this issue Mar 2, 2025 · 9 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.

Comments

@wooster0
Copy link

wooster0 commented Mar 2, 2025

I hit this issue very often:

const std = @import("std");

pub fn main() void {
    var size: struct { width: u32, height: u32 } = undefined;
    size = get_size();
}

fn get_size() struct { width: u32, height: u32 } {
    return .{ .width = 5, .height = 5 };
}
x.zig:5:20: error: expected type 'x.main__struct_2625', found 'x.get_size__struct_2628'
    size = get_size();
           ~~~~~~~~^~
x.zig:8:15: note: struct declared here
fn get_size() struct { width: u32, height: u32 } {
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.zig:4:15: note: struct declared here
    var size: struct { width: u32, height: u32 } = undefined;
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The fix would be to add const Size = struct { width: u32, height: u32 }; and use that in both places.
However, I don't want to have to pollute my top level namespace with consts for trivial short types like this if both types are the exact same.
In fact sometimes I have to pollute my top level namespace with consts like that only for a single edge case where I happen to have the need to specify the result type explicitly. This is unfortunate.

Another solution that seems to work:

const std = @import("std");

pub fn main() void {
    var size: struct { u32, u32 } = undefined;
    size = get_size();
}

fn get_size() struct { u32, u32 } {
    return .{ 5, 5 };
}

However I don't like tuples for things like this because .@"0" etc. is cryptic and I want to use field names. No, I don't want to use destructuring either.

If the field names and order are the same why are the two structs not compatible?

@xdBronch
Copy link
Contributor

xdBronch commented Mar 3, 2025

this doesnt seem like a great idea and a much more tame version was already removed in #21817. imo something like this should exist as some kind of cast if at all e.g. std.meta.structCast.
fwiw you can index tuples rather than using .@"0"

@jinzhongjia
Copy link

Your idea is actually wrong, and when you need to do this, you directly declare that returning the same structure is better

@mlugg mlugg closed this as not planned Won't fix, can't repro, duplicate, stale Mar 3, 2025
@mlugg mlugg added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Mar 3, 2025
@wooster0
Copy link
Author

wooster0 commented Mar 3, 2025

No comment here explains why this "doesn't seem like a great idea" or why "my idea is actually wrong" so I'm given zero explanation on the downsides of this.

@xdBronch
Copy link
Contributor

xdBronch commented Mar 3, 2025

I mean, type safety? it feels kinda obvious why I said that. should structurally equivalent enums coerce? unions? pointers? if anything tuples here are the outlier, not normal structs (and I'm not saying those should change to be clear). I also feel like the pr I linked is a decent argument against it already

@wooster0
Copy link
Author

wooster0 commented Mar 3, 2025

Not going to assume I'm going to get an explanation either so I guess it's just that for some reason everyone uses tuples here or they simple haven't run into the same problem.

This also doesn't apply to only structs but also unions, enums, etc. where you don't have a non-named variant anyway. Only tuples coercing is an inconsistency.

@wooster0
Copy link
Author

wooster0 commented Mar 3, 2025

should structurally equivalent enums coerce? unions? pointers?

Why shouldn't they?

struct { a: u32 } and struct { a: u32 } are the same so what's the problem with type safety?

@xdBronch
Copy link
Contributor

xdBronch commented Mar 3, 2025

enums are pretty commonly used to represent distinct integer types in the compiler and stdlib so i dont think any argument is going to get far there. its a useful property and there have been proposals to allow even stricter type distinctiveness.
things might be named or shaped similarly but contextually mean different things, what if they have decls? are you meant to be able to rely on @TypeOf(some_struct).decl? member functions? tuples are the only container type that completely disallow decls so its not a problem there. if "type safety" isnt a good enough reason im not sure if theres much else i can say

@wooster0
Copy link
Author

wooster0 commented Mar 3, 2025

things might be named or shaped similarly but contextually mean different things, what if they have decls? are you meant to be able to rely on @typeof(some_struct).decl? member functions? tuples are the only container type that completely disallow decls

First actually useful piece of information on an explanation I see in this thread. That's a good point.

@andrewrk
Copy link
Member

andrewrk commented Mar 4, 2025

Please do not file a proposal to change the language

Thank you for your interest in improving the Zig language. However, we are not accepting new proposals to change the language.

If you wish to make a language proposal, you must convince a Zig core team member to file it on your behalf and champion it. Some are paid contractors and some are volunteers, and they all freely choose how to spend their time. A core team member may be willing to champion proposals, or maybe not, at their discretion. Please do not harass Zig core team members.

To give these words some weight, I'm giving the OP a 1-month timeout before they are welcome back on the issue tracker.

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

5 participants