Skip to content

Commit

Permalink
fix: Fix macro transcriber emitting incorrect lifetime tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Feb 11, 2024
1 parent ddf105b commit c990587
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
54 changes: 54 additions & 0 deletions crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
"#]],
);
}
18 changes: 14 additions & 4 deletions crates/mbe/src/expander/transcriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions crates/mbe/src/syntax_bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions crates/tt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down

0 comments on commit c990587

Please sign in to comment.