Now that I know that I think it’s likely due to result location semantics. My mental model would be that the assignment basically “fixes/finalizes” the type. Though I will stop guessing and let the people who really know this answer
.{ x, y } is not a tuple literal, rather it is composite type literal with an inferred type.
If there is no type to infer, then zig generates a new type that fits the literal, in your examples that would be a tuple, but that depends on the literal.
.{ .foo = x } would generate a non-tuple struct.
Tuples can coerce to arrays, but only by value not pointer.
var a = .{ x, x }; _ = &a;
var s2: [2]u8 = a; _ = &s2;
I generally agree with @vulpesx’s point, but I think part of this misunderstanding is due to the documentation not being thorough enough.
I think the current syntax for initializing array pointers and such isn’t based on tuple coercion, but on result type inference.
But the current document explains the relationship between the result type and .{ x } like this:
Expression .{x} Parent Result Type T Sub-expression Result Type x is a @FieldType(T, "0")
Since @FieldType only applies to struct (tuple) types, it’s easy to misunderstand that .{ x } is just a tuple literal. Using it to initialize slices or multiple pointers works through type coercion rather than inferred result type.
I admit I still don’t understand what exactly you are talking about.
It is just quite confusing to me.
At least, pointers to tuples can be coerced into slices, then it is quite easily to get array pointers and many-item pointers from the resulting slices. It looks meaningless to me that prevent pointers to tuples from being directly coerced into array pointers and many-item pointers.
This is indeed a bit confusing. It’s possible that this inconsistency is caused by the missing error report in this particular compiler implementation. I agree that if array pointers aren’t allowed to be coerced like this, slices certainly shouldn’t be either.
@vulpesx, do you agree with @npc1054657282 on this point? If not, is there a rule in official doc to allow pointers to tuple variables -> slices coercion?
This is though only possible if the inner types are coercible into the type of target slice. And with that it is only really possible for tuples of primitive types and for tuples who’s element have all the same type, making them equal to an array.
var x: u8 = 1; _ = &x;
var y: u16 = 2; _ = &y;
const c = .{ x, y }; _ = &c;
var s4: []const u16 = &c; _ = &s4;
const b = .{ x, y }; _ = &b;
var s3: []const u8 = &b; _ = &s3; // error
And at least for me this makes sense. Tuples have a compile time known length and list of types. If those types all are the same they are basically equal to an array of the same size. So the argument for being coercible to slices boils down to arrays being coercible to slices. And we should of course be able to do this.