Skip to content

[Macro] Omnibus pull request with macro improvements #62768

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

Merged
merged 19 commits into from
Jan 3, 2023

Conversation

DougGregor
Copy link
Member

@DougGregor DougGregor commented Dec 22, 2022

This pull request brings together a number of fixes and changes for expression macros:

  • Improve diagnostics for macros (e.g., for missing/extra/mislabeled arguments), as well as subscripts
  • Fix a fiendish bug where we had multiple ASTs for the macro expansion code
  • Added a test with a simple variadic macro (a print)
  • Switch the syntax of macro definitions over to = <expression>, using the library-defined #externalMacro specified in SE-0382 to describe external macro definitions. This adds the first macro definition to the standard library.
  • Prevent recursive expansion of macros.
  • Add support for external macros that are defined via enum/class/actor (in addition to struct).
  • Fixes for indexing and API digestion of macros
  • Implement appropriate overloading rules for macro declarations, as they relate to both themselves and other entities (functions, properties, etc.).

@DougGregor
Copy link
Member Author

@swift-ci please build toolchain

@DougGregor
Copy link
Member Author

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

3 similar comments
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor changed the title [Macro] Omnibus pull request with macros-related fixes [Macro] Omnibus pull request with macro improvements Jan 3, 2023
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please built toolchain

@DougGregor
Copy link
Member Author

@swift-ci please build toolchain

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please build toolchain

Each macro expansion buffer was getting parsed twice: once by
ParseSourceFileRequest (which is used by unqualified name lookup) and
once to parse the expression when type-checking the expanded macro.
This meant that the same code had two ASTs. Hilarity ensures.

Stop directly invoking the parser on macro-expanded code. Instead, go
through ParseSourceFileRequest *as is always the right way*, and dig
out the expression we want.
This improves diagnostics for missing/extra/incorrectly-labeled arguments.
…callee kind

Most of the diagnostics for extra/missing/mislabeled arguments refer
to argument to a "call". Some (but not call) would substitute in
"subscript". None would refer to an argument to a macro expansion
properly.

Rework all of these to refer to the argument in a call, subscript, or
macro expansion as appropriate. Fix up lots of tests that now say
"subscript" instead, and add tests for macro expansions.
Macros can use variadic generics, and don't need runtime support for
variadic generics to do so. Add an example "print".
Unlike functions, you can't curry macros; diagnose when one omits the
arguments in a macro expansion of a macro that has a parameter list.
Always parse macro expansions, regardless of language mode, and
eliminate the fallback path for very, very, very old object literals
like `#Color`. Instead, check for the feature flag for macro
declaration and at macro expansion time, since this is a semantic
restriction.

While here, refactor things so the vast majority of the macro-handling
logic still applies even if the Swift Swift parser is disabled. Only
attempts to expand the macro will fail. This allows us to enable the
macro-diagnostics test everywhere.
Align the grammar of macro declarations with SE-0382, so that macro
definitions are parsed as an expression. External macro definitions
are referenced via a referenced to the macro `#externalMacro`. Define
that macro in the standard library, and recognize uses of it as the
definition of other macros to use externally-defined macros. For
example, this means that the "stringify" macro used in a lot of
examples is now defined as something like this:

    @expression macro stringify<T>(_ value: T) -> (T, String) =
        #externalMacro(module: "MyMacros", type: "StringifyMacro")

We still parse the old "A.B" syntax for two reasons. First, it's
helpful to anyone who has existing code using the prior syntax, so they
get a warning + Fix-It to rewrite to the new syntax. Second, we use it
to define builtin macros like `externalMacro` itself, which looks like this:

    @expression
    public macro externalMacro<T>(module: String, type: String) -> T =
        Builtin.ExternalMacro

This uses the same virtual `Builtin` module as other library builtins,
and we can expand it to handle other builtin macro implementations
(such as #line) over time.
…riminators.

Thanks to Alex Hoppen for providing this test!
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor merged commit 0c54362 into swiftlang:main Jan 3, 2023
@DougGregor DougGregor deleted the macro-omnibus branch January 3, 2023 15:13
ahoppen added a commit to ahoppen/swift-source-compat-suite that referenced this pull request Jan 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant