type delimiter = struct {
text: []u8,
next: *delimiter,
};
let OPENQUOTE_D = delimiter {
text = ['`', '`'],
next = &CLOSEQUOTE_D,
};
let CLOSEQUOTE_D = delimiter {
text = ['\'', '\''],
next = &OPENQUOTE_D,
};
export fn main() void = void;
// <...>/broken.ha:6:4: error: Circular dependency for 'OPENQUOTE_D'
//
//
// 6 | let OPENQUOTE_D = delimiter {
// | ^
//
// Error: harec: exited with status 1
// hare build: build failed
This can be avoided by a workaround but it requires using nullable pointers and @init
:
type delimiter = struct {
text: []u8,
next: nullable *delimiter,
};
let OPENQUOTE_D = delimiter {
text = ['`', '`'],
next = null,
};
let CLOSEQUOTE_D = delimiter {
text = ['\'', '\''],
next = &OPENQUOTE_D,
};
@init fn init() void = {
OPENQUOTE_D.next = &CLOSEQUOTE_D;
};
export fn main() void = void;
// This compiles.
Preceding IRC discussion:
1:33pm <smlavine> I'm having trouble declaring a compile time circular linked list because of a "Circular dependency" error. I have a workaround but it requires using @init and nullable
pointers. Any suggestions? https://paste.sr.ht/~smlavine/c765fe0d683ae04e0549ac34db896c21748a94fb
1:35pm <ecs> yeah i don't think there's really a good way for us to do something better
1:35pm <ecs> i guess technically we could try to separate finding the result type of an expression from typechecking it?
2:33pm <sebonirc> fwiw my "proposal" thing about generalizing `init` for global initializers would allow your workaround to work without nullable pointers, that being said it's still a hack
which it might be good to fix?
2:33pm <sebonirc> probably worth filing a ticket either way
2:34pm <sebonirc> smlavine: ^
2:34pm <ecs> we'd need to do something similar to the type store dimensions vs representation distinction
2:34pm <ecs> and i'm not really sure it's worth it
2:34pm <sebonirc> yeah i'm not sure either tbh, but i still think there should be a ticket for it so then we at least have to make a decision on it
2:35pm <ecs> fair
2:39pm <smlavine> Will file a ticket
Drew was against supporting this back when I was designing the declaration scanning pass. I don't have a strong opinion either way, but if we decide to implement this, it shouldn't be too hard since most of the infrastructure is already there.
I'd be interested in seeing what an implementation for this would look like. If the infrastructure is already there and it's simple enough to implement, I think it's worth it.