rust/compiler
Jack Huey 3c99dcd82d
Rollup merge of #83366 - jyn514:stabilize-key-value-attrs, r=petrochenkov
Stabilize extended_key_value_attributes

Closes https://github.com/rust-lang/rust/issues/44732. Closes https://github.com/rust-lang/rust/issues/78835. Closes https://github.com/rust-lang/rust/issues/82768 (by making it irrelevant).

 # 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 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
(https://github.com/rust-lang/rust/pull/82539). 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 22:35:54 -04:00
..
rustc use jemallocator in rustc/rustdoc 2021-04-04 14:10:26 -07:00
rustc_apfloat Use iter::zip in compiler/ 2021-03-26 09:32:31 -07:00
rustc_arena Remove (lots of) dead code 2021-03-27 22:16:33 -04:00
rustc_ast Implement Anonymous{Struct, Union} in the AST 2021-05-16 09:49:16 -05:00
rustc_ast_lowering Auto merge of #84767 - scottmcm:try_trait_actual, r=lcnr 2021-05-18 20:50:01 +00:00
rustc_ast_passes Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_ast_pretty Implement Anonymous{Struct, Union} in the AST 2021-05-16 09:49:16 -05:00
rustc_attr Allow specifying alignment for functions 2021-04-05 17:36:51 -04:00
rustc_builtin_macros Add support for const operands and options to global_asm! 2021-05-13 22:31:57 +01:00
rustc_codegen_cranelift Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_codegen_llvm Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_codegen_ssa Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_data_structures Only compute Obligation cache_key once in register_obligation_at 2021-05-04 11:57:53 -07:00
rustc_driver Use () for analysis. 2021-05-12 14:01:16 +02:00
rustc_error_codes swap function order for better read flow 2021-05-13 13:22:24 +02:00
rustc_errors Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_expand Auto merge of #83813 - cbeuw:remap-std, r=michaelwoerister 2021-05-12 11:05:56 +00:00
rustc_feature Rollup merge of #83366 - jyn514:stabilize-key-value-attrs, r=petrochenkov 2021-05-18 22:35:54 -04:00
rustc_fs_util Optimize away a fs::metadata call. 2021-01-06 08:33:15 -08:00
rustc_graphviz Remove (lots of) dead code 2021-03-27 22:16:33 -04:00
rustc_hir Rollup merge of #83366 - jyn514:stabilize-key-value-attrs, r=petrochenkov 2021-05-18 22:35:54 -04:00
rustc_hir_pretty Add support for const operands and options to global_asm! 2021-05-13 22:31:57 +01:00
rustc_incremental Use () for codegen queries. 2021-05-12 13:58:46 +02:00
rustc_index Change bitwise operator to more easily keep data in vector registers 2021-05-04 11:55:18 -04:00
rustc_infer Add comments to opportunistic resolve functions 2021-05-15 23:36:10 -04:00
rustc_interface Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_lexer Fix outdated crate names in compiler docs 2021-04-08 11:12:14 -05:00
rustc_lint Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_lint_defs Add additional migrations to handle auto-traits and clone traits 2021-05-06 14:17:59 -04:00
rustc_llvm Auto merge of #85190 - mati865:update-cc, r=Mark-Simulacrum 2021-05-14 04:12:40 +00:00
rustc_macros Use iter::zip in compiler/ 2021-03-26 09:32:31 -07:00
rustc_metadata Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_middle Auto merge of #85437 - GuillaumeGomez:rollup-3jcirty, r=GuillaumeGomez 2021-05-18 14:48:53 +00:00
rustc_mir Address review comments 2021-05-17 21:31:05 -04:00
rustc_mir_build Remove remnants of BorrowOfPackedField 2021-05-17 19:32:58 +02:00
rustc_parse Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_parse_format Rollup merge of #83348 - osa1:issue83344, r=jackh726 2021-03-28 01:33:13 +09:00
rustc_passes Rollup merge of #85339 - FabianWolff:issue-83893, r=varkor 2021-05-18 14:08:51 +02:00
rustc_plugin_impl Use () for plugin_registrar_fn. 2021-05-12 13:58:43 +02:00
rustc_privacy Use () for privacy. 2021-05-12 13:58:45 +02:00
rustc_query_impl Use () in dependency_formats. 2021-05-12 13:58:41 +02:00
rustc_query_system Show nicer error when an 'unstable fingerprints' error occurs 2021-05-10 17:43:51 -04:00
rustc_resolve Add support for const operands and options to global_asm! 2021-05-13 22:31:57 +01:00
rustc_save_analysis Auto merge of #85178 - cjgillot:local-crate, r=oli-obk 2021-05-17 01:42:03 +00:00
rustc_serialize Auto merge of #83465 - michaelwoerister:safe-read_raw_bytes, r=cjgillot 2021-03-26 01:28:59 +00:00
rustc_session Auto merge of #83129 - LeSeulArtichaut:thir-unsafeck, r=nikomatsakis 2021-05-13 10:49:29 +00:00
rustc_span Auto merge of #84767 - scottmcm:try_trait_actual, r=lcnr 2021-05-18 20:50:01 +00:00
rustc_symbol_mangling Use () for proc_macro_decls_static. 2021-05-12 13:58:43 +02:00
rustc_target Auto merge of #85312 - ehuss:macro_use-unused-attr, r=petrochenkov 2021-05-16 20:19:45 +00:00
rustc_trait_selection Rollup merge of #85369 - FabianWolff:issue-84973, r=jackh726 2021-05-18 14:08:55 +02:00
rustc_traits Auto merge of #83207 - oli-obk:valtree2, r=lcnr 2021-04-02 10:28:12 +00:00
rustc_ty_utils add new attribute rustc_insignificant_dtor and a query to check if a type has a significant drop 2021-05-14 22:57:33 -04:00
rustc_type_ir Make TypeFoldable::is_global() false when fresh tys/consts are present 2021-05-01 16:58:33 -04:00
rustc_typeck Rollup merge of #85393 - Aaron1011:async-type-err, r=varkor 2021-05-18 14:08:56 +02:00