Skip to content

Commit

Permalink
Improve the vec![...] macro with UFCS.
Browse files Browse the repository at this point in the history
There are two limitations to the macro that this addresses:
1. the expected type is not propagated, coercions don't trigger
2. references inside element expressions don't outlive the `Vec`

Both of these limitations are caused by the block in the
macro expansion, previously needed to trigger a coercion
from `Box<[T; N]>` to `Box<[T]>`, now possible with UFCS.
  • Loading branch information
eddyb committed Jan 18, 2015
1 parent a833337 commit 23a553a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/libcollections/macros.rs
Expand Up @@ -12,13 +12,13 @@
#[macro_export]
#[stable]
macro_rules! vec {
($x:expr; $y:expr) => ({
let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$x; $y]);
$crate::slice::SliceExt::into_vec(xs)
});
($($x:expr),*) => ({
let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$($x),*]);
$crate::slice::SliceExt::into_vec(xs)
});
($x:expr; $y:expr) => (
<[_] as $crate::slice::SliceExt>::into_vec(
$crate::boxed::Box::new([$x; $y]))
);
($($x:expr),*) => (
<[_] as $crate::slice::SliceExt>::into_vec(
$crate::boxed::Box::new([$($x),*]))
);
($($x:expr,)*) => (vec![$($x),*])
}
5 changes: 5 additions & 0 deletions src/test/run-pass/coerce-expect-unsized.rs
Expand Up @@ -33,4 +33,9 @@ pub fn main() {

let _: Box<[int]> = Box::new([1, 2, 3]);
let _: Box<Fn(int) -> _> = Box::new(|x| (x as u8));

let _: Vec<Box<Fn(int) -> _>> = vec![
Box::new(|x| (x as u8)),
box |x| (x as i16 as u8),
];
}
18 changes: 18 additions & 0 deletions src/test/run-pass/vec-macro-rvalue-scope.rs
@@ -0,0 +1,18 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn one() -> i32 { 1 }

// Make sure the vec![...] macro doesn't introduce hidden rvalue
// scopes (such as blocks) around the element expressions.
pub fn main() {
assert_eq!(vec![&one(), &one(), &2], vec![&1, &1, &(one()+one())]);
assert_eq!(vec![&one(); 2], vec![&1, &one()]);
}

0 comments on commit 23a553a

Please sign in to comment.