-
Notifications
You must be signed in to change notification settings - Fork 4
Derive macros #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Derive macros #155
Conversation
Good stuff, but if I add a If the compiler was ready we would compile the derive macro with the current standard libraries, then add For now maybe we could only use For now we could manually copy/paste generated code in the standard libraries. What matters is that we shouldn't be hand-rolling |
I think this is likely fine for now. We will eventually need some kind of "procedural macro" that can generate anything (types, functions, modules, maybe even packages) anyway, we can start with derive macros. Some (maybe most) of the macros will take time to run, and because they generate types and functions that can be used in the rest of the program, naively, the type checker will need the output before fully type checking the program. That's not ideal in language servers. We should have the features in place to avoid this. Some ideas:
The principle is: type checking and other LSP functionality should still be response with macros. Do whatever it takes to make sure this is the case (without getting rid of macros, they're useful). An open question is what kind of introspection to allow in macros. In my use cases (mainly in Rust, but with TemplateHaskell in the past as well) I've never needed anything more than the AST passed to the macro. That works for: generating serializers (with annotations on fields), implementing |
Re: introspection, I think I found one of the reasons why some of the other languages need it. Consider this Dart class:
This top-level definition is not self-contained: some of the definition is in So if I add something like Rust's derive macros:
and pass the AST of the We don't have this problem in Rust and Fir (at least yet). A derive macro gets the whole type definition. In principle there could be use cases where you have to look at the types in the fields, but I'm not aware of any such use cases. |
Another use case for introspection is when you have generate code not in a macro that wraps a definition that you use, but somewhere else. For example, instead of
you do something like (not real Fir syntax)
(where (This could be in another library than I don't know if we need this kind of thing. My current thinking is: if Rust doesn't need this then we also probably don't. |
The program is not used yet, but it can be used for derive macros. See #155 for the discussion.
I've merged the Fir code to derive |
Another concern here is that this will make bootstrapping much more difficult as the compiler will have to support derive macros from day 0. I think we should copy-paste generated code for now. |
TODO: Parse macro output and add it to the module.
TODO: Add tests.