Unnamed repository; edit this file 'description' to name the repository.
Use reserve_exact for pushing to Subtree
GnomedDev 2024-02-05
parent 8011b56 · commit a607e1b
-rw-r--r--crates/hir-expand/src/builtin_fn_macro.rs8
-rw-r--r--crates/tt/src/lib.rs11
2 files changed, 13 insertions, 6 deletions
diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index c2f6a8396d..8d60f58628 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -361,9 +361,7 @@ fn panic_expand(
};
// FIXME(slow): quote! have a way to expand to builder to make this a vec!
- let mut mutable_trees = std::mem::take(&mut call.token_trees).into_vec();
- mutable_trees.push(tt::TokenTree::Subtree(subtree));
- call.token_trees = mutable_trees.into_boxed_slice();
+ call.push(tt::TokenTree::Subtree(subtree));
ExpandResult::ok(call)
}
@@ -395,9 +393,7 @@ fn unreachable_expand(
};
// FIXME(slow): quote! have a way to expand to builder to make this a vec!
- let mut mutable_trees = std::mem::take(&mut call.token_trees).into_vec();
- mutable_trees.push(tt::TokenTree::Subtree(subtree));
- call.token_trees = mutable_trees.into_boxed_slice();
+ call.push(tt::TokenTree::Subtree(subtree));
ExpandResult::ok(call)
}
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs
index 462cae6de3..855459dc85 100644
--- a/crates/tt/src/lib.rs
+++ b/crates/tt/src/lib.rs
@@ -77,6 +77,17 @@ impl<S: Span> Subtree<S> {
Subtree { delimiter: Delimiter::invisible_delim_spanned(span), token_trees: Box::new([]) }
}
+ /// This is slow, and should be avoided, as it will always reallocate!
+ pub fn push(&mut self, subtree: TokenTree<S>) {
+ let mut mutable_trees = std::mem::take(&mut self.token_trees).into_vec();
+
+ // Reserve exactly space for one element, to avoid `into_boxed_slice` having to reallocate again.
+ mutable_trees.reserve_exact(1);
+ mutable_trees.push(subtree);
+
+ self.token_trees = mutable_trees.into_boxed_slice();
+ }
+
pub fn visit_ids(&mut self, f: &mut impl FnMut(S) -> S) {
self.delimiter.open = f(self.delimiter.open);
self.delimiter.close = f(self.delimiter.close);