Skip to content

Crash iterating over tuple elements via pointer in comptime #19428

Closed as not planned
@michaelbartnett

Description

@michaelbartnett

Zig Version

0.12.0-dev.3434+e90583f5d

Steps to Reproduce and Observed Behavior

This code produces a compiler crash on master:

const std = @import("std");

pub const attributes = struct {
    pub fn first(comptime T: type, comptime AttribType: type) ?*const AttribType {
        inline for (&T.ATTRIBUTES) |*attrib| {
            if (comptime @TypeOf(attrib.*) == AttribType) {
                return attrib;
            }
        }
        return null;
    }
};

pub const SimpleAttribute = struct {
    n: i32,
};

pub const SomeTypeWithAttributes = struct {
    m: u8 = 255,

    pub const ATTRIBUTES = .{
        SimpleAttribute{ .n = 42 },
    };
};

pub fn main() void {
    var value: i32 = -1;
    if (attributes.first(SomeTypeWithAttributes, SimpleAttribute)) |pattr| {
        value = pattr.n;
    }

    std.log.info("SimpleAttribute.n of SomeTypeWithAttributes resolved to {}", .{value});
}

Expected Behavior

Expected no crash ofc :)

I also expect it to return the address of the element of the tuple declared in SomeTypeWithAttributes.

Squirl (🙌) on the discord pointed out that changing this function to return values instead of addresses gets rid of the crash, and that if I wanted to avoid making a bunch of copies I could still take the address of the comptime result value and it would likely dedupe.

This totally works for my current use case, although this leaves it in a less-semantically-clear state from the user's perspective. If I take the address of the result of the comptime function call result, is it the address of SomeTypeWithAttributes.ATTRIBUTES[0] or is it the address of a copy of that static data at a different location in memory at runtime? If that's not information that Zig wants to expose to the programmer, then maybe worth a compiler message or a note in docs?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions