From 9d7b2f609badfbef1f2dfa32e7bbc7929fd6da2a Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 17 Mar 2025 01:36:02 -0400 Subject: [PATCH 01/18] RFC: `--crate-attr` --- text/3791-crate-attr.md | 113 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 text/3791-crate-attr.md diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md new file mode 100644 index 00000000000..2759bf32825 --- /dev/null +++ b/text/3791-crate-attr.md @@ -0,0 +1,113 @@ +- Feature Name: `crate-attr` +- Start Date: 2025-03-16 +- RFC PR: [rust-lang/rfcs#3791](https://github.com/rust-lang/rfcs/pull/3791) +- Rust Issue: [rust-lang/rust#138287](https://github.com/rust-lang/rust/issues/138287) + +# Summary +[summary]: #summary + +`--crate-attr` allows injecting crate-level attributes via the command line. + +# Motivation +[motivation]: #motivation + +There are three main motivations. + +1. CLI flags are easier to configure for a whole workspace at once. +2. When designing new features, we do not need to choose between attributes and flags; adding an attribute automatically makes it possible to set with a flag. +3. Tools that require a specific attribute can pass that attribute automatically. + +Each of these corresponds to a different set of stakeholders. The first corresponds to developers writing Rust code. For this group, as the size of their code increases and they split it into multiple crates, it becomes more and more difficult to configure attributes for the whole workspace; they need to be duplicated into the root of each crate. Some attributes that could be useful to configure workspace-wide: +- `no_std` +- `feature` (in particular, enabling unstable lints for a whole workspace at once) +- [`doc(html_{favicon,logo,playground,root}_url}`][doc-url] +- [`doc(html_no_source)`] +- `doc(attr(...))` + +Cargo has features for configuring flags for a workspace (RUSTFLAGS, `target..rustflags`, `profile..rustflags`), but no such mechanism exists for crate-level attributes. + +Additionally, some existing CLI options could have been useful as attributes. This leads to the second group: Maintainers of the Rust language. Often we need to decide between attributes and flags; either we duplicate features between the two (lints, `crate-name`, `crate-type`), or we make it harder to configure the options for stakeholder group 1. + +The third group is the authors of external tools. The [original motivation][impl] for this feature was for Crater, which wanted to enable a rustfix feature in *all* crates it built without having to modify the source code. Other motivations include the currently-unstable [`register-tool`], which with this RFC could be an attribute passed by the external tool (or configured in the workspace), and [custom test frameworks]. + +[impl]: https://github.com/rust-lang/rust/pull/52355 +[`register-tool`]: https://github.com/rust-lang/rust/issues/66079#issuecomment-1010266282 +[doc-url]: https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html#at-the-crate-level +[`doc(html_no_source)`]: https://github.com/rust-lang/rust/issues/75497 +[custom test frameworks]: https://github.com/rust-lang/rust/pull/52355#issuecomment-405037604 + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +The `--crate-attr` flag allows you to inject attributes into the crate root. +For example, `--crate-attr=crate_name="test"` acts as if `#![crate_name="test"]` were present before the first source line of the crate root. + +To inject multiple attributes, pass `--crate-attr` multiple times. + +This feature lets you pass attributes to your whole workspace at once, even if rustc doesn't natively support them as flags. +For example, you could configure `strict_provenance_lints` for all your crates by adding +`build.rustflags = ["--crate-attr=feature(strict_provenance_lints)", "-Wfuzzy_provenance_casts", "-Wlossy_provenance_casts"]` +to `.cargo/config.toml`. + +(This snippet is adapted from [the unstable book].) + +[the unstable book]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/crate-attr.html#crate-attr + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +Any crate-level attribute is valid to pass to `--crate-attr`. + +Formally, the expansion behaves as follows: + +1. The crate is parsed as if `--crate-attr` were not present. +2. The attributes in `--crate-attr` are parsed. +3. The attributes are injected at the top of the crate root. +4. Macro expansion is performed. + +As a consequence, this feature does not affect [shebang parsing], nor can it affect nor be affected by comments that appear on the first source line. + +Another consequence is that the argument to `--crate-attr` is syntactically isolated from the rest of the crate; `--crate-attr=/*` is always an error and cannot begin a multi-line comment. + +`--crate-attr` is treated as Rust source code, which means that whitespace, block comments, and raw strings are valid: `'--crate-attr= crate_name /*foo bar*/ = r#"my-crate"# '` is equivalent to `--crate-attr=crate_name="my-crate"`. + +The argument to `--crate-attr` is treated as-if it were surrounded by `#![ ]`, i.e. it must be an inner attribute and it cannot include multiple attributes, nor can it be any grammar production other than an [`Attr`]. + +If the attribute is already present in the source code, it behaves exactly as it would if duplicated twice in the source. +For example, duplicating `no_std` is idempotent; duplicating `crate_type` generates both types; and duplicating `crate_name` is idempotent if the names are the same and a hard error otherwise. +It is suggested, but not required, that the implementation not warn on idempotent attributes, even if it would normally warn that duplicate attributes are unused. + +[shebang parsing]: https://doc.rust-lang.org/nightly/reference/input-format.html#shebang-removal +[`Attr`]: https://doc.rust-lang.org/nightly/reference/attributes.html + +# Drawbacks +[drawbacks]: #drawbacks + +It makes it harder for Rust developers to know whether it's idiomatic to use flags or attributes. +In practice, this has not be a large drawback for `crate_name` and `crate_type`, although for lints perhaps a little more so since they were only recently stabilized in Cargo. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- We could require `--crate-attr=#![foo]` instead. This is more verbose and requires extensive shell quoting, for not much benefit. +- We could disallow comments in the attribute. This perhaps makes the design less surprising, but complicates the implementation for little benefit. +- We could add a syntax for passing multiple attributes in a single CLI flag. We would have to find a syntax that avoids ambiguity *and* that does not mis-parse the data inside string literals (i.e. picking a fixed string, such as `|`, would not work because it has to take quote nesting into account). This greatly complicates the implementation for little benefit. + +This cannot be done in a library or macro. It can be done in an external tool, but only by modifying the source in place, which requires first parsing it, and in general is much more brittle than this approach (for example, preventing the argument from injecting a unterminated block comment, or from injecting a non-attribute grammar production, becomes much harder). + +In the author's opinion, having source injected via this mechanism does not make code any harder to read than the existing flags that are already stable (in particular `-C panic` and `--edition` come to mind). + +# Prior art +[prior-art]: #prior-art + +- HTML allows `` to emulate headers, which is very useful for using hosted infra where one does not control the server. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +How should this interact with doctests? Does it apply to the crate being tested or to the generated test? + +# Future possibilities +[future-possibilities]: #future-possibilities + +This proposal would make it easier to use external tools with [`#![register_tool]`][`register-tool`], since they could be configured for a whole workspace at once instead of individually; and could be configured without modifying the source code. From ed9d23127997ef9ef4aae48b15cbb299843184b9 Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 17 Mar 2025 10:46:04 -0400 Subject: [PATCH 02/18] initial feedback - Mention how this applies to doctests - Mention build-std - Remove outdated mention of custom test frameworks --- text/3791-crate-attr.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 2759bf32825..aac4c4322df 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -28,13 +28,13 @@ Cargo has features for configuring flags for a workspace (RUSTFLAGS, `target. Date: Mon, 17 Mar 2025 10:47:03 -0400 Subject: [PATCH 03/18] forgot to mark doctests as resolved --- text/3791-crate-attr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index aac4c4322df..f13f2a1d51b 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -113,7 +113,7 @@ In the author's opinion, having source injected via this mechanism does not make # Unresolved questions [unresolved-questions]: #unresolved-questions -How should this interact with doctests? Does it apply to the crate being tested or to the generated test? +None to my knowledge. # Future possibilities [future-possibilities]: #future-possibilities From c29d39415b2d07080ab652adf12204ebe1fdb969 Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 17 Mar 2025 11:53:39 -0400 Subject: [PATCH 04/18] Document that all tools support this flag. Document order and precedence. --- text/3791-crate-attr.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index f13f2a1d51b..e3e35350a70 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -7,6 +7,9 @@ [summary]: #summary `--crate-attr` allows injecting crate-level attributes via the command line. +It is supported by all the major tools: Rustc, Rustdoc, Clippy, and Rustfmt. +Rustdoc extends it to doctests, discussed in further detail below. +It is encouraged, but not required, that external `rustc_driver` tools also support this flag. # Motivation [motivation]: #motivation @@ -60,6 +63,16 @@ Running (for example) `RUSTDOCFLAGS="--crate-attr='feature(strict_provenance_lin [reference-level-explanation]: #reference-level-explanation Any crate-level attribute is valid to pass to `--crate-attr`. +Attributes are applied in the order they were given on the command line; so `--crate-attr=warn(unused) --crate-attr=deny(unused)` is equivalent to `deny(unused)`. +`crate-attr` attributes are applied before source code attributes. +For example, the following file, when compiled with `crate-attr=deny(unused)`, does not fail with an error, but only warns: + +```rust +#![warn(unused)] +fn foo() {} +``` + +This means that `crate-attr=deny(unused)` is exactly equivalent to `-D unused`. Formally, the expansion behaves as follows: From 7b03a05565dbe2ddbf5eeca0d2a178d5f9dddb39 Mon Sep 17 00:00:00 2001 From: jyn Date: Tue, 18 Mar 2025 07:21:56 -0400 Subject: [PATCH 05/18] Define `-A/W/D` to be exactly equivalent to `--crate-attr` --- text/3791-crate-attr.md | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index e3e35350a70..2ac64828fba 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -62,17 +62,9 @@ Running (for example) `RUSTDOCFLAGS="--crate-attr='feature(strict_provenance_lin # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -Any crate-level attribute is valid to pass to `--crate-attr`. -Attributes are applied in the order they were given on the command line; so `--crate-attr=warn(unused) --crate-attr=deny(unused)` is equivalent to `deny(unused)`. -`crate-attr` attributes are applied before source code attributes. -For example, the following file, when compiled with `crate-attr=deny(unused)`, does not fail with an error, but only warns: +## Semantics -```rust -#![warn(unused)] -fn foo() {} -``` - -This means that `crate-attr=deny(unused)` is exactly equivalent to `-D unused`. +Any crate-level attribute is valid to pass to `--crate-attr`. Formally, the expansion behaves as follows: @@ -93,6 +85,8 @@ If the attribute is already present in the source code, it behaves exactly as it For example, duplicating `no_std` is idempotent; duplicating `crate_type` generates both types; and duplicating `crate_name` is idempotent if the names are the same and a hard error otherwise. It is suggested, but not required, that the implementation not warn on idempotent attributes, even if it would normally warn that duplicate attributes are unused. +## Doctests + `--crate-attr` is also a rustdoc flag. Rustdoc behaves identically to rustc for the main crate being compiled. For doctests, by default, `--crate-attr` applies to both the main crate and the generated doctest. This can be overridden for the doctest using `--crate-attr=doc(test(attr(...)))`. @@ -101,6 +95,32 @@ This can be overridden for the doctest using `--crate-attr=doc(test(attr(...)))` [shebang parsing]: https://doc.rust-lang.org/nightly/reference/input-format.html#shebang-removal [`Attr`]: https://doc.rust-lang.org/nightly/reference/attributes.html +## Ordering + +Attributes are applied in the order they were given on the command line; so `--crate-attr=warn(unused) --crate-attr=deny(unused)` is equivalent to `deny(unused)`. +`crate-attr` attributes are applied before source code attributes. +For example, the following file, when compiled with `crate-attr=deny(unused)`, does not fail with an error, but only warns: + +```rust +#![warn(unused)] +fn foo() {} +``` + +Additionally, all existing `-A -W -D -F` flags become aliases for `--crate-attr` (`allow`, `warn`, `deny`, and `forbid`, respectively). In particular, this implies that the following CLI flag combinations are exactly equivalent: +- `-D unused` +- `-A unused -D unused` +- `--crate-attr=allow(unused) -D unused` + +`--force-warn` has no attribute that is equivalent, and is not affected by this RFC. + +"Equivalence" as described in this section only makes sense because lint attributes are defined to have a precedence order. +Other attributes, such as doc-comments, define no such precedence. Those attributes have whatever meaning they define for their order. +For example, passing `'--crate-attr=doc = "Compiled on March 18 2025"'` to a crate with `#![doc = "My awesome crate"]` on the first line would generate documentation for the crate root reading: +``` +Compiled on March 18 2025 +My awesome crate +``` + # Drawbacks [drawbacks]: #drawbacks From aca698c693a73ccaba3e4d8fd10b220c2c866202 Mon Sep 17 00:00:00 2001 From: jyn Date: Tue, 18 Mar 2025 07:30:00 -0400 Subject: [PATCH 06/18] Clarify that `//!` isn't allowed --- text/3791-crate-attr.md | 1 + 1 file changed, 1 insertion(+) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 2ac64828fba..c82ea298888 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -80,6 +80,7 @@ Another consequence is that the argument to `--crate-attr` is syntactically isol `--crate-attr` is treated as Rust source code, which means that whitespace, block comments, and raw strings are valid: `'--crate-attr= crate_name /*foo bar*/ = r#"my-crate"# '` is equivalent to `--crate-attr=crate_name="my-crate"`. The argument to `--crate-attr` is treated as-if it were surrounded by `#![ ]`, i.e. it must be an inner attribute and it cannot include multiple attributes, nor can it be any grammar production other than an [`Attr`]. +In particular, this implies that `//!` syntax for doc-comments is disallowed (although `doc = "..."` is fine). If the attribute is already present in the source code, it behaves exactly as it would if duplicated twice in the source. For example, duplicating `no_std` is idempotent; duplicating `crate_type` generates both types; and duplicating `crate_name` is idempotent if the names are the same and a hard error otherwise. From 046463bb0dffd53345cf91dbf7b311271c91b93a Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 04:19:43 -0400 Subject: [PATCH 07/18] extend prior art section --- text/3791-crate-attr.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index c82ea298888..813c9446f2b 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -143,6 +143,8 @@ In the author's opinion, having source injected via this mechanism does not make [prior-art]: #prior-art - HTML allows `` to emulate headers, which is very useful for using hosted infra where one does not control the server. +- bash allows `-x` and similar to emulate `set -x` (for all `set` arguments). It also allows `-O shopt_...` for all `shopt ...` arguments. +- tmux config syntax is the same as its CLI syntax (for example `tmux set-option ...` is mostly the same as writing `set-option ...` in `tmux.conf`, modulo some issues around startup order and inherited options). # Unresolved questions [unresolved-questions]: #unresolved-questions From 4b9fa4b2f9f5f01c9562767c8b6cda9fab1cc9b0 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 04:25:02 -0400 Subject: [PATCH 08/18] Document why crate-attr is prepended instead of appended --- text/3791-crate-attr.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 813c9446f2b..8cb889cb844 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -133,6 +133,9 @@ In practice, this has not be a large drawback for `crate_name` and `crate_type`, - We could require `--crate-attr=#![foo]` instead. This is more verbose and requires extensive shell quoting, for not much benefit. - We could disallow comments in the attribute. This perhaps makes the design less surprising, but complicates the implementation for little benefit. +- We could apply `--crate-attr` after attributes in the source, instead of before. This has two drawbacks: + 1. It has different behavior for lints than the existing A/W/D flags, so those flags could not semantically be unified with crate-attr. We would be adding yet another precedence group. + 2. It does not allow configuring a "default" option for a workspace and then overriding it in a single crate. - We could add a syntax for passing multiple attributes in a single CLI flag. We would have to find a syntax that avoids ambiguity *and* that does not mis-parse the data inside string literals (i.e. picking a fixed string, such as `|`, would not work because it has to take quote nesting into account). This greatly complicates the implementation for little benefit. This cannot be done in a library or macro. It can be done in an external tool, but only by modifying the source in place, which requires first parsing it, and in general is much more brittle than this approach (for example, preventing the argument from injecting a unterminated block comment, or from injecting a non-attribute grammar production, becomes much harder). From 69df2b8bf09b2980d6da748dc3a18e459849a758 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 04:39:18 -0400 Subject: [PATCH 09/18] Mention that `line!` and `column!` cause problems --- text/3791-crate-attr.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 8cb889cb844..87a9f98dafe 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -152,7 +152,9 @@ In the author's opinion, having source injected via this mechanism does not make # Unresolved questions [unresolved-questions]: #unresolved-questions -None to my knowledge. +How should macros that give information about source code behave when used in this attribute? For example, `line!` does not seem to have an obvious behavior, and `column!` could either include or not include the surrounding `#![]`. + +Note this should not be construed to imply that `--crate-attr` uses a different file/module than the source or otherwise limits macros. `file!`, `include!`, `include_str!`, and `module_path!` should all behave the same as when written in source code. # Future possibilities [future-possibilities]: #future-possibilities From f1cb06b32e7aff182702ff332c991f0d331c4661 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 04:42:53 -0400 Subject: [PATCH 10/18] Mention that the more verbose syntax fixes column! --- text/3791-crate-attr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 87a9f98dafe..29f2a873120 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -131,7 +131,7 @@ In practice, this has not be a large drawback for `crate_name` and `crate_type`, # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -- We could require `--crate-attr=#![foo]` instead. This is more verbose and requires extensive shell quoting, for not much benefit. +- We could require `--crate-attr=#![foo]` instead. This is more verbose and requires extensive shell quoting, for not much benefit. It does however resolve the concern around `column!` (to include the `#![` in the column number), and looks closer to the syntax in a source file. - We could disallow comments in the attribute. This perhaps makes the design less surprising, but complicates the implementation for little benefit. - We could apply `--crate-attr` after attributes in the source, instead of before. This has two drawbacks: 1. It has different behavior for lints than the existing A/W/D flags, so those flags could not semantically be unified with crate-attr. We would be adding yet another precedence group. From 640136e309b35ce8991a75f63090c4ba57f77460 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 04:49:07 -0400 Subject: [PATCH 11/18] oops forgot miri --- text/3791-crate-attr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 29f2a873120..024012ced91 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -7,7 +7,7 @@ [summary]: #summary `--crate-attr` allows injecting crate-level attributes via the command line. -It is supported by all the major tools: Rustc, Rustdoc, Clippy, and Rustfmt. +It is supported by all the official rustc drivers: Rustc, Rustdoc, Clippy, Miri, and Rustfmt. Rustdoc extends it to doctests, discussed in further detail below. It is encouraged, but not required, that external `rustc_driver` tools also support this flag. From 8ef1b640ace12a07c08463d9711481275deeed46 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 05:06:03 -0400 Subject: [PATCH 12/18] mention that #![crate_name] is a mess --- text/3791-crate-attr.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 024012ced91..c78d6712034 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -152,7 +152,9 @@ In the author's opinion, having source injected via this mechanism does not make # Unresolved questions [unresolved-questions]: #unresolved-questions -How should macros that give information about source code behave when used in this attribute? For example, `line!` does not seem to have an obvious behavior, and `column!` could either include or not include the surrounding `#![]`. +- Is `--crate-name` equivalent to `--crate-attr=crate_name`? As currently implemented, the answer is no. Fixing this is hard; see https://github.com/rust-lang/rust/issues/91632 and https://github.com/rust-lang/rust/pull/108221#issuecomment-1435765434 (these do not directly answer why, but I am not aware of any documentation that does). + +- How should macros that give information about source code behave when used in this attribute? For example, `line!` does not seem to have an obvious behavior, and `column!` could either include or not include the surrounding `#![]`. Note this should not be construed to imply that `--crate-attr` uses a different file/module than the source or otherwise limits macros. `file!`, `include!`, `include_str!`, and `module_path!` should all behave the same as when written in source code. From 9a9b8da3b7a6d9a3bf80b3eebc2b2609b53f7815 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 05:15:22 -0400 Subject: [PATCH 13/18] document that this shares a Span with the crate root --- text/3791-crate-attr.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index c78d6712034..0404fa49ad5 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -122,6 +122,14 @@ Compiled on March 18 2025 My awesome crate ``` +## Spans, modules, and editions + +`file!`, `include!`, `include_str!`, and `module_path!` all behave the same as when written in source code. + +`--crate-attr` shares an edition with the crate (i.e. it is affected by `--edition`). In practice this should not be observable. + +The behavior of `file!` and `column!` are not specified; see "Unresolved questions". + # Drawbacks [drawbacks]: #drawbacks @@ -156,8 +164,6 @@ In the author's opinion, having source injected via this mechanism does not make - How should macros that give information about source code behave when used in this attribute? For example, `line!` does not seem to have an obvious behavior, and `column!` could either include or not include the surrounding `#![]`. -Note this should not be construed to imply that `--crate-attr` uses a different file/module than the source or otherwise limits macros. `file!`, `include!`, `include_str!`, and `module_path!` should all behave the same as when written in source code. - # Future possibilities [future-possibilities]: #future-possibilities From b213d1f322023b82bc5c9b842d37eae5fff5a2d5 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 05:24:39 -0400 Subject: [PATCH 14/18] Mention that the edition may be observable --- text/3791-crate-attr.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 0404fa49ad5..44ba526c326 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -126,10 +126,19 @@ My awesome crate `file!`, `include!`, `include_str!`, and `module_path!` all behave the same as when written in source code. -`--crate-attr` shares an edition with the crate (i.e. it is affected by `--edition`). In practice this should not be observable. +`--crate-attr` shares an edition with the crate (i.e. it is affected by `--edition`). This may be observable because `doc` attributes can invoke arbitrary macros. Consider this use of [indoc]: +``` +--crate-attr='doc = indoc::indoc! {" + test + this +"}' +``` +Edition-related changes to how proc-macros are passed tokens may need to consider how crate-attr is affected. The behavior of `file!` and `column!` are not specified; see "Unresolved questions". +[indoc]: https://docs.rs/indoc/latest/indoc/ + # Drawbacks [drawbacks]: #drawbacks @@ -168,3 +177,5 @@ In the author's opinion, having source injected via this mechanism does not make [future-possibilities]: #future-possibilities This proposal would make it easier to use external tools with [`#![register_tool]`][`register-tool`], since they could be configured for a whole workspace at once instead of individually; and could be configured without modifying the source code. + +I would like to add an `#![edition = ...]` attribute and make `--edition` an alias for `--crate-attr=edition`. At that point the interaction between crate-attr and macros becomes more complicated. But right now there is no interaction because `--edition` must always be a flag. From 4c1b2bad1fa53951e8d844c660c718f2d8abdca7 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 05:48:48 -0400 Subject: [PATCH 15/18] oops typo --- text/3791-crate-attr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 44ba526c326..97d3a4e89f9 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -135,7 +135,7 @@ My awesome crate ``` Edition-related changes to how proc-macros are passed tokens may need to consider how crate-attr is affected. -The behavior of `file!` and `column!` are not specified; see "Unresolved questions". +The behavior of `line!` and `column!` are not specified; see "Unresolved questions". [indoc]: https://docs.rs/indoc/latest/indoc/ From a3abbbe136893ba50eddd53b17e83db547a4efdf Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 05:54:43 -0400 Subject: [PATCH 16/18] document that this may interact with custom inner attributes --- text/3791-crate-attr.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 97d3a4e89f9..a141f29fffc 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -179,3 +179,5 @@ In the author's opinion, having source injected via this mechanism does not make This proposal would make it easier to use external tools with [`#![register_tool]`][`register-tool`], since they could be configured for a whole workspace at once instead of individually; and could be configured without modifying the source code. I would like to add an `#![edition = ...]` attribute and make `--edition` an alias for `--crate-attr=edition`. At that point the interaction between crate-attr and macros becomes more complicated. But right now there is no interaction because `--edition` must always be a flag. + +We may want to allow [procedural macros at the crate root](https://github.com/rust-lang/rust/issues/54726). At that point we have to decide whether those macros can see `--crate-attr`. I *think* this should not be an issue because the attributes are appended, not prepended, but it needs more research. From cb4205d9eae0f20b6e36bcf3046e56b43bd55fd5 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 06:01:04 -0400 Subject: [PATCH 17/18] oops typo (redux) --- text/3791-crate-attr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index a141f29fffc..7d7cf14142f 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -180,4 +180,4 @@ This proposal would make it easier to use external tools with [`#![register_tool I would like to add an `#![edition = ...]` attribute and make `--edition` an alias for `--crate-attr=edition`. At that point the interaction between crate-attr and macros becomes more complicated. But right now there is no interaction because `--edition` must always be a flag. -We may want to allow [procedural macros at the crate root](https://github.com/rust-lang/rust/issues/54726). At that point we have to decide whether those macros can see `--crate-attr`. I *think* this should not be an issue because the attributes are appended, not prepended, but it needs more research. +We may want to allow [procedural macros at the crate root](https://github.com/rust-lang/rust/issues/54726). At that point we have to decide whether those macros can see `--crate-attr`. I *think* this should not be an issue because the attributes are prepended, not appended, but it needs more research. From 327a5ec5a4235f526b59af8fb8587168438bd865 Mon Sep 17 00:00:00 2001 From: jyn Date: Wed, 26 Mar 2025 12:20:57 -0400 Subject: [PATCH 18/18] ok maybe edition should not actually be an attribute --- text/3791-crate-attr.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/text/3791-crate-attr.md b/text/3791-crate-attr.md index 7d7cf14142f..2b460fc54dc 100644 --- a/text/3791-crate-attr.md +++ b/text/3791-crate-attr.md @@ -178,6 +178,4 @@ In the author's opinion, having source injected via this mechanism does not make This proposal would make it easier to use external tools with [`#![register_tool]`][`register-tool`], since they could be configured for a whole workspace at once instead of individually; and could be configured without modifying the source code. -I would like to add an `#![edition = ...]` attribute and make `--edition` an alias for `--crate-attr=edition`. At that point the interaction between crate-attr and macros becomes more complicated. But right now there is no interaction because `--edition` must always be a flag. - We may want to allow [procedural macros at the crate root](https://github.com/rust-lang/rust/issues/54726). At that point we have to decide whether those macros can see `--crate-attr`. I *think* this should not be an issue because the attributes are prepended, not appended, but it needs more research.