rust/library/core/src
Joshua Nelson e48b6b4599 Stabilize extended_key_value_attributes
# Stabilization report

 ## Summary

This stabilizes using macro expansion in key-value attributes, like so:

 ```rust
 #[doc = include_str!("my_doc.md")]
 struct S;

 #[path = concat!(env!("OUT_DIR"), "/generated.rs")]
 mod m;
 ```

See the changes to the reference for details on what macros are allowed;
see Petrochenkov's excellent blog post [on internals](https://internals.rust-lang.org/t/macro-expansion-points-in-attributes/11455)
for alternatives that were considered and rejected ("why accept no more
and no less?")

This has been available on nightly since 1.50 with no major issues.

 ## Notes

 ### Accepted syntax

The parser accepts arbitrary Rust expressions in this position, but any expression other than a macro invocation will ultimately lead to an error because it is not expected by the built-in expression forms (e.g., `#[doc]`).  Note that decorators and the like may be able to observe other expression forms.

 ### Expansion ordering

Expansion of macro expressions in "inert" attributes occurs after decorators have executed, analogously to macro expressions appearing in the function body or other parts of decorator input.

There is currently no way for decorators to accept macros in key-value position if macro expansion must be performed before the decorator executes (if the macro can simply be copied into the output for later expansion, that can work).

 ## Test cases

 - https://github.com/rust-lang/rust/blob/master/src/test/ui/attributes/key-value-expansion-on-mac.rs
 - https://github.com/rust-lang/rust/blob/master/src/test/rustdoc/external-doc.rs

The feature has also been dogfooded extensively in the compiler and
standard library:

- https://github.com/rust-lang/rust/pull/83329
- https://github.com/rust-lang/rust/pull/83230
- https://github.com/rust-lang/rust/pull/82641
- https://github.com/rust-lang/rust/pull/80534

 ## Implementation history

- Initial proposal: https://github.com/rust-lang/rust/issues/55414#issuecomment-554005412
- Experiment to see how much code it would break: https://github.com/rust-lang/rust/pull/67121
- Preliminary work to restrict expansion that would conflict with this
feature: https://github.com/rust-lang/rust/pull/77271
- Initial implementation: https://github.com/rust-lang/rust/pull/78837
- Fix for an ICE: https://github.com/rust-lang/rust/pull/80563

 ## Unresolved Questions

~~https://github.com/rust-lang/rust/pull/83366#issuecomment-805180738 listed some concerns, but they have been resolved as of this final report.~~

 ## Additional Information

 There are two workarounds that have a similar effect for `#[doc]`
attributes on nightly. One is to emulate this behavior by using a limited version of this feature that was stabilized for historical reasons:

```rust
macro_rules! forward_inner_docs {
    ($e:expr => $i:item) => {
        #[doc = $e]
        $i
    };
}

forward_inner_docs!(include_str!("lib.rs") => struct S {});
```

This also works for other attributes (like `#[path = concat!(...)]`).
The other is to use `doc(include)`:

```rust
 #![feature(external_doc)]
 #[doc(include = "lib.rs")]
 struct S {}
```

The first works, but is non-trivial for people to discover, and
difficult to read and maintain. The second is a strange special-case for
a particular use of the macro. This generalizes it to work for any use
case, not just including files.

I plan to remove `doc(include)` when this is stabilized. The
`forward_inner_docs` workaround will still compile without warnings, but
I expect it to be used less once it's no longer necessary.
2021-05-18 01:01:36 -04:00
..
alloc Fix const stability since versions. 2021-03-15 14:39:18 +00:00
array Auto merge of #84147 - cuviper:array-method-dispatch, r=nikomatsakis,m-ou-se 2021-04-25 07:26:49 +00:00
char Update char::escape_debug_ext to handle different escapes in strings vs. chars 2021-03-26 11:23:51 +03:00
convert Get rid of "[+] show undocumented items" toggle on numeric From impls 2021-04-22 11:51:05 -07:00
fmt Rollup merge of #84390 - m-ou-se:make-debug-non-exhaustive-without-fields-a-little-bit-less-verbose, r=kennytm 2021-04-21 23:06:21 +02:00
future Rename #[doc(spotlight)] to #[doc(notable_trait)] 2021-03-15 13:59:54 -07:00
hash Auto merge of #83390 - clarfonthey:hasher_docs, r=Amanieu 2021-04-26 08:21:55 +00:00
iter mark internal inplace_iteration traits as hidden 2021-05-16 19:36:21 +02:00
macros Add support for const operands and options to global_asm! 2021-05-13 22:31:57 +01:00
mem Fix typo in MaybeUninit::array_assume_init safety comment 2021-05-05 12:31:38 +03:00
num add BITS associated constant to core::num::Wrapping 2021-05-11 13:36:43 +02:00
ops Auto merge of #84092 - scottmcm:try_trait_initial, r=yaahc,m-ou-se 2021-04-26 23:17:31 +00:00
prelude Bump cfgs 2021-04-04 14:57:05 -04:00
ptr #[inline(always)] on basic pointer methods 2021-05-12 10:10:28 +01:00
slice Clarify documentation for [T]::contains. Fixes #84877. 2021-05-03 12:01:16 -07:00
str str::is_char_boundary - few comments 2021-04-30 20:51:30 +02:00
stream Remove Stream::next 2021-01-23 16:54:56 +01:00
sync Stabilize atomic_fetch_update methods on AtomicBool and AtomicPtr. 2021-04-11 11:45:46 +02:00
task Add the try_trait_v2 library basics 2021-04-17 11:58:18 -07:00
unicode Add a check for ASCII characters in to_upper and to_lower 2021-02-26 11:39:36 -06:00
any.rs Change the Debug impl of Any and UnsafeCell to use finish_non_exhaustive 2021-04-21 14:51:04 +02:00
ascii.rs Replace all fmt.pad with debug_struct 2021-04-21 14:38:24 +02:00
bool.rs Stabilise then 2020-11-22 13:45:14 +00:00
borrow.rs Fix borrow and deref 2021-03-03 11:23:29 +01:00
cell.rs Use #[inline(always)] on trivial UnsafeCell methods 2021-04-04 11:55:13 -07:00
clone.rs Fix core tests 2021-03-03 11:22:49 +01:00
cmp.rs Disallows #![feature(no_coverage)] on stable and beta 2021-05-05 07:52:26 -07:00
default.rs Add diagnostic item to Default trait 2021-03-04 10:14:48 -08:00
ffi.rs Replace all fmt.pad with debug_struct 2021-04-21 14:38:24 +02:00
hint.rs Auto merge of #84725 - sebpop:arm64-isb, r=joshtriplett 2021-05-02 04:54:31 +00:00
internal_macros.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
intrinsics.rs Rollup merge of #84755 - jyn514:core-links, r=kennytm 2021-05-07 00:38:38 +02:00
lazy.rs Capitalize safety comments 2020-09-08 22:26:44 -04:00
lib.rs Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
marker.rs Add additional migrations to handle auto-traits and clone traits 2021-05-06 14:17:59 -04:00
option.rs Reorder the parameter descriptions of map_or and map_or_else 2021-04-27 18:00:30 +08:00
panic.rs Implement new panic!() behaviour for Rust 2021. 2021-01-25 13:48:11 +01:00
panicking.rs Fix panic message of assert_failed_inner 2021-03-13 18:50:43 +08:00
pin.rs Fix overlength lines in core::pin. 2021-01-05 20:14:02 +01:00
primitive.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
raw.rs Deprecate the core::raw / std::raw module 2021-04-15 02:32:33 +02:00
result.rs Reorder the parameter descriptions of map_or and map_or_else 2021-04-27 18:00:30 +08:00
time.rs use else if in std library 2021-05-03 07:05:08 -04:00
tuple.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
unit.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00