Implement dummy assert macro

This commit is contained in:
Edwin Cheng 2020-03-11 23:08:12 +08:00
parent bddf6b5266
commit 759bcea96d
4 changed files with 60 additions and 6 deletions

View file

@ -88,6 +88,7 @@ register_builtin! {
(compile_error, CompileError) => compile_error_expand, (compile_error, CompileError) => compile_error_expand,
(file, File) => file_expand, (file, File) => file_expand,
(line, Line) => line_expand, (line, Line) => line_expand,
(assert, Assert) => assert_expand,
(stringify, Stringify) => stringify_expand, (stringify, Stringify) => stringify_expand,
(format_args, FormatArgs) => format_args_expand, (format_args, FormatArgs) => format_args_expand,
// format_args_nl only differs in that it adds a newline in the end, // format_args_nl only differs in that it adds a newline in the end,
@ -151,6 +152,45 @@ fn column_expand(
Ok(expanded) Ok(expanded)
} }
fn assert_expand(
_db: &dyn AstDatabase,
_id: LazyMacroId,
tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
// A hacky implementation for goto def and hover
// We expand `assert!("", arg1, arg2)` to
// ```
// {(&(arg1), &(arg2));}
// ```,
// which is wrong but useful.
let mut args = Vec::new();
let mut current = Vec::new();
for tt in tt.token_trees.iter().cloned() {
match tt {
tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
args.push(current);
current = Vec::new();
}
_ => {
current.push(tt);
}
}
}
if !current.is_empty() {
args.push(current);
}
let arg_tts = args.into_iter().flat_map(|arg| {
quote! { &(##arg), }
}.token_trees).collect::<Vec<_>>();
let expanded = quote! {
{ { (##arg_tts); } }
};
Ok(expanded)
}
fn file_expand( fn file_expand(
_db: &dyn AstDatabase, _db: &dyn AstDatabase,
_id: LazyMacroId, _id: LazyMacroId,
@ -493,6 +533,22 @@ mod tests {
assert_eq!(expanded, "\"\""); assert_eq!(expanded, "\"\"");
} }
#[test]
fn test_assert_expand() {
let expanded = expand_builtin_macro(
r#"
#[rustc_builtin_macro]
macro_rules! assert {
($fmt:expr) => ({ /* compiler built-in */ });
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
}
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
"#,
);
assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}");
}
#[test] #[test]
fn test_compile_error_expand() { fn test_compile_error_expand() {
let expanded = expand_builtin_macro( let expanded = expand_builtin_macro(

View file

@ -172,6 +172,7 @@ pub mod known {
column, column,
compile_error, compile_error,
line, line,
assert,
stringify, stringify,
concat, concat,
include, include,

View file

@ -99,6 +99,7 @@ macro_rules! __quote {
( & ) => {$crate::__quote!(@PUNCT '&')}; ( & ) => {$crate::__quote!(@PUNCT '&')};
( , ) => {$crate::__quote!(@PUNCT ',')}; ( , ) => {$crate::__quote!(@PUNCT ',')};
( : ) => {$crate::__quote!(@PUNCT ':')}; ( : ) => {$crate::__quote!(@PUNCT ':')};
( ; ) => {$crate::__quote!(@PUNCT ';')};
( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; ( :: ) => {$crate::__quote!(@PUNCT ':', ':')};
( . ) => {$crate::__quote!(@PUNCT '.')}; ( . ) => {$crate::__quote!(@PUNCT '.')};
( < ) => {$crate::__quote!(@PUNCT '<')}; ( < ) => {$crate::__quote!(@PUNCT '<')};

View file

@ -838,14 +838,10 @@ fn func(foo: i32) { if true { <|>foo; }; }
r#" r#"
//- /lib.rs //- /lib.rs
#[rustc_builtin_macro] #[rustc_builtin_macro]
macro_rules! assert { macro_rules! format {}
($cond:expr) => {{ /* compiler built-in */ }};
($cond:expr,) => {{ /* compiler built-in */ }};
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
}
fn foo() { fn foo() {
assert!("hel<|>lo"); format!("hel<|>lo {}", 0);
} }
"#, "#,
); );