diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-02-11 12:10:38 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-02-11 12:10:38 +0100 |
| commit | c9905875933d38aa218a51d65b0b515b5ace4e36 (patch) | |
| tree | 5edde084bca0226751dac5dd4633f4607b55a043 | |
| parent | ddf105b646c6749a2de2451c9a499a354eec79c2 (diff) | |
| download | rust-c9905875933d38aa218a51d65b0b515b5ace4e36.tar.gz rust-c9905875933d38aa218a51d65b0b515b5ace4e36.zip | |
fix: Fix macro transcriber emitting incorrect lifetime tokens
| -rw-r--r-- | crates/hir-def/src/macro_expansion_tests/mbe/regression.rs | 54 | ||||
| -rw-r--r-- | crates/mbe/src/expander/transcriber.rs | 18 | ||||
| -rw-r--r-- | crates/mbe/src/syntax_bridge.rs | 6 | ||||
| -rw-r--r-- | crates/tt/src/lib.rs | 1 |
4 files changed, 73 insertions, 6 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index 6717ee1aa5f..4aad53c3bd7 100644 --- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs @@ -1090,3 +1090,57 @@ fn main() { "#]], ); } + +#[test] +fn regression_16529() { + check( + r#" +mod any { + #[macro_export] + macro_rules! nameable { + { + struct $name:ident[$a:lifetime] + } => { + $crate::any::nameable! { + struct $name[$a] + a + } + }; + { + struct $name:ident[$a:lifetime] + a + } => {}; + } + pub use nameable; + + nameable! { + Name['a] + } +} +"#, + expect![[r#" +mod any { + #[macro_export] + macro_rules! nameable { + { + struct $name:ident[$a:lifetime] + } => { + $crate::any::nameable! { + struct $name[$a] + a + } + }; + { + struct $name:ident[$a:lifetime] + a + } => {}; + } + pub use nameable; + + /* error: unexpected token in input */$crate::any::nameable! { + struct $name[$a]a + } +} +"#]], + ); +} diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs index 9291f799cca..6d3055da286 100644 --- a/crates/mbe/src/expander/transcriber.rs +++ b/crates/mbe/src/expander/transcriber.rs @@ -101,10 +101,20 @@ impl<S: Span> Bindings<S> { }))) } MetaVarKind::Lifetime => { - Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: SmolStr::new_static("'missing"), - span, - }))) + Fragment::Tokens(tt::TokenTree::Subtree(tt::Subtree { + delimiter: tt::Delimiter::invisible_spanned(span), + token_trees: Box::new([ + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { + char: '\'', + span, + spacing: tt::Spacing::Joint, + })), + tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + text: SmolStr::new_static("missing"), + span, + })), + ]), + })) } MetaVarKind::Literal => { Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index bfc5d197f68..3c270e30a9b 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs @@ -700,10 +700,12 @@ impl<S> SynToken<S> { } impl<SpanMap, S: std::fmt::Debug> SrcToken<Converter<SpanMap, S>, S> for SynToken<S> { - fn kind(&self, ctx: &Converter<SpanMap, S>) -> SyntaxKind { + fn kind(&self, _ctx: &Converter<SpanMap, S>) -> SyntaxKind { match self { SynToken::Ordinary(token) => token.kind(), - SynToken::Punct { .. } => SyntaxKind::from_char(self.to_char(ctx).unwrap()).unwrap(), + SynToken::Punct { token, offset: i } => { + SyntaxKind::from_char(token.text().chars().nth(*i).unwrap()).unwrap() + } SynToken::Leaf(_) => { never!(); SyntaxKind::ERROR diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index 9004bff53a8..eec88f80688 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs @@ -152,6 +152,7 @@ pub struct Punct<S> { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Spacing { Alone, + /// Whether the following token is joint to the current one. Joint, } |
