Try pasting this into IEx. The B module isn't being compiled and loaded before the %B{} tries to use it.
defmodule A do
defmodule B do
defstruct c: nil
end
defstruct b: %B{}
end
This is not a bug. You can't use a module in the same context it was defined.
Sorry, I answered too fast. This should actually work because defstruct's argument should be unquoted inside a function context.
@ericmj we evaluate it before.
Maybe we should considering unquoting it only inside the function since you can emulate outside emulation with @attributes.
I think that is the best option here, because afaik there is no workaround for Devin's issue. We can also make sure unquote fragments work.
I am not sure about how to proceed here. We can make it work as long as we guarantee the keys are known at compilation time. It is a more rigid structure that would work with deriving and allow typespecs to be implemented easily... but on the other hand it will make it harder to build structs dynamically (you would effectively need macros).
@ericmj let's talk about this during the afternoon too.
Ok, we are going for now this is not a bug due to how compilation in elixir works.
Possible solutions are:
defmodule A do
defmodule B do
defstruct c: nil
end
defstruct b: B.__struct__
end
This has actually been fixed! Structs now work on quoted expressions rather than runtime values.
Most helpful comment
This has actually been fixed! Structs now work on quoted expressions rather than runtime values.