Skip to content

Commit 3c24189

Browse files
committed
Auto merge of rust-lang#16530 - Veykril:missing-lt, r=Veykril
fix: Fix macro transcriber emitting incorrect lifetime tokens Fixes rust-lang/rust-analyzer#16529
2 parents 5e1b09b + c990587 commit 3c24189

File tree

4 files changed

+73
-6
lines changed

4 files changed

+73
-6
lines changed

crates/hir-def/src/macro_expansion_tests/mbe/regression.rs

+54
Original file line numberDiff line numberDiff line change
@@ -1090,3 +1090,57 @@ fn main() {
10901090
"#]],
10911091
);
10921092
}
1093+
1094+
#[test]
1095+
fn regression_16529() {
1096+
check(
1097+
r#"
1098+
mod any {
1099+
#[macro_export]
1100+
macro_rules! nameable {
1101+
{
1102+
struct $name:ident[$a:lifetime]
1103+
} => {
1104+
$crate::any::nameable! {
1105+
struct $name[$a]
1106+
a
1107+
}
1108+
};
1109+
{
1110+
struct $name:ident[$a:lifetime]
1111+
a
1112+
} => {};
1113+
}
1114+
pub use nameable;
1115+
1116+
nameable! {
1117+
Name['a]
1118+
}
1119+
}
1120+
"#,
1121+
expect![[r#"
1122+
mod any {
1123+
#[macro_export]
1124+
macro_rules! nameable {
1125+
{
1126+
struct $name:ident[$a:lifetime]
1127+
} => {
1128+
$crate::any::nameable! {
1129+
struct $name[$a]
1130+
a
1131+
}
1132+
};
1133+
{
1134+
struct $name:ident[$a:lifetime]
1135+
a
1136+
} => {};
1137+
}
1138+
pub use nameable;
1139+
1140+
/* error: unexpected token in input */$crate::any::nameable! {
1141+
struct $name[$a]a
1142+
}
1143+
}
1144+
"#]],
1145+
);
1146+
}

crates/mbe/src/expander/transcriber.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,20 @@ impl<S: Span> Bindings<S> {
101101
})))
102102
}
103103
MetaVarKind::Lifetime => {
104-
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
105-
text: SmolStr::new_static("'missing"),
106-
span,
107-
})))
104+
Fragment::Tokens(tt::TokenTree::Subtree(tt::Subtree {
105+
delimiter: tt::Delimiter::invisible_spanned(span),
106+
token_trees: Box::new([
107+
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
108+
char: '\'',
109+
span,
110+
spacing: tt::Spacing::Joint,
111+
})),
112+
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
113+
text: SmolStr::new_static("missing"),
114+
span,
115+
})),
116+
]),
117+
}))
108118
}
109119
MetaVarKind::Literal => {
110120
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {

crates/mbe/src/syntax_bridge.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -700,10 +700,12 @@ impl<S> SynToken<S> {
700700
}
701701

702702
impl<SpanMap, S: std::fmt::Debug> SrcToken<Converter<SpanMap, S>, S> for SynToken<S> {
703-
fn kind(&self, ctx: &Converter<SpanMap, S>) -> SyntaxKind {
703+
fn kind(&self, _ctx: &Converter<SpanMap, S>) -> SyntaxKind {
704704
match self {
705705
SynToken::Ordinary(token) => token.kind(),
706-
SynToken::Punct { .. } => SyntaxKind::from_char(self.to_char(ctx).unwrap()).unwrap(),
706+
SynToken::Punct { token, offset: i } => {
707+
SyntaxKind::from_char(token.text().chars().nth(*i).unwrap()).unwrap()
708+
}
707709
SynToken::Leaf(_) => {
708710
never!();
709711
SyntaxKind::ERROR

crates/tt/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ pub struct Punct<S> {
152152
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
153153
pub enum Spacing {
154154
Alone,
155+
/// Whether the following token is joint to the current one.
155156
Joint,
156157
}
157158

0 commit comments

Comments
 (0)