Skip to content

Commit 12fe0e4

Browse files
Merge #10397
10397: fix: fix format string highlighting for `panic!` and `assert!` r=jonas-schievink a=jonas-schievink part of #10394 bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 161a5e8 + 375a0ff commit 12fe0e4

File tree

4 files changed

+91
-18
lines changed

4 files changed

+91
-18
lines changed

crates/hir_expand/src/builtin_macro.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -180,22 +180,29 @@ fn assert_expand(
180180
_id: MacroCallId,
181181
tt: &tt::Subtree,
182182
) -> ExpandResult<tt::Subtree> {
183-
// A hacky implementation for goto def and hover
184-
// We expand `assert!(cond, arg1, arg2)` to
185-
// ```
186-
// {(cond, &(arg1), &(arg2));}
187-
// ```,
188-
// which is wrong but useful.
189-
183+
let krate = tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() };
190184
let args = parse_exprs_with_sep(tt, ',');
191-
192-
let arg_tts = args.into_iter().flat_map(|arg| {
193-
quote! { &(#arg), }
194-
}.token_trees);
195-
196-
let expanded = quote! {
197-
{ { (##arg_tts); } }
185+
let expanded = match &*args {
186+
[cond, panic_args @ ..] => {
187+
let comma = tt::Subtree {
188+
delimiter: None,
189+
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
190+
char: ',',
191+
spacing: tt::Spacing::Alone,
192+
id: tt::TokenId::unspecified(),
193+
}))],
194+
};
195+
let cond = cond.clone();
196+
let panic_args = itertools::Itertools::intersperse(panic_args.iter().cloned(), comma);
197+
quote! {{
198+
if !#cond {
199+
#krate::panic!(##panic_args);
200+
}
201+
}}
202+
}
203+
[] => quote! {{}},
198204
};
205+
199206
ExpandResult::ok(expanded)
200207
}
201208

@@ -731,7 +738,7 @@ mod tests {
731738
}
732739
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
733740
"#,
734-
expect![["{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}"]],
741+
expect![[r#"{if!true{$crate::panic!("{} {:?}",arg1(a,b,c),arg2);}}"#]],
735742
);
736743
}
737744

crates/ide/src/syntax_highlighting/format.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ fn is_format_string(string: &ast::String) -> Option<()> {
3131
let parent = string.syntax().parent()?;
3232

3333
let name = parent.parent().and_then(ast::MacroCall::cast)?.path()?.segment()?.name_ref()?;
34-
if !matches!(name.text().as_str(), "format_args" | "format_args_nl") {
34+
if !matches!(
35+
name.text().as_str(),
36+
"format_args" | "format_args_nl" | "const_format_args" | "panic_2015" | "panic_2021"
37+
) {
3538
return None;
3639
}
3740

3841
let first_literal = parent
3942
.children_with_tokens()
40-
.filter_map(|it| it.as_token().cloned().and_then(ast::String::cast))
41-
.next()?;
43+
.find_map(|it| it.as_token().cloned().and_then(ast::String::cast))?;
4244
if &first_literal != string {
4345
return None;
4446
}

crates/ide/src/syntax_highlighting/test_data/highlight_strings.html

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,34 @@
5151
<span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>args<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">{</span> <span class="comment">/* compiler built-in */</span> <span class="brace">}</span><span class="brace">}</span><span class="semicolon">;</span>
5252
<span class="brace">}</span>
5353

54+
<span class="keyword">mod</span> <span class="module declaration">panic</span> <span class="brace">{</span>
55+
<span class="keyword">pub</span> <span class="keyword">macro</span> <span class="macro declaration">panic_2015</span> <span class="brace">{</span>
56+
<span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
57+
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="string_literal">"explicit panic"</span><span class="parenthesis">)</span>
58+
<span class="parenthesis">)</span><span class="comma">,</span>
59+
<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>literal <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
60+
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
61+
<span class="parenthesis">)</span><span class="comma">,</span>
62+
<span class="comment">// Use `panic_str` instead of `panic_display::&lt;&str&gt;` for non_fmt_panic lint.</span>
63+
<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
64+
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_str<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
65+
<span class="parenthesis">)</span><span class="comma">,</span>
66+
<span class="comment">// Special-case the single-argument case for const_panic.</span>
67+
<span class="parenthesis">(</span><span class="string_literal">"{}"</span><span class="comma">,</span> <span class="punctuation">$</span>arg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
68+
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="operator">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
69+
<span class="parenthesis">)</span><span class="comma">,</span>
70+
<span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
71+
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_fmt<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>const_format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
72+
<span class="parenthesis">)</span><span class="comma">,</span>
73+
<span class="brace">}</span>
74+
<span class="brace">}</span>
75+
76+
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="parenthesis attribute">(</span><span class="none attribute">std_panic</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
77+
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">macro_export</span><span class="attribute attribute">]</span>
78+
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">panic</span> <span class="brace">{</span><span class="brace">}</span>
79+
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
80+
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">assert</span> <span class="brace">{</span><span class="brace">}</span>
81+
5482
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
5583
<span class="comment">// from https://doc.rust-lang.org/std/fmt/index.html</span>
5684
<span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "Hello"</span>
@@ -100,4 +128,8 @@
100128
<span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> ничоси <span class="operator">=</span> <span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
101129

102130
<span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> "</span><span class="comma">,</span> thingy<span class="comma">,</span> n2<span class="parenthesis">)</span><span class="semicolon">;</span>
131+
<span class="macro">panic!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">0</span><span class="parenthesis">)</span><span class="semicolon">;</span>
132+
<span class="macro">panic!</span><span class="parenthesis">(</span><span class="string_literal">"more </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
133+
<span class="macro">assert!</span><span class="parenthesis">(</span><span class="bool_literal">true</span><span class="comma">,</span> <span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
134+
<span class="macro">assert!</span><span class="parenthesis">(</span><span class="bool_literal">true</span><span class="comma">,</span> <span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> asdasd"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
103135
<span class="brace">}</span></code></pre>

crates/ide/src/syntax_highlighting/tests.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,34 @@ macro_rules! format_args_nl {
446446
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
447447
}
448448
449+
mod panic {
450+
pub macro panic_2015 {
451+
() => (
452+
$crate::panicking::panic("explicit panic")
453+
),
454+
($msg:literal $(,)?) => (
455+
$crate::panicking::panic($msg)
456+
),
457+
// Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
458+
($msg:expr $(,)?) => (
459+
$crate::panicking::panic_str($msg)
460+
),
461+
// Special-case the single-argument case for const_panic.
462+
("{}", $arg:expr $(,)?) => (
463+
$crate::panicking::panic_display(&$arg)
464+
),
465+
($fmt:expr, $($arg:tt)+) => (
466+
$crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
467+
),
468+
}
469+
}
470+
471+
#[rustc_builtin_macro(std_panic)]
472+
#[macro_export]
473+
macro_rules! panic {}
474+
#[rustc_builtin_macro]
475+
macro_rules! assert {}
476+
449477
fn main() {
450478
// from https://doc.rust-lang.org/std/fmt/index.html
451479
println!("Hello"); // => "Hello"
@@ -495,6 +523,10 @@ fn main() {
495523
println!("{ничоси}", ничоси = 92);
496524
497525
println!("{:x?} {} ", thingy, n2);
526+
panic!("{}", 0);
527+
panic!("more {}", 1);
528+
assert!(true, "{}", 1);
529+
assert!(true, "{} asdasd", 1);
498530
}"#
499531
.trim(),
500532
expect_file!["./test_data/highlight_strings.html"],

0 commit comments

Comments
 (0)