Eliminate local_inner_macros in favor of non-ident macro paths

This commit is contained in:
David Tolnay 2024-08-01 14:12:44 -07:00
parent eca2658a22
commit 7633cb7f05
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
3 changed files with 37 additions and 38 deletions

View File

@ -50,11 +50,11 @@
/// "comma -->", /// "comma -->",
/// ]); /// ]);
/// ``` /// ```
#[macro_export(local_inner_macros)] #[macro_export]
macro_rules! json { macro_rules! json {
// Hide distracting implementation details from the generated rustdoc. // Hide distracting implementation details from the generated rustdoc.
($($json:tt)+) => { ($($json:tt)+) => {
json_internal!($($json)+) $crate::json_internal!($($json)+)
}; };
} }
@ -65,7 +65,7 @@ macro_rules! json {
// //
// Changes are fine as long as `json_internal!` does not call any new helper // Changes are fine as long as `json_internal!` does not call any new helper
// macros and can still be invoked as `json_internal!($($json)+)`. // macros and can still be invoked as `json_internal!($($json)+)`.
#[macro_export(local_inner_macros)] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! json_internal { macro_rules! json_internal {
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -77,57 +77,57 @@ macro_rules! json_internal {
// Done with trailing comma. // Done with trailing comma.
(@array [$($elems:expr,)*]) => { (@array [$($elems:expr,)*]) => {
json_internal_vec![$($elems,)*] vec![$($elems,)*]
}; };
// Done without trailing comma. // Done without trailing comma.
(@array [$($elems:expr),*]) => { (@array [$($elems:expr),*]) => {
json_internal_vec![$($elems),*] vec![$($elems),*]
}; };
// Next element is `null`. // Next element is `null`.
(@array [$($elems:expr,)*] null $($rest:tt)*) => { (@array [$($elems:expr,)*] null $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(null)] $($rest)*)
}; };
// Next element is `true`. // Next element is `true`.
(@array [$($elems:expr,)*] true $($rest:tt)*) => { (@array [$($elems:expr,)*] true $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(true)] $($rest)*)
}; };
// Next element is `false`. // Next element is `false`.
(@array [$($elems:expr,)*] false $($rest:tt)*) => { (@array [$($elems:expr,)*] false $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(false)] $($rest)*)
}; };
// Next element is an array. // Next element is an array.
(@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!([$($array)*])] $($rest)*)
}; };
// Next element is a map. // Next element is a map.
(@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!({$($map)*})] $($rest)*)
}; };
// Next element is an expression followed by comma. // Next element is an expression followed by comma.
(@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($next),] $($rest)*)
}; };
// Last element is an expression with no trailing comma. // Last element is an expression with no trailing comma.
(@array [$($elems:expr,)*] $last:expr) => { (@array [$($elems:expr,)*] $last:expr) => {
json_internal!(@array [$($elems,)* json_internal!($last)]) $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($last)])
}; };
// Comma after the most recent element. // Comma after the most recent element.
(@array [$($elems:expr),*] , $($rest:tt)*) => { (@array [$($elems:expr),*] , $($rest:tt)*) => {
json_internal!(@array [$($elems,)*] $($rest)*) $crate::json_internal!(@array [$($elems,)*] $($rest)*)
}; };
// Unexpected token after most recent element. // Unexpected token after most recent element.
(@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
json_unexpected!($unexpected) $crate::json_unexpected!($unexpected)
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -146,12 +146,12 @@ macro_rules! json_internal {
// Insert the current entry followed by trailing comma. // Insert the current entry followed by trailing comma.
(@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
let _ = $object.insert(($($key)+).into(), $value); let _ = $object.insert(($($key)+).into(), $value);
json_internal!(@object $object () ($($rest)*) ($($rest)*)); $crate::json_internal!(@object $object () ($($rest)*) ($($rest)*));
}; };
// Current entry followed by unexpected token. // Current entry followed by unexpected token.
(@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
json_unexpected!($unexpected); $crate::json_unexpected!($unexpected);
}; };
// Insert the last entry without trailing comma. // Insert the last entry without trailing comma.
@ -161,78 +161,78 @@ macro_rules! json_internal {
// Next value is `null`. // Next value is `null`.
(@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(null)) $($rest)*);
}; };
// Next value is `true`. // Next value is `true`.
(@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(true)) $($rest)*);
}; };
// Next value is `false`. // Next value is `false`.
(@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(false)) $($rest)*);
}; };
// Next value is an array. // Next value is an array.
(@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!([$($array)*])) $($rest)*);
}; };
// Next value is a map. // Next value is a map.
(@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!({$($map)*})) $($rest)*);
}; };
// Next value is an expression followed by comma. // Next value is an expression followed by comma.
(@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)) , $($rest)*);
}; };
// Last value is an expression with no trailing comma. // Last value is an expression with no trailing comma.
(@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
json_internal!(@object $object [$($key)+] (json_internal!($value))); $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)));
}; };
// Missing value for last entry. Trigger a reasonable error message. // Missing value for last entry. Trigger a reasonable error message.
(@object $object:ident ($($key:tt)+) (:) $copy:tt) => { (@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
// "unexpected end of macro invocation" // "unexpected end of macro invocation"
json_internal!(); $crate::json_internal!();
}; };
// Missing colon and value for last entry. Trigger a reasonable error // Missing colon and value for last entry. Trigger a reasonable error
// message. // message.
(@object $object:ident ($($key:tt)+) () $copy:tt) => { (@object $object:ident ($($key:tt)+) () $copy:tt) => {
// "unexpected end of macro invocation" // "unexpected end of macro invocation"
json_internal!(); $crate::json_internal!();
}; };
// Misplaced colon. Trigger a reasonable error message. // Misplaced colon. Trigger a reasonable error message.
(@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
// Takes no arguments so "no rules expected the token `:`". // Takes no arguments so "no rules expected the token `:`".
json_unexpected!($colon); $crate::json_unexpected!($colon);
}; };
// Found a comma inside a key. Trigger a reasonable error message. // Found a comma inside a key. Trigger a reasonable error message.
(@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
// Takes no arguments so "no rules expected the token `,`". // Takes no arguments so "no rules expected the token `,`".
json_unexpected!($comma); $crate::json_unexpected!($comma);
}; };
// Key is fully parenthesized. This avoids clippy double_parens false // Key is fully parenthesized. This avoids clippy double_parens false
// positives because the parenthesization may be necessary here. // positives because the parenthesization may be necessary here.
(@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); $crate::json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*));
}; };
// Refuse to absorb colon token into key expression. // Refuse to absorb colon token into key expression.
(@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => { (@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
json_expect_expr_comma!($($unexpected)+); $crate::json_expect_expr_comma!($($unexpected)+);
}; };
// Munch a token into the current key. // Munch a token into the current key.
(@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); $crate::json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -254,11 +254,11 @@ macro_rules! json_internal {
}; };
([]) => { ([]) => {
$crate::Value::Array(json_internal_vec![]) $crate::Value::Array(vec![])
}; };
([ $($tt:tt)+ ]) => { ([ $($tt:tt)+ ]) => {
$crate::Value::Array(json_internal!(@array [] $($tt)+)) $crate::Value::Array($crate::json_internal!(@array [] $($tt)+))
}; };
({}) => { ({}) => {
@ -268,7 +268,7 @@ macro_rules! json_internal {
({ $($tt:tt)+ }) => { ({ $($tt:tt)+ }) => {
$crate::Value::Object({ $crate::Value::Object({
let mut object = $crate::Map::new(); let mut object = $crate::Map::new();
json_internal!(@object object () ($($tt)+) ($($tt)+)); $crate::json_internal!(@object object () ($($tt)+) ($($tt)+));
object object
}) })
}; };
@ -280,9 +280,8 @@ macro_rules! json_internal {
}; };
} }
// The json_internal macro above cannot invoke vec directly because it uses // Used by old versions of Rocket.
// local_inner_macros. A vec invocation there would resolve to $crate::vec. // Unused since https://github.com/rwf2/Rocket/commit/c74bcfd40a47b35330db6cafb88e4f3da83e0d17
// Instead invoke vec here outside of local_inner_macros.
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! json_internal_vec { macro_rules! json_internal_vec {

View File

@ -9,4 +9,4 @@ note: while trying to match `@`
| |
| (@array [$($elems:expr,)*]) => { | (@array [$($elems:expr,)*]) => {
| ^ | ^
= note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -9,4 +9,4 @@ note: while trying to match `@`
| |
| (@array [$($elems:expr,)*]) => { | (@array [$($elems:expr,)*]) => {
| ^ | ^
= note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)