Skip to content

Commit 944bd2c

Browse files
Merge #3559
3559: Implement builtin assert! macro r=matklad a=edwin0cheng This PR add a dummy implementation for `assert!` macro, which mainly make `hover` and `goto-def` works on arguments inside it. Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
2 parents b08f26c + 8f7703b commit 944bd2c

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

crates/ra_hir_expand/src/builtin_macro.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ register_builtin! {
8888
(compile_error, CompileError) => compile_error_expand,
8989
(file, File) => file_expand,
9090
(line, Line) => line_expand,
91+
(assert, Assert) => assert_expand,
9192
(stringify, Stringify) => stringify_expand,
9293
(format_args, FormatArgs) => format_args_expand,
9394
// format_args_nl only differs in that it adds a newline in the end,
@@ -151,6 +152,45 @@ fn column_expand(
151152
Ok(expanded)
152153
}
153154

155+
fn assert_expand(
156+
_db: &dyn AstDatabase,
157+
_id: LazyMacroId,
158+
tt: &tt::Subtree,
159+
) -> Result<tt::Subtree, mbe::ExpandError> {
160+
// A hacky implementation for goto def and hover
161+
// We expand `assert!(cond, arg1, arg2)` to
162+
// ```
163+
// {(cond, &(arg1), &(arg2));}
164+
// ```,
165+
// which is wrong but useful.
166+
167+
let mut args = Vec::new();
168+
let mut current = Vec::new();
169+
for tt in tt.token_trees.iter().cloned() {
170+
match tt {
171+
tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
172+
args.push(current);
173+
current = Vec::new();
174+
}
175+
_ => {
176+
current.push(tt);
177+
}
178+
}
179+
}
180+
if !current.is_empty() {
181+
args.push(current);
182+
}
183+
184+
let arg_tts = args.into_iter().flat_map(|arg| {
185+
quote! { &(##arg), }
186+
}.token_trees).collect::<Vec<_>>();
187+
188+
let expanded = quote! {
189+
{ { (##arg_tts); } }
190+
};
191+
Ok(expanded)
192+
}
193+
154194
fn file_expand(
155195
_db: &dyn AstDatabase,
156196
_id: LazyMacroId,
@@ -493,6 +533,22 @@ mod tests {
493533
assert_eq!(expanded, "\"\"");
494534
}
495535

536+
#[test]
537+
fn test_assert_expand() {
538+
let expanded = expand_builtin_macro(
539+
r#"
540+
#[rustc_builtin_macro]
541+
macro_rules! assert {
542+
($cond:expr) => ({ /* compiler built-in */ });
543+
($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ })
544+
}
545+
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
546+
"#,
547+
);
548+
549+
assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}");
550+
}
551+
496552
#[test]
497553
fn test_compile_error_expand() {
498554
let expanded = expand_builtin_macro(

crates/ra_hir_expand/src/name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ pub mod known {
172172
column,
173173
compile_error,
174174
line,
175+
assert,
175176
stringify,
176177
concat,
177178
include,

crates/ra_hir_expand/src/quote.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ macro_rules! __quote {
9999
( & ) => {$crate::__quote!(@PUNCT '&')};
100100
( , ) => {$crate::__quote!(@PUNCT ',')};
101101
( : ) => {$crate::__quote!(@PUNCT ':')};
102+
( ; ) => {$crate::__quote!(@PUNCT ';')};
102103
( :: ) => {$crate::__quote!(@PUNCT ':', ':')};
103104
( . ) => {$crate::__quote!(@PUNCT '.')};
104105
( < ) => {$crate::__quote!(@PUNCT '<')};

crates/ra_ide/src/hover.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -832,20 +832,35 @@ fn func(foo: i32) { if true { <|>foo; }; }
832832
assert_eq!(hover_on, "\"Tracks\"");
833833
}
834834

835+
#[test]
836+
fn test_hover_through_assert_macro() {
837+
let hover_on = check_hover_result(
838+
r#"
839+
//- /lib.rs
840+
#[rustc_builtin_macro]
841+
macro_rules! assert {}
842+
843+
fn bar() -> bool { true }
844+
fn foo() {
845+
assert!(ba<|>r());
846+
}
847+
"#,
848+
&["fn bar() -> bool"],
849+
);
850+
851+
assert_eq!(hover_on, "bar");
852+
}
853+
835854
#[test]
836855
fn test_hover_through_literal_string_in_builtin_macro() {
837856
check_hover_no_result(
838857
r#"
839858
//- /lib.rs
840859
#[rustc_builtin_macro]
841-
macro_rules! assert {
842-
($cond:expr) => {{ /* compiler built-in */ }};
843-
($cond:expr,) => {{ /* compiler built-in */ }};
844-
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
845-
}
860+
macro_rules! format {}
846861
847862
fn foo() {
848-
assert!("hel<|>lo");
863+
format!("hel<|>lo {}", 0);
849864
}
850865
"#,
851866
);

0 commit comments

Comments
 (0)