Skip to content

Commit 925b30e

Browse files
committed
rust: quote: import crate
This is a subset of the Rust `quote` crate, version 1.0.35, licensed under "Apache-2.0 OR MIT", from: https://github.com/dtolnay/quote/raw/1.0.35/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/dtolnay/quote/blob/1.0.35/README.md#license https://github.com/dtolnay/quote/blob/1.0.35/LICENSE-APACHE https://github.com/dtolnay/quote/blob/1.0.35/LICENSE-MIT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. The following script may be used to verify the contents: for path in $(cd rust/quote/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/dtolnay/quote/raw/1.0.35/src/$path \ | diff --unified rust/quote/$path - && echo $path: OK done Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 24954e2 commit 925b30e

File tree

7 files changed

+2599
-0
lines changed

7 files changed

+2599
-0
lines changed

rust/quote/ext.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use super::ToTokens;
2+
use core::iter;
3+
use proc_macro2::{TokenStream, TokenTree};
4+
5+
/// TokenStream extension trait with methods for appending tokens.
6+
///
7+
/// This trait is sealed and cannot be implemented outside of the `quote` crate.
8+
pub trait TokenStreamExt: private::Sealed {
9+
/// For use by `ToTokens` implementations.
10+
///
11+
/// Appends the token specified to this list of tokens.
12+
fn append<U>(&mut self, token: U)
13+
where
14+
U: Into<TokenTree>;
15+
16+
/// For use by `ToTokens` implementations.
17+
///
18+
/// ```
19+
/// # use quote::{quote, TokenStreamExt, ToTokens};
20+
/// # use proc_macro2::TokenStream;
21+
/// #
22+
/// struct X;
23+
///
24+
/// impl ToTokens for X {
25+
/// fn to_tokens(&self, tokens: &mut TokenStream) {
26+
/// tokens.append_all(&[true, false]);
27+
/// }
28+
/// }
29+
///
30+
/// let tokens = quote!(#X);
31+
/// assert_eq!(tokens.to_string(), "true false");
32+
/// ```
33+
fn append_all<I>(&mut self, iter: I)
34+
where
35+
I: IntoIterator,
36+
I::Item: ToTokens;
37+
38+
/// For use by `ToTokens` implementations.
39+
///
40+
/// Appends all of the items in the iterator `I`, separated by the tokens
41+
/// `U`.
42+
fn append_separated<I, U>(&mut self, iter: I, op: U)
43+
where
44+
I: IntoIterator,
45+
I::Item: ToTokens,
46+
U: ToTokens;
47+
48+
/// For use by `ToTokens` implementations.
49+
///
50+
/// Appends all tokens in the iterator `I`, appending `U` after each
51+
/// element, including after the last element of the iterator.
52+
fn append_terminated<I, U>(&mut self, iter: I, term: U)
53+
where
54+
I: IntoIterator,
55+
I::Item: ToTokens,
56+
U: ToTokens;
57+
}
58+
59+
impl TokenStreamExt for TokenStream {
60+
fn append<U>(&mut self, token: U)
61+
where
62+
U: Into<TokenTree>,
63+
{
64+
self.extend(iter::once(token.into()));
65+
}
66+
67+
fn append_all<I>(&mut self, iter: I)
68+
where
69+
I: IntoIterator,
70+
I::Item: ToTokens,
71+
{
72+
for token in iter {
73+
token.to_tokens(self);
74+
}
75+
}
76+
77+
fn append_separated<I, U>(&mut self, iter: I, op: U)
78+
where
79+
I: IntoIterator,
80+
I::Item: ToTokens,
81+
U: ToTokens,
82+
{
83+
for (i, token) in iter.into_iter().enumerate() {
84+
if i > 0 {
85+
op.to_tokens(self);
86+
}
87+
token.to_tokens(self);
88+
}
89+
}
90+
91+
fn append_terminated<I, U>(&mut self, iter: I, term: U)
92+
where
93+
I: IntoIterator,
94+
I::Item: ToTokens,
95+
U: ToTokens,
96+
{
97+
for token in iter {
98+
token.to_tokens(self);
99+
term.to_tokens(self);
100+
}
101+
}
102+
}
103+
104+
mod private {
105+
use proc_macro2::TokenStream;
106+
107+
pub trait Sealed {}
108+
109+
impl Sealed for TokenStream {}
110+
}

rust/quote/format.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/// Formatting macro for constructing `Ident`s.
2+
///
3+
/// <br>
4+
///
5+
/// # Syntax
6+
///
7+
/// Syntax is copied from the [`format!`] macro, supporting both positional and
8+
/// named arguments.
9+
///
10+
/// Only a limited set of formatting traits are supported. The current mapping
11+
/// of format types to traits is:
12+
///
13+
/// * `{}` ⇒ [`IdentFragment`]
14+
/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
15+
/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
16+
/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
17+
/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
18+
///
19+
/// See [`std::fmt`] for more information.
20+
///
21+
/// <br>
22+
///
23+
/// # IdentFragment
24+
///
25+
/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
26+
/// default. This trait is like `Display`, with a few differences:
27+
///
28+
/// * `IdentFragment` is only implemented for a limited set of types, such as
29+
/// unsigned integers and strings.
30+
/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
31+
///
32+
/// [`IdentFragment`]: crate::IdentFragment
33+
/// [`Ident`]: proc_macro2::Ident
34+
///
35+
/// <br>
36+
///
37+
/// # Hygiene
38+
///
39+
/// The [`Span`] of the first `Ident` argument is used as the span of the final
40+
/// identifier, falling back to [`Span::call_site`] when no identifiers are
41+
/// provided.
42+
///
43+
/// ```
44+
/// # use quote::format_ident;
45+
/// # let ident = format_ident!("Ident");
46+
/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
47+
/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
48+
/// assert_eq!(my_ident, "MyIdentIsCool");
49+
/// ```
50+
///
51+
/// Alternatively, the span can be overridden by passing the `span` named
52+
/// argument.
53+
///
54+
/// ```
55+
/// # use quote::format_ident;
56+
/// # const IGNORE_TOKENS: &'static str = stringify! {
57+
/// let my_span = /* ... */;
58+
/// # };
59+
/// # let my_span = proc_macro2::Span::call_site();
60+
/// format_ident!("MyIdent", span = my_span);
61+
/// ```
62+
///
63+
/// [`Span`]: proc_macro2::Span
64+
/// [`Span::call_site`]: proc_macro2::Span::call_site
65+
///
66+
/// <p><br></p>
67+
///
68+
/// # Panics
69+
///
70+
/// This method will panic if the resulting formatted string is not a valid
71+
/// identifier.
72+
///
73+
/// <br>
74+
///
75+
/// # Examples
76+
///
77+
/// Composing raw and non-raw identifiers:
78+
/// ```
79+
/// # use quote::format_ident;
80+
/// let my_ident = format_ident!("My{}", "Ident");
81+
/// assert_eq!(my_ident, "MyIdent");
82+
///
83+
/// let raw = format_ident!("r#Raw");
84+
/// assert_eq!(raw, "r#Raw");
85+
///
86+
/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
87+
/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
88+
/// ```
89+
///
90+
/// Integer formatting options:
91+
/// ```
92+
/// # use quote::format_ident;
93+
/// let num: u32 = 10;
94+
///
95+
/// let decimal = format_ident!("Id_{}", num);
96+
/// assert_eq!(decimal, "Id_10");
97+
///
98+
/// let octal = format_ident!("Id_{:o}", num);
99+
/// assert_eq!(octal, "Id_12");
100+
///
101+
/// let binary = format_ident!("Id_{:b}", num);
102+
/// assert_eq!(binary, "Id_1010");
103+
///
104+
/// let lower_hex = format_ident!("Id_{:x}", num);
105+
/// assert_eq!(lower_hex, "Id_a");
106+
///
107+
/// let upper_hex = format_ident!("Id_{:X}", num);
108+
/// assert_eq!(upper_hex, "Id_A");
109+
/// ```
110+
#[macro_export]
111+
macro_rules! format_ident {
112+
($fmt:expr) => {
113+
$crate::format_ident_impl!([
114+
$crate::__private::Option::None,
115+
$fmt
116+
])
117+
};
118+
119+
($fmt:expr, $($rest:tt)*) => {
120+
$crate::format_ident_impl!([
121+
$crate::__private::Option::None,
122+
$fmt
123+
] $($rest)*)
124+
};
125+
}
126+
127+
#[macro_export]
128+
#[doc(hidden)]
129+
macro_rules! format_ident_impl {
130+
// Final state
131+
([$span:expr, $($fmt:tt)*]) => {
132+
$crate::__private::mk_ident(
133+
&$crate::__private::format!($($fmt)*),
134+
$span,
135+
)
136+
};
137+
138+
// Span argument
139+
([$old:expr, $($fmt:tt)*] span = $span:expr) => {
140+
$crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
141+
};
142+
([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
143+
$crate::format_ident_impl!([
144+
$crate::__private::Option::Some::<$crate::__private::Span>($span),
145+
$($fmt)*
146+
] $($rest)*)
147+
};
148+
149+
// Named argument
150+
([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
151+
$crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
152+
};
153+
([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
154+
match $crate::__private::IdentFragmentAdapter(&$arg) {
155+
arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
156+
}
157+
};
158+
159+
// Positional argument
160+
([$span:expr, $($fmt:tt)*] $arg:expr) => {
161+
$crate::format_ident_impl!([$span, $($fmt)*] $arg,)
162+
};
163+
([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
164+
match $crate::__private::IdentFragmentAdapter(&$arg) {
165+
arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
166+
}
167+
};
168+
}

rust/quote/ident_fragment.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use alloc::borrow::Cow;
2+
use core::fmt;
3+
use proc_macro2::{Ident, Span};
4+
5+
/// Specialized formatting trait used by `format_ident!`.
6+
///
7+
/// [`Ident`] arguments formatted using this trait will have their `r#` prefix
8+
/// stripped, if present.
9+
///
10+
/// See [`format_ident!`] for more information.
11+
///
12+
/// [`format_ident!`]: crate::format_ident
13+
pub trait IdentFragment {
14+
/// Format this value as an identifier fragment.
15+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
16+
17+
/// Span associated with this `IdentFragment`.
18+
///
19+
/// If non-`None`, may be inherited by formatted identifiers.
20+
fn span(&self) -> Option<Span> {
21+
None
22+
}
23+
}
24+
25+
impl<T: IdentFragment + ?Sized> IdentFragment for &T {
26+
fn span(&self) -> Option<Span> {
27+
<T as IdentFragment>::span(*self)
28+
}
29+
30+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31+
IdentFragment::fmt(*self, f)
32+
}
33+
}
34+
35+
impl<T: IdentFragment + ?Sized> IdentFragment for &mut T {
36+
fn span(&self) -> Option<Span> {
37+
<T as IdentFragment>::span(*self)
38+
}
39+
40+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41+
IdentFragment::fmt(*self, f)
42+
}
43+
}
44+
45+
impl IdentFragment for Ident {
46+
fn span(&self) -> Option<Span> {
47+
Some(self.span())
48+
}
49+
50+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51+
let id = self.to_string();
52+
if let Some(id) = id.strip_prefix("r#") {
53+
fmt::Display::fmt(id, f)
54+
} else {
55+
fmt::Display::fmt(&id[..], f)
56+
}
57+
}
58+
}
59+
60+
impl<T> IdentFragment for Cow<'_, T>
61+
where
62+
T: IdentFragment + ToOwned + ?Sized,
63+
{
64+
fn span(&self) -> Option<Span> {
65+
T::span(self)
66+
}
67+
68+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69+
T::fmt(self, f)
70+
}
71+
}
72+
73+
// Limited set of types which this is implemented for, as we want to avoid types
74+
// which will often include non-identifier characters in their `Display` impl.
75+
macro_rules! ident_fragment_display {
76+
($($T:ty),*) => {
77+
$(
78+
impl IdentFragment for $T {
79+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80+
fmt::Display::fmt(self, f)
81+
}
82+
}
83+
)*
84+
};
85+
}
86+
87+
ident_fragment_display!(bool, str, String, char);
88+
ident_fragment_display!(u8, u16, u32, u64, u128, usize);

0 commit comments

Comments
 (0)