forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 472
rust: quote: import crate
This is a subset of the Rust `quote` crate, version 1.0.21, licensed under "Apache-2.0 OR MIT", from: https://github.com/dtolnay/quote/raw/1.0.21/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.21/README.md#license https://github.com/dtolnay/quote/blob/1.0.21/LICENSE-APACHE https://github.com/dtolnay/quote/blob/1.0.21/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.21/src/$path \ | diff --unified rust/quote/$path - && echo $path: OK done Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
- Loading branch information
commit 90523afa3d810630ed8f41e23acc4deb259cad5a
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use super::ToTokens; | ||
use core::iter; | ||
use proc_macro2::{TokenStream, TokenTree}; | ||
|
||
/// TokenStream extension trait with methods for appending tokens. | ||
/// | ||
/// This trait is sealed and cannot be implemented outside of the `quote` crate. | ||
pub trait TokenStreamExt: private::Sealed { | ||
/// For use by `ToTokens` implementations. | ||
/// | ||
/// Appends the token specified to this list of tokens. | ||
fn append<U>(&mut self, token: U) | ||
where | ||
U: Into<TokenTree>; | ||
|
||
/// For use by `ToTokens` implementations. | ||
/// | ||
/// ``` | ||
/// # use quote::{quote, TokenStreamExt, ToTokens}; | ||
/// # use proc_macro2::TokenStream; | ||
/// # | ||
/// struct X; | ||
/// | ||
/// impl ToTokens for X { | ||
/// fn to_tokens(&self, tokens: &mut TokenStream) { | ||
/// tokens.append_all(&[true, false]); | ||
/// } | ||
/// } | ||
/// | ||
/// let tokens = quote!(#X); | ||
/// assert_eq!(tokens.to_string(), "true false"); | ||
/// ``` | ||
fn append_all<I>(&mut self, iter: I) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens; | ||
|
||
/// For use by `ToTokens` implementations. | ||
/// | ||
/// Appends all of the items in the iterator `I`, separated by the tokens | ||
/// `U`. | ||
fn append_separated<I, U>(&mut self, iter: I, op: U) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens, | ||
U: ToTokens; | ||
|
||
/// For use by `ToTokens` implementations. | ||
/// | ||
/// Appends all tokens in the iterator `I`, appending `U` after each | ||
/// element, including after the last element of the iterator. | ||
fn append_terminated<I, U>(&mut self, iter: I, term: U) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens, | ||
U: ToTokens; | ||
} | ||
|
||
impl TokenStreamExt for TokenStream { | ||
fn append<U>(&mut self, token: U) | ||
where | ||
U: Into<TokenTree>, | ||
{ | ||
self.extend(iter::once(token.into())); | ||
} | ||
|
||
fn append_all<I>(&mut self, iter: I) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens, | ||
{ | ||
for token in iter { | ||
token.to_tokens(self); | ||
} | ||
} | ||
|
||
fn append_separated<I, U>(&mut self, iter: I, op: U) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens, | ||
U: ToTokens, | ||
{ | ||
for (i, token) in iter.into_iter().enumerate() { | ||
if i > 0 { | ||
op.to_tokens(self); | ||
} | ||
token.to_tokens(self); | ||
} | ||
} | ||
|
||
fn append_terminated<I, U>(&mut self, iter: I, term: U) | ||
where | ||
I: IntoIterator, | ||
I::Item: ToTokens, | ||
U: ToTokens, | ||
{ | ||
for token in iter { | ||
token.to_tokens(self); | ||
term.to_tokens(self); | ||
} | ||
} | ||
} | ||
|
||
mod private { | ||
use proc_macro2::TokenStream; | ||
|
||
pub trait Sealed {} | ||
|
||
impl Sealed for TokenStream {} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/// Formatting macro for constructing `Ident`s. | ||
/// | ||
/// <br> | ||
/// | ||
/// # Syntax | ||
/// | ||
/// Syntax is copied from the [`format!`] macro, supporting both positional and | ||
/// named arguments. | ||
/// | ||
/// Only a limited set of formatting traits are supported. The current mapping | ||
/// of format types to traits is: | ||
/// | ||
/// * `{}` ⇒ [`IdentFragment`] | ||
/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal) | ||
/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex) | ||
/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex) | ||
/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary) | ||
/// | ||
/// See [`std::fmt`] for more information. | ||
/// | ||
/// <br> | ||
/// | ||
/// # IdentFragment | ||
/// | ||
/// Unlike `format!`, this macro uses the [`IdentFragment`] 8000 formatting trait by | ||
/// default. This trait is like `Display`, with a few differences: | ||
/// | ||
/// * `IdentFragment` is only implemented for a limited set of types, such as | ||
/// unsigned integers and strings. | ||
/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present. | ||
/// | ||
/// [`IdentFragment`]: crate::IdentFragment | ||
/// [`Ident`]: proc_macro2::Ident | ||
/// | ||
/// <br> | ||
/// | ||
/// # Hygiene | ||
/// | ||
/// The [`Span`] of the first `Ident` argument is used as the span of the final | ||
/// identifier, falling back to [`Span::call_site`] when no identifiers are | ||
/// provided. | ||
/// | ||
/// ``` | ||
/// # use quote::format_ident; | ||
/// # let ident = format_ident!("Ident"); | ||
/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it. | ||
/// let my_ident = format_ident!("My{}{}", ident, "IsCool"); | ||
/// assert_eq!(my_ident, "MyIdentIsCool"); | ||
/// ``` | ||
/// | ||
/// Alternatively, the span can be overridden by passing the `span` named | ||
/// argument. | ||
/// | ||
/// ``` | ||
/// # use quote::format_ident; | ||
/// # const IGNORE_TOKENS: &'static str = stringify! { | ||
/// let my_span = /* ... */; | ||
/// # }; | ||
/// # let my_span = proc_macro2::Span::call_site(); | ||
/// format_ident!("MyIdent", span = my_span); | ||
/// ``` | ||
/// | ||
/// [`Span`]: proc_macro2::Span | ||
/// [`Span::call_site`]: proc_macro2::Span::call_site | ||
/// | ||
/// <p><br></p> | ||
/// | ||
/// # Panics | ||
/// | ||
/// This method will panic if the resulting formatted string is not a valid | ||
/// identifier. | ||
/// | ||
/// <br> | ||
/// | ||
/// # Examples | ||
/// | ||
/// Composing raw and non-raw identifiers: | ||
/// ``` | ||
/// # use quote::format_ident; | ||
/// let my_ident = format_ident!("My{}", "Ident"); | ||
/// assert_eq!(my_ident, "MyIdent"); | ||
/// | ||
/// let raw = format_ident!("r#Raw"); | ||
/// assert_eq!(raw, "r#Raw"); | ||
/// | ||
/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw); | ||
/// assert_eq!(my_ident_raw, "MyIdentIsRaw"); | ||
/// ``` | ||
/// | ||
/// Integer formatting options: | ||
/// ``` | ||
/// # use quote::format_ident; | ||
/// let num: u32 = 10; | ||
/// | ||
/// let decimal = format_ident!("Id_{}", num); | ||
/// assert_eq!(decimal, "Id_10"); | ||
/// | ||
/// let octal = format_ident!("Id_{:o}", num); | ||
/// assert_eq!(octal, "Id_12"); | ||
/// | ||
/// let binary = format_ident!("Id_{:b}", num); | ||
/// assert_eq!(binary, "Id_1010"); | ||
/// | ||
/// let lower_hex = format_ident!("Id_{:x}", num); | ||
/// assert_eq!(lower_hex, "Id_a"); | ||
/// | ||
/// let upper_hex = format_ident!("Id_{:X}", num); | ||
/// assert_eq!(upper_hex, "Id_A"); | ||
/// ``` | ||
#[macro_export] | ||
macro_rules! format_ident { | ||
($fmt:expr) => { | ||
$crate::format_ident_impl!([ | ||
$crate::__private::Option::None, | ||
$fmt | ||
]) | ||
}; | ||
|
||
($fmt:expr, $($rest:tt)*) => { | ||
$crate::format_ident_impl!([ | ||
$crate::__private::Option::None, | ||
$fmt | ||
] $($rest)*) | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
#[doc(hidden)] | ||
macro_rules! format_ident_impl { | ||
// Final state | ||
([$span:expr, $($fmt:tt)*]) => { | ||
$crate::__private::mk_ident( | ||
&$crate::__private::format!($($fmt)*), | ||
$span, | ||
) | ||
}; | ||
|
||
// Span argument | ||
([$old:expr, $($fmt:tt)*] span = $span:expr) => { | ||
$crate::format_ident_impl!([$old, $($fmt)*] span = $span,) | ||
}; | ||
([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => { | ||
$crate::format_ident_impl!([ | ||
$crate::__private::Option::Some::<$crate::__private::Span>($span), | ||
$($fmt)* | ||
] $($rest)*) | ||
}; | ||
|
||
// Named argument | ||
([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => { | ||
$crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,) | ||
}; | ||
([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => { | ||
match $crate::__private::IdentFragmentAdapter(&$arg) { | ||
arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*), | ||
} | ||
}; | ||
|
||
// Positional argument | ||
([$span:expr, $($fmt:tt)*] $arg:expr) => { | ||
$crate::format_ident_impl!([$span, $($fmt)*] $arg,) | ||
}; | ||
([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => { | ||
match $crate::__private::IdentFragmentAdapter(&$arg) { | ||
arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*), | ||
} | ||
}; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
use core::fmt; | ||
use proc_macro2::{Ident, Span}; | ||
use std::borrow::Cow; | ||
|
||
/// Specialized formatting trait used by `format_ident!`. | ||
/// | ||
/// [`Ident`] arguments formatted using this trait will have their `r#` prefix | ||
/// stripped, if present. | ||
/// | ||
/// See [`format_ident!`] for more information. | ||
pub trait IdentFragment { | ||
/// Format this value as an identifier fragment. | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; | ||
|
||
/// Span associated with this `IdentFragment`. | ||
/// | ||
/// If non-`None`, may be inherited by formatted identifiers. | ||
fn span(&self) -> Option<Span> { | ||
None | ||
} | ||
} | ||
|
||
impl<T: IdentFragment + ?Sized> IdentFragment for &T { | ||
fn span(&self) -> Option<Span> { | ||
<T as IdentFragment>::span(*self) | ||
} | ||
|
||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
IdentFragment::fmt(*self, f) | ||
} | ||
} | ||
|
||
impl<T: IdentFragment + ?Sized> IdentFragment for &mut T { | ||
fn span(&self) -> Option<Span> { | ||
<T as IdentFragment>::span(*self) | ||
} | ||
|
||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
IdentFragment::fmt(*self, f) | ||
} | ||
} | ||
|
||
impl IdentFragment for Ident { | ||
fn span(&self) -> Option<Span> { | ||
Some(self.span()) | ||
} | ||
|
||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
let id = self.to_string(); | ||
if id.starts_with("r#") { | ||
fmt::Display::fmt(&id[2..], f) | ||
} else { | ||
fmt::Display::fmt(&id[..], f) | ||
} | ||
} | ||
} | ||
|
||
impl<T> IdentFragment for Cow<'_, T> | ||
where | ||
T: IdentFragment + ToOwned + ?Sized, | ||
{ | ||
fn span(&self) -> Option<Span> { | ||
T::span(self) | ||
} | ||
|
||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
T::fmt(self, f) | ||
} | ||
} | ||
|
||
// Limited set of types which this is implemented for, as we want to avoid types | ||
// which will often include non-identifier characters in their `Display` impl. | ||
macro_rules! ident_fragment_display { | ||
($($T:ty),*) => { | ||
$( | ||
impl IdentFragment for $T { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Display::fmt(self, f) | ||
} | ||
} | ||
)* | ||
}; | ||
} | ||
|
||
ident_fragment_display!(bool, str, String, char); | ||
ident_fragment_display!(u8, u16, u32, u64, u128, usize); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Third-party crates support:
proc-macro2
,quote
,syn
,serde
andserde_derive
#1007New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rust-next
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
Third-party crates support:
proc-macro2
,quote
,syn
,serde
andserde_derive
#1007Changes from 1 commit
4d28d13
ff8917c
bb40745
90523af
d7f4b0d
313e6c9
f9bcfd0
3916aa6
2e4b1b4
7fcbf51
22605b8
b56a317
6f37f9b
16bebcf
9121b11
7d2ea51
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.