-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vec![]
should support the [value, ..repeat]
syntax
#15587
Comments
I don't think rust-lang/rfcs#88 is relevant here; that's relevant to The FWIW, extending macro_rules! vec{
($e:expr, ..$n:expr) => { ::std::vec::Vec::from_elem($n, $e) };
($($e:expr),*) => {{
let mut _temp = ::std::vec::Vec::new();
$(_temp.push($e);)*
_temp
}};
($($e:expr),+,) => (vec!($($e),+));
} |
Oh right, I totally got the dependency on rust-lang/rfcs#88 backwards. I still think it would make sense to mirror the syntax of This should either involve a Whether or not to extend |
Personally, I think supporting Given that, I would support a PR that modifies the definition of |
What about expanding to ($init: expr, .. $n: expr) => {{
let n = $n;
let v = Vec::with_capacity(n);
for _ in range(0, n) { v.push($init) }
v
}} i.e. don't require |
@huonw That's inconsistent with array literals. I submitted a PR a while back as #14272 (closed due to inactivity) that added an Note that with your version the following code: let x = vec![{println!("wat"); 3u}, ..5]; would print "wat" 5 times, but the equivalent array expression only prints "wat" once. |
FWIW, if you want that expression-duplicating behavior with |
Yeah, if we want to emulate the |
After #17920 introduced Today, you'd expect {
use std::slice::BoxedSlice;
let xs: ::std::boxed::Box<[_]> = box() [0u, ..16];
xs.into_vec()
} Except that it doesn't because the macro definition expects To make this work, we'll have to change Anyhow, such change probably merits an RFC? |
@japaric: I don't think it needs an RFC. The syntax is defined as part of the core language for fixed-size arrays and |
I correct myself, this can be done using macros by example. This appears to work: #![feature(macro_rules)]
macro_rules! my_vec {
($value:expr, ..$repeat:expr) => ({
use std::slice::BoxedSlice;
let xs: ::std::boxed::Box<[_]> = box() [$value, ..$repeat];
xs.into_vec()
});
($($x:expr),*) => ({
use std::slice::BoxedSlice;
let xs: ::std::boxed::Box<[_]> = box() [$($x),*];
xs.into_vec()
});
}
fn main() {
println!("{}", my_vec![0u, ..16]);
println!("{}", my_vec![0u, 1]);
} Prints:
(I would send a PR, but I'm on my way out) |
It would be nicer if it could just pass through all of the tokens opaquely. I don't know how to do that or if it's actually possible. |
Is there any advantage of doing it that way? I think the macro definition above covers all the initialization patterns we currently have. (modulo trailing comma, but that's easy to add)
I'll be working with syntax extensions later today, I'll check whether this is feasible or not, and report it here. |
It's certainly doable, here's an out of tree implementation. I'll reproduce the important part of the README here for posteriority:
{
use std::slice::BoxedSlice;
use std::boxed::HEAP;
let xs = box (HEAP) [$SOMETHING];
xs.into_vec()
} Both Do let me know if I should send a PR with the syntax extension version or with the macro by example version. |
It seems to me that this can be done via the following (the #![feature(macro_rules)]
macro_rules! expr {
($e: expr) => { $e }
}
macro_rules! vec {
($($contents: tt)*) => {
{
use std::slice::BoxedSlice;
use std::boxed::HEAP;
let xs = expr!(box (HEAP) [$($contents)*]);
xs.into_vec()
}
}
}
fn main() {
println!("{}", vec![1u, 2, 3]);
println!("{}", vec![1u, .. 10]);
} |
If it can be done with just |
+1 to the syntax addition let x = vec![0u8,..1024*1024]; |
Fix autoimport does nothing when importing trait that is as _ imports Potentially fixes rust-lang#15128 There are two cases of imports: 1. With simple path 2. With use tree list (or say complex path). On deeper inspection, the [`recursive_merge`](https://github.com/rust-lang/rust-analyzer/blob/994df3d6a31d39f11600f30a6df0b744b13937c1/crates/ide-db/src/imports/merge_imports.rs#L87) function (called by [`try_merge_trees_mut`)](https://github.com/rust-lang/rust-analyzer/blob/994df3d6a31d39f11600f30a6df0b744b13937c1/crates/ide-db/src/imports/merge_imports.rs#L69) is meaningful only in the case of complex path (i.e when the UseTree contains a UseTreeList). The [`recursive_merge`](https://github.com/rust-lang/rust-analyzer/blob/994df3d6a31d39f11600f30a6df0b744b13937c1/crates/ide-db/src/imports/merge_imports.rs#L87) function has [match with `Ok` arm](https://github.com/rust-lang/rust-analyzer/blob/994df3d6a31d39f11600f30a6df0b744b13937c1/crates/ide-db/src/imports/merge_imports.rs#L106), that is only executed when both LHS and RHS has `PathSegment` with same `NameRef`. The removal of underscore is implemented in this arm in the case of complex path. For simple paths, the underscore is removed by checking if both LHS and RHS are simple paths and if their `Path` is same (the check is done [here](https://github.com/rust-lang/rust-analyzer/blob/994df3d6a31d39f11600f30a6df0b744b13937c1/crates/ide-db/src/imports/merge_imports.rs#L74)) and remove the underscore if one is found (I made an assumption here that RHS will always be what rust-analyzer suggests to import, because at this point I'm not sure how to remove underscore with help of `ted::replace`).
Rust now supports
[]
in macro invocations, with a driving use case being able to writevec![0, 0, 0]
as analogy to the fixed sized vector syntax[0, 0, 0]
.However, there is no analogy to the
[0, ..n]
repeat syntax for it:vec![0, ..n]
does not work.For it to be added,vec!
would either need to become a procedural macro, or something like rust-lang/rfcs#88 needs to be implemented.The text was updated successfully, but these errors were encountered: