diff options
| author | Shoyu Vanilla (Flint) <modulo641@gmail.com> | 2025-09-30 05:06:47 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-30 05:06:47 +0000 |
| commit | 5969470982c20f21eda1238d85f88f7987fa9803 (patch) | |
| tree | 732756c1548bc0f4c955dccd32d59fe93a1fe4ce /src | |
| parent | cd26daab4fcf53bbacbc1843c4abb6d83bc3dc48 (diff) | |
| parent | f4a865fea72cbbd1478cada7af19c1bcf0b9d588 (diff) | |
| download | rust-5969470982c20f21eda1238d85f88f7987fa9803.tar.gz rust-5969470982c20f21eda1238d85f88f7987fa9803.zip | |
Merge pull request #20745 from Oblarg/fix-negative-int-literals-in-macro-by-example
Fix negative integer literals in const generics in declarative macro context
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/hover/tests.rs | 42 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs | 14 |
2 files changed, 55 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 1ea11a215f8..8bc0b3f6ab3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -4797,6 +4797,48 @@ fn main() { } #[test] +fn const_generic_negative_literal_macro_expansion() { + // Test that negative literals work correctly in const generics + // when used through macro expansion. This ensures the transcriber + // doesn't wrap negative literals in parentheses, which would create + // invalid syntax like Foo::<(-1)> instead of Foo::<-1>. + check( + r#" +struct Foo<const I: i16> { + pub value: i16, +} + +impl<const I: i16> Foo<I> { + pub fn new(value: i16) -> Self { + Self { value } + } +} + +macro_rules! create_foo { + ($val:expr) => { + Foo::<$val>::new($val) + }; +} + +fn main() { + let v$0alue = create_foo!(-1); +} +"#, + expect![[r#" + *value* + + ```rust + let value: Foo<-1> + ``` + + --- + + size = 2, align = 2, no Drop + "#]], + ); +} + +#[test] fn hover_self_param_shows_type() { check( r#" diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 2c046df10f5..3e4ab8bdc1d 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -401,7 +401,19 @@ fn expand_var( let sub = sub.strip_invisible(); let mut span = id; marker(&mut span); - let wrap_in_parens = !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) + + // Check if this is a simple negative literal (MINUS + LITERAL) + // that should not be wrapped in parentheses + let is_negative_literal = matches!( + sub.flat_tokens(), + [ + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), + tt::TokenTree::Leaf(tt::Leaf::Literal(_)) + ] + ); + + let wrap_in_parens = !is_negative_literal + && !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) && sub.try_into_subtree().is_none_or(|it| { it.top_subtree().delimiter.kind == tt::DelimiterKind::Invisible }); |
