From 23a553a30398c856ae7d7179b751024334444296 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 18 Jan 2015 13:13:23 +0200 Subject: [PATCH] Improve the vec![...] macro with UFCS. 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. --- src/libcollections/macros.rs | 16 ++++++++-------- src/test/run-pass/coerce-expect-unsized.rs | 5 +++++ src/test/run-pass/vec-macro-rvalue-scope.rs | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 src/test/run-pass/vec-macro-rvalue-scope.rs diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index c078db7d46f..85aedaeb010 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -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),*]) } diff --git a/src/test/run-pass/coerce-expect-unsized.rs b/src/test/run-pass/coerce-expect-unsized.rs index f590e6e0728..200d3fd6935 100644 --- a/src/test/run-pass/coerce-expect-unsized.rs +++ b/src/test/run-pass/coerce-expect-unsized.rs @@ -33,4 +33,9 @@ pub fn main() { let _: Box<[int]> = Box::new([1, 2, 3]); let _: Box _> = Box::new(|x| (x as u8)); + + let _: Vec _>> = vec![ + Box::new(|x| (x as u8)), + box |x| (x as i16 as u8), + ]; } diff --git a/src/test/run-pass/vec-macro-rvalue-scope.rs b/src/test/run-pass/vec-macro-rvalue-scope.rs new file mode 100644 index 00000000000..68dedfc6a2e --- /dev/null +++ b/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 or the MIT license +// , 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()]); +}