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 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 diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs index fac6acaca6125..99ad424cc20b7 100644 --- a/src/liballoc/linked_list.rs +++ b/src/liballoc/linked_list.rs @@ -1288,6 +1288,8 @@ mod tests { let mut node_ptr: &Node; match list.head { None => { + // tail node should also be None. + assert!(list.tail.is_none()); assert_eq!(0, list.len); return; } @@ -1314,6 +1316,11 @@ mod tests { } } } + + // verify that the tail node points to the last node. + let tail = list.tail.as_ref().expect("some tail node").as_ref(); + assert_eq!(tail as *const Node, node_ptr as *const Node); + // check that len matches interior links. assert_eq!(len, list.len); } } 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]. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index a858a8d7449f4..f8933d06360e0 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,)* } 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/libstd/io/mod.rs b/src/libstd/io/mod.rs index 54ee8880ec3c1..b7a3695b47096 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -441,7 +441,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; @@ -465,7 +465,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 { 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