ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34k stars 2.49k forks source link

@typeName gives a different value when struct{} is assigned to a variable whose type is specified #21534

Open LearnLoop365 opened 4 days ago

LearnLoop365 commented 4 days ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

//! struct_name.zig
const std: type = @import("std");

pub fn main() void {
    const Foo = struct {};
    const Bar: type = struct {};
    std.debug.print("variable: {s}\n", .{@typeName(Foo)});
    std.debug.print("variable: {s}\n", .{@typeName(Bar)});
}

--------- Result ----------

$ zig run struct_name.zig
variable: struct_name.main.Foo
variable: struct_name.main__struct_2634

Expected Behavior

According to the docs: https://ziglang.org/documentation/master/#Struct-Naming

Expected by the 1st rule: "If the struct is in the initialization expression of a variable, it gets named after that variable."

variable: struct_name.main.Foo
variable: struct_name.main.Bar
kj4tmp commented 3 days ago

This probably has something to do with this code in Sema not handling order of Ast instructions correctly

https://github.com/ziglang/zig/blob/085cc54aadb327b9910be2c72b31ea046e7e8f52/src/Sema.zig#L2951

.dbg_var => {
            // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
            const ref = inst.?.toRef();
            const zir_tags = sema.code.instructions.items(.tag);
            const zir_data = sema.code.instructions.items(.data);
            for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
                .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
                    return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
                        block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
                    }, .no_embedded_nulls);
                },
                else => {},
            };
            // fall through to anon strat
        },
Rexicon226 commented 3 days ago

Just want to put my 2c in, while this may be considered a bug or issue in documentation, I don't think we should be focusing on or fixing the value that @typeName gives out. It should not conform to any specification, nor should the output ever be relied on.

mlugg commented 1 day ago

This does happen due to the code snippet linked above, but not for the reason in the comment. Instead, it's because there's an intermediate coercion to Zir.Inst.Ref.type_type via an as_node instruction, so the str_op.operand == ref check fails. We'll want to either harden that logic a little, or just replace the dbg_var name strategy with something less janky. (By the way, the fact that that loop casually iterates through the entire rest of this file's ZIR is horrifying.)