Merge #11549
11549: feat: support concat_bytes r=jonas-schievink a=ihciah Support `concat_bytes`. Solve #11544. Co-authored-by: ihciah <ihciah@gmail.com>
This commit is contained in:
commit
c8257488c1
@ -313,6 +313,24 @@ fn main() { "foor0bar\nfalse"; }
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concat_bytes_expand() {
|
||||
check(
|
||||
r##"
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! concat_bytes {}
|
||||
|
||||
fn main() { concat_bytes!(b'A', b"BC", [68, b'E', 70]); }
|
||||
"##,
|
||||
expect![[r##"
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! concat_bytes {}
|
||||
|
||||
fn main() { [b'A', 66, 67, 68, b'E', 70]; }
|
||||
"##]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concat_with_captured_expr() {
|
||||
check(
|
||||
|
@ -121,6 +121,7 @@ register_builtin! {
|
||||
(compile_error, CompileError) => compile_error_expand,
|
||||
(concat, Concat) => concat_expand,
|
||||
(concat_idents, ConcatIdents) => concat_idents_expand,
|
||||
(concat_bytes, ConcatBytes) => concat_bytes_expand,
|
||||
(include, Include) => include_expand,
|
||||
(include_bytes, IncludeBytes) => include_bytes_expand,
|
||||
(include_str, IncludeStr) => include_str_expand,
|
||||
@ -359,6 +360,12 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
|
||||
token.value().map(|it| it.into_owned())
|
||||
}
|
||||
|
||||
fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
|
||||
let lit = ast::make::tokens::literal(&lit.to_string());
|
||||
let token = ast::ByteString::cast(lit)?;
|
||||
token.value().map(|it| it.into_owned())
|
||||
}
|
||||
|
||||
fn compile_error_expand(
|
||||
_db: &dyn AstDatabase,
|
||||
_id: MacroCallId,
|
||||
@ -422,6 +429,74 @@ fn concat_expand(
|
||||
ExpandResult { value: ExpandedEager::new(quote!(#text)), err }
|
||||
}
|
||||
|
||||
fn concat_bytes_expand(
|
||||
_db: &dyn AstDatabase,
|
||||
_arg_id: MacroCallId,
|
||||
tt: &tt::Subtree,
|
||||
) -> ExpandResult<ExpandedEager> {
|
||||
let mut bytes = Vec::new();
|
||||
let mut err = None;
|
||||
for (i, t) in tt.token_trees.iter().enumerate() {
|
||||
match t {
|
||||
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
|
||||
let token = ast::make::tokens::literal(&lit.to_string());
|
||||
match token.kind() {
|
||||
syntax::SyntaxKind::BYTE => bytes.push(token.text().to_string()),
|
||||
syntax::SyntaxKind::BYTE_STRING => {
|
||||
let components = unquote_byte_string(lit).unwrap_or_else(|| Vec::new());
|
||||
components.into_iter().for_each(|x| bytes.push(x.to_string()));
|
||||
}
|
||||
_ => {
|
||||
err.get_or_insert(mbe::ExpandError::UnexpectedToken.into());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
|
||||
tt::TokenTree::Subtree(tree)
|
||||
if tree.delimiter_kind() == Some(tt::DelimiterKind::Bracket) =>
|
||||
{
|
||||
if let Err(e) = concat_bytes_expand_subtree(tree, &mut bytes) {
|
||||
err.get_or_insert(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
err.get_or_insert(mbe::ExpandError::UnexpectedToken.into());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let ident = tt::Ident { text: bytes.join(", ").into(), id: tt::TokenId::unspecified() };
|
||||
ExpandResult { value: ExpandedEager::new(quote!([#ident])), err }
|
||||
}
|
||||
|
||||
fn concat_bytes_expand_subtree(
|
||||
tree: &tt::Subtree,
|
||||
bytes: &mut Vec<String>,
|
||||
) -> Result<(), ExpandError> {
|
||||
for (ti, tt) in tree.token_trees.iter().enumerate() {
|
||||
match tt {
|
||||
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
|
||||
let lit = ast::make::tokens::literal(&lit.to_string());
|
||||
match lit.kind() {
|
||||
syntax::SyntaxKind::BYTE | syntax::SyntaxKind::INT_NUMBER => {
|
||||
bytes.push(lit.text().to_string())
|
||||
}
|
||||
_ => {
|
||||
return Err(mbe::ExpandError::UnexpectedToken.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if ti % 2 == 1 && punct.char == ',' => (),
|
||||
_ => {
|
||||
return Err(mbe::ExpandError::UnexpectedToken.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn concat_idents_expand(
|
||||
_db: &dyn AstDatabase,
|
||||
_arg_id: MacroCallId,
|
||||
|
@ -233,6 +233,7 @@ pub mod known {
|
||||
column,
|
||||
compile_error,
|
||||
concat_idents,
|
||||
concat_bytes,
|
||||
concat,
|
||||
const_format_args,
|
||||
core_panic,
|
||||
|
Loading…
x
Reference in New Issue
Block a user