mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
Implement format_args more properly
This commit is contained in:
parent
3a5aa03e66
commit
eae425b10f
1 changed files with 43 additions and 4 deletions
|
@ -207,12 +207,34 @@ fn compile_error_expand(
|
||||||
fn format_args_expand(
|
fn format_args_expand(
|
||||||
_db: &dyn AstDatabase,
|
_db: &dyn AstDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
) -> Result<tt::Subtree, mbe::ExpandError> {
|
) -> Result<tt::Subtree, mbe::ExpandError> {
|
||||||
// FIXME this is just a stub to make format macros type-check without mismatches
|
// We expand `format_args!("", arg1, arg2)` to
|
||||||
// We should make this at least insert the arguments, so that go to def etc. work within format macros
|
// `std::fmt::Arguments::new_v1(&[], &[&arg1, &arg2])`,
|
||||||
|
// which is still not really correct, but close enough for now
|
||||||
|
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(tt::Subtree { delimiter: tt::Delimiter::None, token_trees: current });
|
||||||
|
current = Vec::new();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
current.push(tt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !current.is_empty() {
|
||||||
|
args.push(tt::Subtree { delimiter: tt::Delimiter::None, token_trees: current });
|
||||||
|
}
|
||||||
|
if args.is_empty() {
|
||||||
|
return Err(mbe::ExpandError::NoMatchingRule);
|
||||||
|
}
|
||||||
|
let _format_string = args.remove(0);
|
||||||
|
let arg_tts = args.into_iter().flat_map(|arg| (quote! { & #arg , }).token_trees);
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
std::fmt::Arguments::new_v1(&[], &[])
|
std::fmt::Arguments::new_v1(&[], &[##arg_tts])
|
||||||
};
|
};
|
||||||
Ok(expanded)
|
Ok(expanded)
|
||||||
}
|
}
|
||||||
|
@ -324,4 +346,21 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(expanded, r#"loop{"error!"}"#);
|
assert_eq!(expanded, r#"loop{"error!"}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_format_args_expand() {
|
||||||
|
let expanded = expand_builtin_macro(
|
||||||
|
r#"
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! format_args {
|
||||||
|
($fmt:expr) => ({ /* compiler built-in */ });
|
||||||
|
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||||
|
}
|
||||||
|
format_args!("{} {:?}", arg1(a, b, c), arg2);
|
||||||
|
"#,
|
||||||
|
BuiltinFnLikeExpander::FormatArgs,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(expanded, r#"std::fmt::Arguments::new_v1(&[] ,&[&arg1(a,b,c),&arg2,])"#);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue