Skip to content

Conversation

@nik-rev
Copy link

@nik-rev nik-rev commented Dec 8, 2025

Note: I didn't create an issue for this PR because I don't mind if it gets rejected. As this is my first PR, it is a good opportunity for me to learn the codebase.

What does this PR try to resolve?

This PR adds 2 new capabilities:

  • cargo new --proc-macro
  • cargo init --proc-macro

The new --proc-macro flag will create src/lib.rs with these contents:

#[proc_macro]
pub fn identity_proc_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    input
}

#[proc_macro_derive(Foo, attributes(foo))]
pub fn identity_derive_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    input
}

#[proc_macro_attribute]
pub fn identity_attribute_macro(
    args: proc_macro::TokenStream,
    input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let _ = args;
    input
}

And Cargo.toml with these contents:

[package]
name = "package"
version = "0.1.0"

[dependencies]

[lib]
proc-macro = true

Motivation

Using proc-macros requires making a new crate, and there are many things you have to remember to do:

  • Signatures of the 3 types of procedural macros
  • How to add helper attributes to the derive macro
  • The fact that the signatures use proc_macro::TokenStream and not proc_macro2::TokenStream
  • [lib] proc-macro = true in Cargo.toml

Neither cargo new --lib nor cargo new --bin help with this. Because all pub items must be removed, and proc-macro crates can't have unit tests, these 2 flags are not as helpful.

There should be a 3rd flag which is just for creating a proc macro. This populates the [lib] proc-macro = true section. It also has the 3 signatures of proc-macro functions, including a derive macro with attributes.

The proc_macro::TokenStream type is used instead of doing use proc_macro::TokenStream then using TokenStream because people are likely to only need the proc_macro::TokenStream type in signatures of these functions, as most proc-macros use proc_macro2::TokenStream

How to test and review this PR?

cargo test --test testsuite -- cargo_init::mutually_exclusive_flags cargo_init::simple_proc_macro

@rustbot rustbot added A-cli Area: Command-line interface, option parsing, etc. Command-new S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 8, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 8, 2025

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@nik-rev nik-rev force-pushed the cargo-new-proc-macro branch from c149577 to 2ca2b1f Compare December 8, 2025 20:30
@epage
Copy link
Contributor

epage commented Dec 8, 2025

We've generally been conservative in what add to cargo new, deferring most things to #5151.

We may also want to decide on rust-lang/rfcs#3826 first as that can dramatically change what direction we may wan to go with this (especially since --lib and --bin aren't additive (#10595).

For myself,

  • I'm not a fan of templates with boilerplate that needs to be deleted which this has with covering all proc-macro types.
  • I wonder how much we should incentivize creation of proc macros vs encouraging the further development of declarative macros (an on going effort)
  • As most proc-macros use syn, etc I feel like this falls short in not getting people started on those

Note: I didn't create an issue for this PR because I don't mind if it gets rejected. As this is my first PR, it is a good opportunity for me to learn the codebase.

Note that we encourage Issues also because that is where we are more likely to look when looking for past conversations in case this does get rejected.

Neither cargo new --lib nor cargo new --bin help with this. Because all pub items must be removed, and proc-macro crates can't have unit tests, these 2 flags are not as helpful.

This is an example of why Issues can be helpful. We could dig into this and explore alternatives like an option for less boilerplate, depending on the use case (why still use cargo new?).

)
._arg(flag("bin", "Use a binary (application) template [default]"))
._arg(flag("lib", "Use a library template"))
._arg(flag("proc-macro", "Use a library (proc-macro) template"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most features go through being unstable before becoming stable.

For more information, see https://doc.rust-lang.org/nightly/nightly-rustc/cargo/core/features/index.html

let project_root = &project.root();

snapbox::cmd::Command::cargo_ui()
.arg_line("init --proc-macro --vcs none --edition 2015")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something we've found helpful for authors, reviewers, and the community is the split PRs in at least two commits

  1. Add tests with them passing, showing current behavior
  2. Add fix or features w/ updates to tests, showing new behavior

Then the diff shows how behavior changed.

This isn't always applicable. A straightforward response to this with this PR is to just show "argument not found" errors on the use of --proc-macro. However, consider your point

Neither cargo new --lib nor cargo new --bin help with this. Because all pub items must be removed, and proc-macro crates can't have unit tests, these 2 flags are not as helpful.

You are highlighting how this improves on what is currently there, so the first commit could have tests use --lib with the follow up commit switching them to --proc-macro, with the diff showing how this new flag differs from what you would get before.

Copy link
Contributor

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is my first PR, it is a good opportunity for me to learn the codebase.

FYI my comments are in the line of helping to learn process; I am not reviewing for merging atm

View changes since this review

@nik-rev nik-rev force-pushed the cargo-new-proc-macro branch from 2ca2b1f to 33172a2 Compare December 8, 2025 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-cli Area: Command-line interface, option parsing, etc. Command-new S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants