Repository: rust
Issue: Tracking Issue for `proc_macro::ToTokens`
Labels: A-macros,T-libs-api,C-tracking-issue,A-proc-macros,WG-macros

Feature gate: `#![feature(proc_macro_totokens)]`

This is a tracking issue for adding a `ToTokens` trait in `proc_macro`, which can then be used in `proc_macro::quote!`. See [the ACP](https://github.com/rust-lang/libs-team/issues/431) for motivation.

### Public API

This will be similar to [`quote::ToTokens`](https://docs.rs/quote/latest/quote/trait.ToTokens.html). That can be used as a reference for implementation details since it already provides all of these.

```rust
// proc_macro

pub trait ToTokens {
    fn to_tokens(&self, tokens: &mut TokenStream);
    fn to_token_stream(&self) -> TokenStream { ... }
    fn into_token_stream(self) -> TokenStream
       where Self: Sized { ... }
}

// Aggregate token types
impl ToTokens for TokenTree { /* ... */ }
impl ToTokens for TokenStream { /* ... */ }

// Single token types
impl ToTokens for Literal { /* ... */ }
impl ToTokens for Ident { /* ... */ }
impl ToTokens for Punct { /* ... */ }
impl ToTokens for Group { /* ... */ }

// Indirect types
impl<T: ToTokens + ?Sized> ToTokens for &T { /* ... */ }
impl<T: ToTokens + ?Sized> ToTokens for &mut T { /* ... */ }
impl<T: ToTokens + ?Sized> ToTokens for Box<T> { /* ... */ }
impl<T: ToTokens + ?Sized> ToTokens for Rc<T> { /* ... */ }
impl<T: ToTokens> ToTokens for Option<T> { /* ... */ }
impl<T: ToTokens + ToOwned + ?Sized> ToTokens for Cow<T> { /* ... */ }

// Types that can create `Literal`s
impl ToTokens for {u,i}{8,16,32,64,128} { /* ... */ }
impl ToTokens for f{16,32,64,128} { /* ... */ }
impl ToTokens for bool { /* ... */ }
impl ToTokens for char { /* ... */ }
impl ToTokens for str { /* ... */ }
impl ToTokens for String { /* ... */ }
impl ToTokens for CStr { /* ... */ }
impl ToTokens for CString { /* ... */ }

/* migrate the following APIs, if possible without breakage */

// currently `Extend<TokenStream>` and `Extend<TokenTree>`
impl Extend<T: ToTokens> for TokenStream { /* ... */ }

// currently `FromIterator<TokenStream>` and `FromIterator<TokenTree>`
impl FromIterator<T: ToTokens> for TokenStream { /* ... */ }
```

### Steps / History


- [x] ACP: https://github.com/rust-lang/libs-team/issues/431
- [x] Implementation in `proc_macro`: https://github.com/rust-lang/rust/pull/131441
- [ ] Update `proc_macro::quote!` to use these traits: #...
- [ ] Final comment period (FCP)[^1]
- [ ] Stabilization PR

<!--
Once the feature has gone through a few release cycles and there are no
unresolved questions left, the feature might be ready for stabilization.

If this feature didn't go through the RFC process, a final comment period
(FCP) is always needed before stabilization. This works as follows:

A library API team member can kick off the stabilization process, at which point
the rfcbot will ask all the team members to verify they agree with
stabilization. Once enough members agree and there are no concerns, the final
comment period begins: this issue will be marked as such and will be listed
in the next This Week in Rust newsletter. If no blocking concerns are raised in
that period of 10 days, a stabilization PR can be opened by anyone.
-->

### Unresolved Questions

- What should this be named? `ToTokens` doesn't seem quite accurate, but I don't know what would be better (`ToTokenStream`? `ExtendTokenStream`? Those seem a bit clunky).
- Considering `impl<T: ToTokens> ToTokens` for T is provided, should to_tokens take self by value rather than by reference so cloning isn't always necessary? (fn to_tokens(self, tokens: &mut TokenStream))

[^1]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"SpriteOvO"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->