From 2f51f671c46efe91e803de8ab02fc5d379c089a8 Mon Sep 17 00:00:00 2001 From: David Alber Date: Wed, 22 Nov 2017 20:44:05 -0800 Subject: [PATCH 1/7] Adding `eprint*!` to the list of macros in the `format!` family --- src/liballoc/fmt.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 7148a1143fd46..a092bfb3b0a8a 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -236,6 +236,8 @@ //! writeln! // same as write but appends a newline //! print! // the format string is printed to the standard output //! println! // same as print but appends a newline +//! eprint! // the format string is printed to the standard error +//! eprintln! // same as eprint but appends a newline //! format_args! // described below. //! ``` //! @@ -264,6 +266,11 @@ //! print!("Hello {}!", "world"); //! println!("I have a newline {}", "character at the end"); //! ``` +//! ### `eprint!` +//! +//! The [`eprint!`] and [`eprintln!`] macros are identical to +//! [`print!`] and [`println!`], respectively, except they emit their +//! output to stderr. //! //! ### `format_args!` //! @@ -490,7 +497,10 @@ //! [`writeln!`]: ../../std/macro.writeln.html //! [`write_fmt`]: ../../std/io/trait.Write.html#method.write_fmt //! [`std::io::Write`]: ../../std/io/trait.Write.html +//! [`print!`]: ../../std/macro.print.html //! [`println!`]: ../../std/macro.println.html +//! [`eprint!`]: ../../std/macro.eprint.html +//! [`eprintln!`]: ../../std/macro.eprintln.html //! [`write!`]: ../../std/macro.write.html //! [`format_args!`]: ../../std/macro.format_args.html //! [`fmt::Arguments`]: struct.Arguments.html From 377aaeae2030e3d08a21bb6071c2876a1f0ee776 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Nov 2017 21:48:22 +0100 Subject: [PATCH 2/7] Remove invalid doc link --- src/libstd/io/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index ff952122d3de9..92f1d450130dc 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -444,7 +444,7 @@ fn read_to_end(r: &mut R, buf: &mut Vec) -> Result /// # } /// ``` /// -/// Read from `&str` because [`&[u8]`] implements [`Read`]: +/// Read from `&str` because [`&[u8]`] implements `Read`: /// /// ``` /// # use std::io; @@ -468,7 +468,6 @@ fn read_to_end(r: &mut R, buf: &mut Vec) -> Result /// [`BufRead`]: trait.BufRead.html /// [`BufReader`]: struct.BufReader.html /// [`&[u8]`]: primitive.slice.html -/// #[stable(feature = "rust1", since = "1.0.0")] #[doc(spotlight)] pub trait Read { From a1ad729a81cc29ee38b6a11c3bd2028c73fef10c Mon Sep 17 00:00:00 2001 From: Lucas Morales Date: Fri, 24 Nov 2017 03:04:57 -0600 Subject: [PATCH 3/7] core::marker fix typo --- src/libcore/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 0a8127f4ce4fe..0b0724b7a26ff 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -314,7 +314,7 @@ pub trait Copy : Clone { /// /// For cases when one does need thread-safe interior mutability, /// Rust provides [atomic data types], as well as explicit locking via -/// [`sync::Mutex`][mutex] and [`sync::RWLock`][rwlock]. These types +/// [`sync::Mutex`][mutex] and [`sync::RwLock`][rwlock]. These types /// ensure that any mutation cannot cause data races, hence the types /// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe /// analogue of [`Rc`][rc]. From 513910e321eac3eafabc59a0d8745f50c7ea3979 Mon Sep 17 00:00:00 2001 From: Basile Desloges Date: Sat, 25 Nov 2017 11:38:10 +0100 Subject: [PATCH 4/7] Update MSVC compilation instructions regarding path length on Windows --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4fc003036e9b3..589aa1afe35ec 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,9 @@ CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64. python x.py build ``` +If you are seeing build failure when compiling `rustc_binaryen`, make sure the path +length of the rust folder is not longer than 22 characters. + #### Specifying an ABI [specifying-an-abi]: #specifying-an-abi From 0854bfbac92b0410f009b70845d6289894c91d60 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 25 Nov 2017 17:33:47 +0100 Subject: [PATCH 5/7] Derive Debug for LangItem --- src/librustc/middle/lang_items.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 679c4f17a6c03..b57f58e0d2ef4 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -40,7 +40,7 @@ macro_rules! language_item_table { enum_from_u32! { - #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum LangItem { $($variant,)* } From 85e642114b8a6943b7480e363be99a3b08e1b634 Mon Sep 17 00:00:00 2001 From: Murarth Date: Tue, 14 Nov 2017 12:31:07 -0700 Subject: [PATCH 6/7] Implement `Rc`/`Arc` conversions for string-like types Provides the following conversion implementations: * `From<`{`CString`,`&CStr`}`>` for {`Arc`,`Rc`}`` * `From<`{`OsString`,`&OsStr`}`>` for {`Arc`,`Rc`}`` * `From<`{`PathBuf`,`&Path`}`>` for {`Arc`,`Rc`}`` Closes #45008 --- src/libstd/ffi/c_str.rs | 57 +++++++++++++++++++++++++++++++ src/libstd/ffi/os_str.rs | 58 ++++++++++++++++++++++++++++++++ src/libstd/path.rs | 58 ++++++++++++++++++++++++++++++++ src/libstd/sys/redox/os_str.rs | 24 +++++++++++++ src/libstd/sys/unix/os_str.rs | 24 +++++++++++++ src/libstd/sys/windows/os_str.rs | 24 +++++++++++++ src/libstd/sys_common/wtf8.rs | 14 ++++++++ 7 files changed, 259 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 1aa47f066b69f..a2022a2eeb23c 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -19,8 +19,10 @@ use memchr; use ops; use os::raw::c_char; use ptr; +use rc::Rc; use slice; use str::{self, Utf8Error}; +use sync::Arc; use sys; /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the @@ -704,6 +706,42 @@ impl From for Box { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: CString) -> Arc { + let arc: Arc<[u8]> = Arc::from(s.into_inner()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a CStr> for Arc { + #[inline] + fn from(s: &CStr) -> Arc { + let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: CString) -> Rc { + let rc: Rc<[u8]> = Rc::from(s.into_inner()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a CStr> for Rc { + #[inline] + fn from(s: &CStr) -> Rc { + let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } + } +} + #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -1201,6 +1239,8 @@ mod tests { use borrow::Cow::{Borrowed, Owned}; use hash::{Hash, Hasher}; use collections::hash_map::DefaultHasher; + use rc::Rc; + use sync::Arc; #[test] fn c_to_rust() { @@ -1337,4 +1377,21 @@ mod tests { let boxed = >::default(); assert_eq!(boxed.to_bytes_with_nul(), &[0]); } + + #[test] + fn into_rc() { + let orig: &[u8] = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(orig).unwrap(); + let rc: Rc = Rc::from(cstr); + let arc: Arc = Arc::from(cstr); + + assert_eq!(&*rc, cstr); + assert_eq!(&*arc, cstr); + + let rc2: Rc = Rc::from(cstr.to_owned()); + let arc2: Arc = Arc::from(cstr.to_owned()); + + assert_eq!(&*rc2, cstr); + assert_eq!(&*arc2, cstr); + } } diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 8c34660f821b7..cb902461f39fd 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -13,6 +13,8 @@ use fmt; use ops; use cmp; use hash::{Hash, Hasher}; +use rc::Rc; +use sync::Arc; use sys::os_str::{Buf, Slice}; use sys_common::{AsInner, IntoInner, FromInner}; @@ -592,6 +594,42 @@ impl From for Box { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: OsString) -> Arc { + let arc = s.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a OsStr> for Arc { + #[inline] + fn from(s: &OsStr) -> Arc { + let arc = s.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: OsString) -> Rc { + let rc = s.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a OsStr> for Rc { + #[inline] + fn from(s: &OsStr) -> Rc { + let rc = s.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } + } +} + #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -793,6 +831,9 @@ mod tests { use super::*; use sys_common::{AsInner, IntoInner}; + use rc::Rc; + use sync::Arc; + #[test] fn test_os_string_with_capacity() { let os_string = OsString::with_capacity(0); @@ -935,4 +976,21 @@ mod tests { assert_eq!(os_str, os_string); assert!(os_string.capacity() >= 123); } + + #[test] + fn into_rc() { + let orig = "Hello, world!"; + let os_str = OsStr::new(orig); + let rc: Rc = Rc::from(os_str); + let arc: Arc = Arc::from(os_str); + + assert_eq!(&*rc, os_str); + assert_eq!(&*arc, os_str); + + let rc2: Rc = Rc::from(os_str.to_owned()); + let arc2: Arc = Arc::from(os_str.to_owned()); + + assert_eq!(&*rc2, os_str); + assert_eq!(&*arc2, os_str); + } } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 69922470cff4a..26c1d96c3bcf9 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -86,6 +86,8 @@ use hash::{Hash, Hasher}; use io; use iter::{self, FusedIterator}; use ops::{self, Deref}; +use rc::Rc; +use sync::Arc; use ffi::{OsStr, OsString}; @@ -1452,6 +1454,42 @@ impl<'a> From for Cow<'a, Path> { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: PathBuf) -> Arc { + let arc: Arc = Arc::from(s.into_os_string()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a Path> for Arc { + #[inline] + fn from(s: &Path) -> Arc { + let arc: Arc = Arc::from(s.as_os_str()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: PathBuf) -> Rc { + let rc: Rc = Rc::from(s.into_os_string()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a Path> for Rc { + #[inline] + fn from(s: &Path) -> Rc { + let rc: Rc = Rc::from(s.as_os_str()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for Path { type Owned = PathBuf; @@ -2568,6 +2606,9 @@ impl Error for StripPrefixError { mod tests { use super::*; + use rc::Rc; + use sync::Arc; + macro_rules! t( ($path:expr, iter: $iter:expr) => ( { @@ -3970,4 +4011,21 @@ mod tests { assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b"); assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b"); } + + #[test] + fn into_rc() { + let orig = "hello/world"; + let path = Path::new(orig); + let rc: Rc = Rc::from(path); + let arc: Arc = Arc::from(path); + + assert_eq!(&*rc, path); + assert_eq!(&*arc, path); + + let rc2: Rc = Rc::from(path.to_owned()); + let arc2: Arc = Arc::from(path.to_owned()); + + assert_eq!(&*rc2, path); + assert_eq!(&*arc2, path); + } } diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index c54286353a92f..5c40d42fa0a44 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use str; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; use std_unicode::lossy::Utf8Lossy; @@ -123,6 +125,16 @@ impl Buf { let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -156,4 +168,16 @@ impl Slice { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index 777db17e3e164..a27e76a0e3bcc 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use str; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; use std_unicode::lossy::Utf8Lossy; @@ -123,6 +125,16 @@ impl Buf { let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -156,4 +168,16 @@ impl Slice { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 3eb4582718b51..b8d2f7bc53ce7 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use sys_common::wtf8::{Wtf8, Wtf8Buf}; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; #[derive(Clone, Hash)] @@ -115,6 +117,16 @@ impl Buf { let inner: Box = unsafe { mem::transmute(boxed) }; Buf { inner: Wtf8Buf::from_box(inner) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -144,4 +156,16 @@ impl Slice { pub fn empty_box() -> Box { unsafe { mem::transmute(Wtf8::empty_box()) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc = self.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc = self.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index b89a73cd28a09..e212b5006f2d1 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -35,8 +35,10 @@ use hash::{Hash, Hasher}; use iter::FromIterator; use mem; use ops; +use rc::Rc; use slice; use str; +use sync::Arc; use sys_common::AsInner; const UTF8_REPLACEMENT_CHARACTER: &'static str = "\u{FFFD}"; @@ -641,6 +643,18 @@ impl Wtf8 { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.bytes); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Wtf8) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.bytes); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Wtf8) } + } } From 62391c8c862556e22933af2510f4852b63444b41 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 25 Nov 2017 11:59:16 -0800 Subject: [PATCH 7/7] InstCombine Len([_; N]) => const N in MIR --- src/librustc_mir/transform/instcombine.rs | 33 +++++++++++++++++------ src/test/mir-opt/combine_array_len.rs | 33 +++++++++++++++++++++++ 2 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 src/test/mir-opt/combine_array_len.rs diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index b091f2f4b6d78..d66d4b14d693d 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -10,10 +10,10 @@ //! Performs various peephole optimizations. -use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; +use rustc::mir::{Constant, Literal, Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; use rustc::mir::visit::{MutVisitor, Visitor}; -use rustc::ty::TyCtxt; -use rustc::util::nodemap::FxHashSet; +use rustc::ty::{TyCtxt, TypeVariants}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::Idx; use std::mem; use transform::{MirPass, MirSource}; @@ -44,11 +44,11 @@ impl MirPass for InstCombine { } } -pub struct InstCombineVisitor { - optimizations: OptimizationList, +pub struct InstCombineVisitor<'tcx> { + optimizations: OptimizationList<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor { +impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { if self.optimizations.and_stars.remove(&location) { debug!("Replacing `&*`: {:?}", rvalue); @@ -62,6 +62,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor { *rvalue = Rvalue::Use(Operand::Consume(new_lvalue)) } + if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) { + debug!("Replacing `Len([_; N])`: {:?}", rvalue); + *rvalue = Rvalue::Use(Operand::Constant(box constant)); + } + self.super_rvalue(rvalue, location) } } @@ -70,7 +75,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor { struct OptimizationFinder<'b, 'a, 'tcx:'a+'b> { mir: &'b Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - optimizations: OptimizationList, + optimizations: OptimizationList<'tcx>, } impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> { @@ -93,11 +98,23 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> { } } + if let Rvalue::Len(ref lvalue) = *rvalue { + let lvalue_ty = lvalue.ty(&self.mir.local_decls, self.tcx).to_ty(self.tcx); + if let TypeVariants::TyArray(_, len) = lvalue_ty.sty { + let span = self.mir.source_info(location).span; + let ty = self.tcx.types.usize; + let literal = Literal::Value { value: len }; + let constant = Constant { span, ty, literal }; + self.optimizations.arrays_lengths.insert(location, constant); + } + } + self.super_rvalue(rvalue, location) } } #[derive(Default)] -struct OptimizationList { +struct OptimizationList<'tcx> { and_stars: FxHashSet, + arrays_lengths: FxHashMap>, } diff --git a/src/test/mir-opt/combine_array_len.rs b/src/test/mir-opt/combine_array_len.rs new file mode 100644 index 0000000000000..136c3493fa407 --- /dev/null +++ b/src/test/mir-opt/combine_array_len.rs @@ -0,0 +1,33 @@ +// Copyright 2017 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 norm2(x: [f32; 2]) -> f32 { + let a = x[0]; + let b = x[1]; + a*a + b*b +} + +fn main() { + assert_eq!(norm2([3.0, 4.0]), 5.0*5.0); +} + +// END RUST SOURCE + +// START rustc.norm2.InstCombine.before.mir +// _5 = Len(_1); +// ... +// _10 = Len(_1); +// END rustc.norm2.InstCombine.before.mir + +// START rustc.norm2.InstCombine.after.mir +// _5 = const 2usize; +// ... +// _10 = const 2usize; +// END rustc.norm2.InstCombine.after.mir