FEATURE: Macros in type positions#193
Open
elias-michaias wants to merge 2 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Macros returning
type_exprnow usable in type positionsPreviously, a macro declared with
-> type_exprcould not actually return their type. The best way to get a type from a macro was by immediately instantiating the type in the macro body and then usingtypeofon the macro call.This change makes them work wherever a type is expected in the compiler's type-checker, including:
:)::).{})What changed
Three fixes in
compiler/src/checker.c:1.
Ast_Kind_Poly_Call_Type: macro in type annotation / inline call positionWhen the parser sees
SomeMacro(A, B)in a type position, it creates anAst_Kind_Poly_Call_Typenode. Previously, if the callee resolved to a macro insteadof a struct/type, the compiler would error with "Cannot instantiate a concrete type off
of a non-polymorphic type."
The fix detects a macro callee, builds a synthetic
AstCall, runs it throughcheck_expressionto trigger macro expansion, then extracts the returned type node fromthe resulting
AstDoBlock.2.
Ast_Kind_Aliasincheck_type:::constant bindingsWhen
OptArr :: composition(Foo, Bar)is processed, the RHS is stored as anAstAliaswrapping anAstDoBlock(the expanded macro body).check_typepreviouslyhad no logic for this case, so subsequent uses of
OptArras a type would fail.The fix walks the do-block body to find the
returnstatement, extracts the returnedtype node, and redirects the alias directly to it.
3.
Ast_Kind_Field_Access:check_type— field-access macro calleeWhen a macro is accessed via field notation (
F.up) and used as a type-position callee(
F.up(F.{}, i32.{})),check_field_accesscorrectly resolved it to the macro nodebut then
check_typeimmediately errored with "This field access did not resolve to bea type. It resolved to be a MACRO."
The fix adds a one-line early-out: if the resolved field is a macro, break out of the
error path so the enclosing
Ast_Kind_Poly_Call_Typehandler can expand it normally.Examples
Macro in variable type annotation
Macro in
::constant binding and struct literalField-access macro as a struct field type
All existing language tests seem to pass.