Skip to content

Make proc_macro available outside procedural macro generation #406

Closed
@dead-claudia

Description

@dead-claudia

Proposal

Problem statement

proc_macro has no clear testing story on its own. It's also not possible to use it in build scripts.

Motivating examples or use cases

The top three most downloaded crates are Syn, proc-macro2, and quote.

  • proc-macro2 is mostly just a port of the built-in proc_macro crate.
  • The functionality of quote already has an unstable analogue in proc_macro itself.
  • Syn parses the token stream into an AST for further manipulation. (Note: integrating this in any way into proc_macro is explicitly outside the scope of this proposal.)

The README introduction for proc-macro2 could itself just be this entire section:

A wrapper around the procedural macro API of the compiler's proc_macro crate.
This library serves two purposes:

  • Bring proc-macro-like functionality to other contexts like build.rs and
    main.rs.
    Types from proc_macro are entirely specific to procedural macros
    and cannot ever exist in code outside of a procedural macro. Meanwhile
    proc_macro2 types may exist anywhere including non-macro code. By developing
    foundational libraries like [syn] and [quote] against proc_macro2 rather
    than proc_macro, the procedural macro ecosystem becomes easily applicable to
    many other use cases and we avoid reimplementing non-macro equivalents of
    those libraries.

  • Make procedural macros unit testable. As a consequence of being specific
    to procedural macros, nothing that uses proc_macro can be executed from a
    unit test. In order for helper libraries or components of a macro to be
    testable in isolation, they must be implemented using proc_macro2.

Solution sketch

Expose the built-in proc_macro crate outside procedural macros, similar to what's currently being done (in nightly) for test. Not sure how exactly that'd work on the technical side, but the external design concept is at least simple. 🙂

Alternatives

Obviously, it's already being done as a crate. This work is highly duplicative, however, and makes little sense to have two separate projects maintain two separate pieces of functionality that do basically the same thing. It makes even less sense considering you all sometimes have to proactively work with their maintainers and around their crates just to avoid breaking people.

Links and related work

See the section "Motivating examples or use cases". It applies here as well.

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

  • We think this problem seems worth solving, and the standard library might be the right place to solve it.
  • We think that this probably doesn't belong in the standard library.

Second, if there's a concrete solution:

  • We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
  • We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard librarieshelp wantedExtra attention is neededwaiting-on-author

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions