I don't think that "infer operator" is a special case of field access, to me it feels like regular known-type elision similar to how C# and C++ use the var keyword if the data type can be inferred from the rhs expression:
const Enum = enum {one, two, five};
const t: Enum = .one; // Enum.one, but the type was inferred from lhs
std.debug.print("{t}\n", .{t});
Defining an anonymous struct is valid in zig; your example is only invalid because "test" is a reserved keyword. But you are correct that it reifies into a concrete type, and after initialization it doesn't coerce into other types because zig doesn't do structural typing: const anonymous = .{ .x = 0, .y = 1 };
std.debug.print("{}\n", .{@TypeOf(anonymous)}); // will output something like test_0__struct_45138
const Point = struct { x: i32, y: i32 };
const p1 = Point{ .x = 0, .y = 1 }; // valid, explicit struct literal
const p2: Point = .{ .x = 0, .y = 1 }; // valid, anonymous struct will coerce to Point
//const pt: Point = anonymous; // error: expected type 'test_0.Point', found 'test_0__struct_45138'
And then there's fieldless anonymous structs aka tuples. I'm including them because they were used in the print statements above: const tuple = .{ 0, "1", true };
std.debug.print("{}\n", .{@TypeOf(tuple)});
// struct { comptime comptime_int = 0, comptime *const [1:0]u8 = "1", comptime bool = true }
Thanks for the detailed answer :)
All this does for me is raise the question of why they chose to use the `.` for so many different uses. I'd be fine if it was just to infer the type, but it seems very overloaded.