From 8e11f47054a1582584f3dfa68ddcce38e5a8870e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 25 Mar 2022 00:40:19 -0700 Subject: [PATCH] Touch up comments from PR 211 --- src/lib.rs | 136 ++++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1277885..7e131ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -661,67 +661,74 @@ macro_rules! quote_bind_next_or_break { }; } -// The obvious way to implement this macro is as a tt muncher. This -// implementation does something more complex, for two reasons. -// - With a tt muncher it's easy to hit Rust's built-in `recursion_limit`, -// which this implementation avoids because it isn't tail recursive. -// - Compile times for a tt muncher are quadratic relative to the length of the -// input. This implementation is linear, so it will be faster (potentially -// much faster) for long inputs. However, the constant factors of this -// implementation are higher than that of a tt muncher, so it is somewhat -// slower than a tt muncher if there are many invocations with short inputs. +// The obvious way to write this macro is as a tt muncher. This implementation +// does something more complex for two reasons. +// +// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which +// this implementation avoids because it isn't tail recursive. +// +// - Compile times for a tt muncher are quadratic relative to the length of +// the input. This implementation is linear, so it will be faster +// (potentially much faster) for big inputs. However, the constant factors +// of this implementation are higher than that of a tt muncher, so it is +// somewhat slower than a tt muncher if there are many invocations with +// short inputs. // // An invocation like this: -// ``` -// quote_each_token! { _s a b c d e f g h i j } -// ``` +// +// quote_each_token!(_s a b c d e f g h i j); +// // expands to this: -// ``` -// quote_tokens_with_context! (_s -// (@ @ @ @ @ @ a b c d e f g h i j) -// (@ @ @ @ @ a b c d e f g h i j @) -// (@ @ @ @ a b c d e f g h i j @ @) -// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) -// (@ @ a b c d e f g h i j @ @ @ @) -// (@ a b c d e f g h i j @ @ @ @ @) -// (a b c d e f g h i j @ @ @ @ @ @) -// ); -// ``` -// which expands to this: -// ``` -// quote_token_with_context! (_s @ @ @ @ @ @ a); -// quote_token_with_context! (_s @ @ @ @ @ a b); -// quote_token_with_context! (_s @ @ @ @ a b c); -// quote_token_with_context! (_s @ @ @ (a) b c d); -// quote_token_with_context! (_s @ @ a (b) c d e); -// quote_token_with_context! (_s @ a b (c) d e f); -// quote_token_with_context! (_s a b c (d) e f g); -// quote_token_with_context! (_s b c d (e) f g h); -// quote_token_with_context! (_s c d e (f) g h i); -// quote_token_with_context! (_s d e f (g) h i j); -// quote_token_with_context! (_s e f g (h) i j @); -// quote_token_with_context! (_s f g h (i) j @ @); -// quote_token_with_context! (_s g h i (j) @ @ @); -// quote_token_with_context! (_s h i j @ @ @ @); -// quote_token_with_context! (_s i j @ @ @ @ @); -// quote_token_with_context! (_s j @ @ @ @ @ @); -// `` -// Without using recursion, we get one invocation of -// `quote_token_with_context!` for each tt, with three tts of context on either -// side. This is enough for the longest possible interpolation form (a -// repetition interpolation with a separator, of the form `# (var) , *`) to be -// fully represented with the first or last tt in the middle. +// +// quote_tokens_with_context!(_s +// (@ @ @ @ @ @ a b c d e f g h i j) +// (@ @ @ @ @ a b c d e f g h i j @) +// (@ @ @ @ a b c d e f g h i j @ @) +// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) +// (@ @ a b c d e f g h i j @ @ @ @) +// (@ a b c d e f g h i j @ @ @ @ @) +// (a b c d e f g h i j @ @ @ @ @ @) +// ); +// +// which gets transposed and expanded to this: +// +// quote_token_with_context!(_s @ @ @ @ @ @ a); +// quote_token_with_context!(_s @ @ @ @ @ a b); +// quote_token_with_context!(_s @ @ @ @ a b c); +// quote_token_with_context!(_s @ @ @ (a) b c d); +// quote_token_with_context!(_s @ @ a (b) c d e); +// quote_token_with_context!(_s @ a b (c) d e f); +// quote_token_with_context!(_s a b c (d) e f g); +// quote_token_with_context!(_s b c d (e) f g h); +// quote_token_with_context!(_s c d e (f) g h i); +// quote_token_with_context!(_s d e f (g) h i j); +// quote_token_with_context!(_s e f g (h) i j @); +// quote_token_with_context!(_s f g h (i) j @ @); +// quote_token_with_context!(_s g h i (j) @ @ @); +// quote_token_with_context!(_s h i j @ @ @ @); +// quote_token_with_context!(_s i j @ @ @ @ @); +// quote_token_with_context!(_s j @ @ @ @ @ @); +// +// Without having used muncher-style recursion, we get one invocation of +// quote_token_with_context for each original tt, with three tts of context on +// either side. This is enough for the longest possible interpolation form (a +// repetition with separator, as in `# (#var) , *`) to be fully represented with +// the first or last tt in the middle. // // The middle tt (surrounded by parentheses) is the tt being processed. -// - When it is a `#`, `quote_token_with_context!` can do an interpolation. The -// interpolation kind will depend on the three subsequent tts. -// - When it is within a later part of an interpolation, it can be ignored, -// because the interpolation has already been done. -// - When it is not part of an interpolation it can be treated normally. -// - When it is a `@` it can be ignored. // -// The parentheses around the middle tt aren't necessary, but they make the -// macro definitions easier to read. +// - When it is a `#`, quote_token_with_context can do an interpolation. The +// interpolation kind will depend on the three subsequent tts. +// +// - When it is within a later part of an interpolation, it can be ignored +// because the interpolation has already been done. +// +// - When it is not part of an interpolation it can be pushed as a single +// token into the output. +// +// - When the middle token is an unparenthesized `@`, that call is one of the +// first 3 or last 3 calls of quote_token_with_context and does not +// correspond to one of the original input tokens, so turns into nothing. #[macro_export] #[doc(hidden)] macro_rules! quote_each_token { @@ -738,7 +745,7 @@ macro_rules! quote_each_token { }; } -// See the comments on `quote_each_token`. +// See the explanation on quote_each_token. #[macro_export] #[doc(hidden)] macro_rules! quote_each_token_spanned { @@ -755,7 +762,7 @@ macro_rules! quote_each_token_spanned { }; } -// See the comments on `quote_each_token`. +// See the explanation on quote_each_token. #[macro_export] #[doc(hidden)] macro_rules! quote_tokens_with_context { @@ -770,7 +777,7 @@ macro_rules! quote_tokens_with_context { }; } -// See the comments on `quote_each_token`. +// See the explanation on quote_each_token. #[macro_export] #[doc(hidden)] macro_rules! quote_tokens_with_context_spanned { @@ -785,14 +792,15 @@ macro_rules! quote_tokens_with_context_spanned { }; } -// See the comments on `quote_each_token`. +// See the explanation on quote_each_token. #[macro_export] #[doc(hidden)] macro_rules! quote_token_with_context { - // `@` is the leading/trailing context character. Ignore it. + // Unparenthesized `@` indicates this call does not correspond to one of the + // original input tokens. Ignore it. ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; - // A repetition interpolation with no separator. + // A repetition with no separator. ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ use $crate::__private::ext::*; let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; @@ -814,7 +822,7 @@ macro_rules! quote_token_with_context { // ... and one step later. ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; - // A repetition interpolation with a separator. + // A repetition with separator. ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ use $crate::__private::ext::*; let mut _i = 0usize; @@ -856,8 +864,8 @@ macro_rules! quote_token_with_context { }; } -// See the comments on `quote_each_token`, and on the individual rules for -// `quote_token_with_context`. +// See the explanation on quote_each_token, and on the individual rules of +// quote_token_with_context. #[macro_export] #[doc(hidden)] macro_rules! quote_token_with_context_spanned {