#Compiler crash, anything I'm doing wrong here, know any similar bugs?

1 messages · Page 1 of 1 (latest)

reef sentinel
#

Code: https://zigbin.io/d777fa

I'm writing a pseudo-attributes lookup helper (think Java/Go annotations or C# attributes) as has been recommended when folks ask for an explicit attribute feature. It works well when I reify the attributes into runtime-available data, but when I try to examine attributes at comptime and compile I get exit code 3 on windows (and SIGTRAP on Linux according to zigbin/godbolt).

I've tried looping through attributes by index, iterating struct fields from the type info, and putting the loop in another function that just returns the tuple index.

I thought maybe I was hitting this bug because initially I had nested tuples: https://github.com/ziglang/zig/issues/18972
But when I pulled it out into just a single top-level tuple literal, I still hit this crash, so I'm not sure it's related. Anyone recall similar open issues and found a workaround? Wanted to check before submitting a bug.

Also, this is happening at least between 0.12.0-dev.2063 and master (tested latest nightly just now).

onyx field
#

I'm not sure what bug you're hitting, but not using pointers fixes it

#

Just change your function to this: ```rs
pub fn first(comptime T: type, comptime AttribType: type) ?AttribType {
inline for (T.ATTRIBUTES) |attrib| {
if (@TypeOf(attrib) == AttribType) {
return attrib;
}
}
return null;
}

#

(I deleted the redundant comptime keyword for you too)

#

@reef sentinel

reef sentinel
#

Oh interesting, also works on the real code where there's a lot more shit going on. Thanks!

I'll omit the pointers for this for now, but do you think it makes sense to be able to take the address of these tuple fields at comptime? It makes sense to me but my brain's running on a slower gear this weekend so maybe I just haven't thought it through enough.

onyx field
#

It should definitely work, you've hit a compiler bug

#

But you'd probably never really need to do that

#

I'd recommend not using pointers unless you need them

reef sentinel
#

I mean, it doesn't really matter for this use case, but it'd be pretty important if the tuple in there is a large type and you don't need to store it again elsewhere so you can't rely on RLS, right? Not exactly a need, but certainly an avoid-premature-pessimization kinda thing.

onyx field
#

At comptime, everything is pointers :)

#

It's all stored in InternPool no matter what, so it literally makes no difference

#

(at least, that's my understanding. I could be wrong)

reef sentinel
#

That's the assumption I've been working under so I choose to believe your understanding 😅

#

I'm thinking more like when runtime code saves off some of this data

onyx field
#

It can take a pointer at that point, no need to do it before you need it

reef sentinel
#

Oh if I take the address of a comptime result, that's stable?

onyx field
#

depends. You shouldn't rely on it

#

But why do you need it to be stable?

reef sentinel
#

Imagine some of these attribute types get big, and there's a big init function that wants to associate type tags or whatever with that attribute data, so there's a big registration function where this helper would return that address, and then you associate a tag with that pointer in a hashtable or whatever.

If we can't rely on getting the address to that tuple, then the data is duplicated in binary. Nbd for a small amount, but I'm explicitly trying to think about how this stuff scales.

#

err, address to that tuple -> address to an element of the tuple (i.e. *SimpleAttribute)

onyx field
#

Oh if it's just for size optimization purposes dw, it'll be deduped

#

Just don't rely on the pointer being stable for anything else, because it's not guaranteed

reef sentinel
#

does it make semantic sense for that to be deduped?

like consider:

var hashtable = std.HashMap(MyTypeTag, SimpleAttribute).init(alloc);
hashtable.put(key, attributes.first(T, SimpleAttribute)); // first() returning by value

where it would be surprising to me if memory was deduped

vs

var hashtable = std.HashMap(MyTypeTag, *SimpleAttribute).init(alloc);
hashtable.put(key, attributes.first(T, SimpleAttribute) orelse defaultSimpleAttribute()); // first() returning address
#

the latter being written under the assumption that you couldn't write

hashtable.put(key, &attributes.first(T, SimpleAttribute)); // first() returning by value
onyx field
#

Why could you not write that?

reef sentinel
#

well, if the advice is not to rely on it, I'm not gonna rely on it lol

onyx field
#

You can rely on it as much as any other optimization

#

Which is to say: it will happen, but don't make your code semantically require it to happen

#

Because it might do something different in future, and break your code

#

Optimizations aren't guarantees, but you shouldn't write your code assuming they will never happen

#

Otherwise we'd all still be using duff's device :D

reef sentinel
#

right right, but if I want to ensure I'm not copying duplicate data around, then I'd want to take a pointer to the SimpleAttribute, right?
like part of my requirement here is that I don't wan to duplicate the data that already there, so I'd rather just take a pointer to it

onyx field
#

yep

reef sentinel
#

ah ok, so it's not "don't rely on this because nasal demons" it's rather "it's mostly reasonable to use my intuition about taking the address of things, but if something I haven't thought hard about enough requires a copy, the compiler will copy and I should measure & read disassembly if I observe this happening and am grumpy about it"?

onyx field
#

Exactly

#

If you're relying on it as an optimization it's fine

#

But don't rely on &thingReturningComptimeValue() == &thingReturningComptimeValue()

#

Because that's not guaranteed in all situations

reef sentinel
#

That makes perfect sense 🙂
In cases where I do want that address equivalence, I've been doing the inline-struct-for-storage trick

onyx field
#

(there are some cases where it is guaranteed, but I'm not sure if your code is one of them because it'd require me to think and it's 11pm lol)

reef sentinel
#

lol fair