]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #34587 - ollie27:rustdoc_prim_titles, r=steveklabnik
authorbors <bors@rust-lang.org>
Wed, 6 Jul 2016 03:16:40 +0000 (20:16 -0700)
committerGitHub <noreply@github.com>
Wed, 6 Jul 2016 03:16:40 +0000 (20:16 -0700)
rustdoc: Remove paths from primitive page <title> tags

Currently primitive pages have a title like "std::u8 - Rust" this changes
it to "u8 - Rust" as "std::u8" is the name of a module not a primitive
type.

202 files changed:
README.md
RELEASES.md
configure
mk/cfg/i686-unknown-linux-gnu.mk
mk/llvm.mk
src/bootstrap/bootstrap.py
src/bootstrap/build/cc.rs
src/bootstrap/build/check.rs
src/bootstrap/build/clean.rs
src/bootstrap/build/config.rs
src/bootstrap/build/dist.rs
src/bootstrap/build/mod.rs
src/bootstrap/build/native.rs
src/bootstrap/build/sanity.rs
src/bootstrap/build/step.rs
src/bootstrap/mk/Makefile.in
src/compiler-rt
src/doc/book/ffi.md
src/doc/book/glossary.md
src/doc/book/lifetimes.md
src/doc/book/ownership.md
src/doc/book/raw-pointers.md
src/doc/book/references-and-borrowing.md
src/doc/book/strings.md
src/doc/book/unsafe.md
src/etc/debugger_pretty_printers_common.py
src/etc/gdb_rust_pretty_printing.py
src/etc/platform-intrinsics/aarch64.json
src/etc/platform-intrinsics/arm.json
src/etc/platform-intrinsics/generator.py
src/etc/platform-intrinsics/x86/avx.json
src/etc/platform-intrinsics/x86/avx2.json
src/etc/platform-intrinsics/x86/bmi.json [new file with mode: 0644]
src/etc/platform-intrinsics/x86/bmi2.json [new file with mode: 0644]
src/etc/platform-intrinsics/x86/fma.json
src/etc/platform-intrinsics/x86/info.json
src/etc/platform-intrinsics/x86/sse.json
src/etc/platform-intrinsics/x86/sse2.json
src/etc/platform-intrinsics/x86/sse3.json
src/etc/platform-intrinsics/x86/sse41.json
src/etc/platform-intrinsics/x86/sse42.json
src/etc/platform-intrinsics/x86/ssse3.json
src/etc/platform-intrinsics/x86/tbm.json [new file with mode: 0644]
src/etc/rust-lldb
src/libcollections/binary_heap.rs
src/libcollections/borrow.rs
src/libcollections/btree/map.rs
src/libcollections/btree/set.rs
src/libcollections/lib.rs
src/libcollectionstest/lib.rs
src/libcore/cell.rs
src/libcore/fmt/mod.rs
src/libcore/hash/mod.rs
src/libcore/hash/sip.rs
src/libcore/intrinsics.rs
src/libcore/iter/iterator.rs
src/libcore/iter/mod.rs
src/libcore/iter/range.rs
src/libcore/iter/traits.rs
src/libcore/lib.rs
src/libcore/num/dec2flt/algorithm.rs
src/libcore/num/dec2flt/mod.rs
src/libcore/num/dec2flt/rawfp.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/flt2dec/decoder.rs
src/libcore/num/mod.rs
src/libcore/ops.rs
src/libcore/result.rs
src/libcoretest/hash/sip.rs
src/libcoretest/lib.rs
src/libcoretest/num/dec2flt/rawfp.rs
src/libcoretest/num/flt2dec/estimator.rs
src/libcoretest/num/flt2dec/mod.rs
src/librand/rand_impls.rs
src/librustc/dep_graph/thread.rs
src/librustc/hir/print.rs
src/librustc/infer/region_inference/mod.rs
src/librustc/lib.rs
src/librustc/lint/context.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dependency_format.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/liveness.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/weak_lang_items.rs
src/librustc/session/mod.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/mod.rs
src/librustc/ty/contents.rs
src/librustc/ty/fold.rs
src/librustc/ty/util.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/lib.rs
src/librustc_data_structures/indexed_vec.rs
src/librustc_data_structures/obligation_forest/mod.rs
src/librustc_data_structures/obligation_forest/test.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/target_features.rs
src/librustc_driver/test.rs
src/librustc_lint/unused.rs
src/librustc_llvm/build.rs
src/librustc_metadata/Cargo.toml
src/librustc_metadata/astencode.rs
src/librustc_metadata/common.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/lib.rs
src/librustc_metadata/loader.rs
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tyencode.rs
src/librustc_platform_intrinsics/x86.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/lib.rs
src/librustc_trans/_match.rs
src/librustc_trans/adt.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/msvc/arch.rs [new file with mode: 0644]
src/librustc_trans/back/msvc/mod.rs
src/librustc_trans/back/write.rs
src/librustc_trans/base.rs
src/librustc_trans/consts.rs
src/librustc_trans/diagnostics.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/lib.rs
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/monomorphize.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render.rs
src/librustdoc/test.rs
src/libserialize/json.rs
src/libstd/collections/hash/map.rs
src/libstd/lib.rs
src/libstd/net/addr.rs
src/libstd/net/mod.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libstd/path.rs
src/libstd/sys/common/net.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/net.rs
src/libsyntax/attr.rs
src/libsyntax/diagnostic_list.rs [new file with mode: 0644]
src/libsyntax/ext/base.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/format.rs
src/libtest/lib.rs
src/rustc/Cargo.lock
src/test/compile-fail/changing-crates.rs
src/test/compile-fail/const-unsized.rs [new file with mode: 0644]
src/test/compile-fail/intrinsic-return-address.rs [new file with mode: 0644]
src/test/compile-fail/issue-24446.rs
src/test/compile-fail/range-1.rs
src/test/compile-fail/stability-attribute-sanity.rs
src/test/compile-fail/svh-change-lit.rs
src/test/compile-fail/svh-change-significant-cfg.rs
src/test/compile-fail/svh-change-trait-bound.rs
src/test/compile-fail/svh-change-type-arg.rs
src/test/compile-fail/svh-change-type-ret.rs
src/test/compile-fail/svh-change-type-static.rs
src/test/compile-fail/svh-use-trait.rs
src/test/debuginfo/pretty-huge-vec.rs [new file with mode: 0644]
src/test/debuginfo/pretty-uninitialized-vec.rs [new file with mode: 0644]
src/test/debuginfo/vec-slices.rs
src/test/pretty/lifetime.rs [new file with mode: 0644]
src/test/pretty/where-clauses.rs
src/test/run-make/execution-engine/test.rs
src/test/run-make/llvm-phase/Makefile [new file with mode: 0644]
src/test/run-make/llvm-phase/test.rs [new file with mode: 0644]
src/test/run-make/many-crates-but-no-match/Makefile
src/test/run-pass/intrinsic-return-address.rs [new file with mode: 0644]
src/test/run-pass/issue-34503.rs [new file with mode: 0644]
src/test/run-pass/range_inclusive.rs
src/tools/compiletest/src/runtest.rs
src/tools/linkchecker/main.rs
src/tools/rustbook/main.rs

index 69bb3c5e874c0b1ced4349c124704bfedd7bb2a1..49236d6b671ef74cb8f4bb8f90d35171d243dc88 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # The Rust Programming Language
 
-This is the main source code repository for [Rust]. It contains the compiler, standard library,
-and documentation.
+This is the main source code repository for [Rust]. It contains the compiler,
+standard library, and documentation.
 
 [Rust]: https://www.rust-lang.org
 
@@ -64,37 +64,37 @@ build.
 
 #### MinGW
 
-[MSYS2](http://msys2.github.io/) can be used to easily build Rust on Windows:
+[MSYS2][msys2] can be used to easily build Rust on Windows:
 
-1. Grab the latest MSYS2 installer and go through the installer.
+msys2: https://msys2.github.io/
 
-2. From the MSYS2 terminal, install the `mingw64` toolchain and other required
-   tools.
+1. Grab the latest [MSYS2 installer][msys2] and go through the installer.
 
-   ```sh
-   # Update package mirrors (may be needed if you have a fresh install of MSYS2)
-   $ pacman -Sy pacman-mirrors
-   ```
+2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
+   MSYS2 (i.e. `C:\msys64`), depending on whether you want 32-bit or 64-bit
+   Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd
+   -mingw32` or `msys2_shell.cmd -mingw64` from the command line instead)
 
-   Download [MinGW from
-   here](http://mingw-w64.org/doku.php/download/mingw-builds), and choose the
-   `version=4.9.x,threads=win32,exceptions=dwarf/seh` flavor when installing. Also, make sure to install to a path without spaces in it. After installing,
-   add its `bin` directory to your `PATH`. This is due to [#28260](https://github.com/rust-lang/rust/issues/28260), in the future,
-   installing from pacman should be just fine.
+3. From this terminal, install the required tools:
 
    ```sh
-   # Make git available in MSYS2 (if not already available on path)
-   $ pacman -S git
+   # Update package mirrors (may be needed if you have a fresh install of MSYS2)
+   $ pacman -Sy pacman-mirrors
 
-   $ pacman -S base-devel
+   # Install build tools needed for Rust. If you're building a 32-bit compiler,
+   # then replace "x86_64" below with "i686". If you've already got git, python,
+   # or CMake installed and in PATH you can remove them from this list. Note
+   # that it is important that the `python2` and `cmake` packages **not** used.
+   # The build has historically been known to fail with these packages.
+   $ pacman -S git \
+               make \
+               diffutils \
+               mingw-w64-x86_64-python2 \
+               mingw-w64-x86_64-cmake \
+               mingw-w64-x86_64-gcc
    ```
 
-3. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
-   MSYS2 (i.e. `C:\msys`), depending on whether you want 32-bit or 64-bit Rust.
-   (As of the latest version of MSYS2 you have to run `msys2_shell.cmd -mingw32`
-   or `msys2_shell.cmd -mingw64` from the command line instead)
-
-4. Navigate to Rust's source code, configure and build it:
+4. Navigate to Rust's source code (or clone it), then configure and build it:
 
    ```sh
    $ ./configure
@@ -114,12 +114,25 @@ $ ./configure
 $ make && make install
 ```
 
+#### MSVC with rustbuild
+
+For those who don't want the hassle of MSYS or MinGW, you can invoke rustbuild
+directly. All you need are Python 2, CMake, and Git in your PATH (make sure you
+do __not__ use the ones from MSYS!). You'll also need Visual Studio 2013 or
+newer with the C++ tools. Then all you need to do is invoke the appropriate
+vcvars bat file and kick off rustbuild.
+
+```bat
+CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
+python .\src\bootstrap\bootstrap.py
+```
+
 ## Building Documentation
 
 If you’d like to build the documentation, it’s almost the same:
 
 ```sh
-./configure
+./configure
 $ make docs
 ```
 
@@ -154,8 +167,8 @@ Snapshot binaries are currently built and tested on several platforms:
 You may find that other platforms work, but these are our officially
 supported build environments that are most likely to work.
 
-Rust currently needs between 600MiB and 1.5GiB to build, depending on platform. If it hits
-swap, it will take a very long time to build.
+Rust currently needs between 600MiB and 1.5GiB to build, depending on platform.
+If it hits swap, it will take a very long time to build.
 
 There is more advice about hacking on Rust in [CONTRIBUTING.md].
 
@@ -192,4 +205,5 @@ Rust is primarily distributed under the terms of both the MIT license
 and the Apache License (Version 2.0), with portions covered by various
 BSD-like licenses.
 
-See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and [COPYRIGHT](COPYRIGHT) for details.
+See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
+[COPYRIGHT](COPYRIGHT) for details.
index 4b404259480b5ee24fb238a65e3b301ee4caa32a..ffe8d64ff2da4c71b64338b88b460a5946f63b05 100644 (file)
@@ -1,3 +1,315 @@
+Version 1.10.0 (2016-07-07)
+===========================
+
+Language
+--------
+
+* [Allow `concat_idents!` in type positions as well as in expression
+  positions]
+  (https://github.com/rust-lang/rust/pull/33735).
+* [`Copy` types are required to have a trivial implementation of `Clone`]
+  (https://github.com/rust-lang/rust/pull/33420).
+  [RFC 1521](https://github.com/rust-lang/rfcs/blob/master/text/1521-copy-clone-semantics.md).
+* [Single-variant enums support the `#[repr(..)]` attribute]
+  (https://github.com/rust-lang/rust/pull/33355).
+* [Fix `#[derive(RustcEncodable)]` in the presence of other `encode` methods]
+  (https://github.com/rust-lang/rust/pull/32908).
+* [`panic!` can be converted to a runtime abort with the
+  `-C panic=abort` flag]
+  (https://github.com/rust-lang/rust/pull/32900).
+  [RFC 1513](https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md).
+* [Add a new crate type, 'cdylib']
+  (https://github.com/rust-lang/rust/pull/33553).
+  cdylibs are dynamic libraries suitable for loading by non-Rust hosts.
+  [RFC 1510](https://github.com/rust-lang/rfcs/blob/master/text/1510-rdylib.md).
+  Note that Cargo does not yet directly support cdylibs.
+
+Stabilized APIs
+---------------
+
+* `os::windows::fs::OpenOptionsExt::access_mode`
+* `os::windows::fs::OpenOptionsExt::share_mode`
+* `os::windows::fs::OpenOptionsExt::custom_flags`
+* `os::windows::fs::OpenOptionsExt::attributes`
+* `os::windows::fs::OpenOptionsExt::security_qos_flags`
+* `os::unix::fs::OpenOptionsExt::custom_flags`
+* [`sync::Weak::new`]
+  (http://doc.rust-lang.org/alloc/arc/struct.Weak.html#method.new)
+* `Default for sync::Weak`
+* [`panic::set_hook`]
+  (http://doc.rust-lang.org/std/panic/fn.set_hook.html)
+* [`panic::take_hook`]
+  (http://doc.rust-lang.org/std/panic/fn.take_hook.html)
+* [`panic::PanicInfo`]
+  (http://doc.rust-lang.org/std/panic/struct.PanicInfo.html)
+* [`panic::PanicInfo::payload`]
+  (http://doc.rust-lang.org/std/panic/struct.PanicInfo.html#method.payload)
+* [`panic::PanicInfo::location`]
+  (http://doc.rust-lang.org/std/panic/struct.PanicInfo.html#method.location)
+* [`panic::Location`]
+  (http://doc.rust-lang.org/std/panic/struct.Location.html)
+* [`panic::Location::file`]
+  (http://doc.rust-lang.org/std/panic/struct.Location.html#method.file)
+* [`panic::Location::line`]
+  (http://doc.rust-lang.org/std/panic/struct.Location.html#method.line)
+* [`ffi::CStr::from_bytes_with_nul`]
+  (http://doc.rust-lang.org/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
+* [`ffi::CStr::from_bytes_with_nul_unchecked`]
+  (http://doc.rust-lang.org/std/ffi/struct.CStr.html#method.from_bytes_with_nul_unchecked)
+* [`ffi::FromBytesWithNulError`]
+  (http://doc.rust-lang.org/std/ffi/struct.FromBytesWithNulError.html)
+* [`fs::Metadata::modified`]
+  (http://doc.rust-lang.org/std/fs/struct.Metadata.html#method.modified)
+* [`fs::Metadata::accessed`]
+  (http://doc.rust-lang.org/std/fs/struct.Metadata.html#method.accessed)
+* [`fs::Metadata::created`]
+  (http://doc.rust-lang.org/std/fs/struct.Metadata.html#method.created)
+* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
+* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
+* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
+* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
+* [`SocketAddr::is_unnamed`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.SocketAddr.html#method.is_unnamed)
+* [`SocketAddr::as_pathname`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.SocketAddr.html#method.as_pathname)
+* [`UnixStream::connect`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.connect)
+* [`UnixStream::pair`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.pair)
+* [`UnixStream::try_clone`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.try_clone)
+* [`UnixStream::local_addr`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.local_addr)
+* [`UnixStream::peer_addr`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.peer_addr)
+* [`UnixStream::set_read_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.read_timeout)
+* [`UnixStream::set_write_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.write_timeout)
+* [`UnixStream::read_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.read_timeout)
+* [`UnixStream::write_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.write_timeout)
+* [`UnixStream::set_nonblocking`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.set_nonblocking)
+* [`UnixStream::take_error`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.take_error)
+* [`UnixStream::shutdown`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html#method.shutdown)
+* Read/Write/RawFd impls for `UnixStream`
+* [`UnixListener::bind`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.bind)
+* [`UnixListener::accept`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.accept)
+* [`UnixListener::try_clone`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.try_clone)
+* [`UnixListener::local_addr`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.local_addr)
+* [`UnixListener::set_nonblocking`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.set_nonblocking)
+* [`UnixListener::take_error`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.take_error)
+* [`UnixListener::incoming`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html#method.incoming)
+* RawFd impls for `UnixListener`
+* [`UnixDatagram::bind`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.bind)
+* [`UnixDatagram::unbound`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.unbound)
+* [`UnixDatagram::pair`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.pair)
+* [`UnixDatagram::connect`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.connect)
+* [`UnixDatagram::try_clone`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.try_clone)
+* [`UnixDatagram::local_addr`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.local_addr)
+* [`UnixDatagram::peer_addr`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.peer_addr)
+* [`UnixDatagram::recv_from`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.recv_from)
+* [`UnixDatagram::recv`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.recv)
+* [`UnixDatagram::send_to`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.send_to)
+* [`UnixDatagram::send`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.send)
+* [`UnixDatagram::set_read_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.set_read_timeout)
+* [`UnixDatagram::set_write_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.set_write_timeout)
+* [`UnixDatagram::read_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.read_timeout)
+* [`UnixDatagram::write_timeout`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.write_timeout)
+* [`UnixDatagram::set_nonblocking`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.set_nonblocking)
+* [`UnixDatagram::take_error`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.take_error)
+* [`UnixDatagram::shutdown`]
+  (http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown)
+* RawFd impls for `UnixDatagram`
+* `{BTree,Hash}Map::values_mut`
+* [`<[_]>::binary_search_by_key`]
+  (http://doc.rust-lang.org/beta/std/primitive.slice.html#method.binary_search_by_key)
+
+Libraries
+---------
+
+* [The `abs_sub` method of floats is deprecated]
+  (https://github.com/rust-lang/rust/pull/33664).
+  The semantics of this minor method are subtle and probably not what
+  most people want.
+* [Add implementation of Ord for Cell<T> and RefCell<T> where T: Ord]
+  (https://github.com/rust-lang/rust/pull/33306).
+* [On Linux, if `HashMap`s can't be initialized with `getrandom` they
+  will fall back to `/dev/urandom` temporarily to avoid blocking
+  during early boot]
+  (https://github.com/rust-lang/rust/pull/33086).
+* [Implemented negation for wrapping numerals]
+  (https://github.com/rust-lang/rust/pull/33067).
+* [Implement `Clone` for `binary_heap::IntoIter`]
+  (https://github.com/rust-lang/rust/pull/33050).
+* [Implement `Display` and `Hash` for `std::num::Wrapping`]
+  (https://github.com/rust-lang/rust/pull/33023).
+* [Add `Default` implementation for `&CStr`, `CString`, `Path`]
+  (https://github.com/rust-lang/rust/pull/32990).
+* [Implement `From<Vec<T>>` and `Into<Vec<T>>` for `VecDeque<T>`]
+  (https://github.com/rust-lang/rust/pull/32866).
+* [Implement `Default` for `UnsafeCell`, `fmt::Error`, `Condvar`,
+  `Mutex`, `RwLock`]
+  (https://github.com/rust-lang/rust/pull/32785).
+
+Cargo
+-----
+* [Cargo.toml supports the `profile.*.panic` option]
+  (https://github.com/rust-lang/cargo/pull/2687).
+  This controls the runtime behavior of the `panic!` macro
+  and can be either "unwind" (the default), or "abort".
+  [RFC 1513](https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md).
+* [Don't throw away errors with `-p` arguments]
+  (https://github.com/rust-lang/cargo/pull/2723).
+* [Report status to stderr instead of stdout]
+  (https://github.com/rust-lang/cargo/pull/2693).
+* [Build scripts are passed a `CARGO_MANIFEST_LINKS` environment
+  variable that corresponds to the `links` field of the manifest]
+  (https://github.com/rust-lang/cargo/pull/2710).
+* [Ban keywords from crate names]
+  (https://github.com/rust-lang/cargo/pull/2707).
+* [Canonicalize `CARGO_HOME` on Windows]
+  (https://github.com/rust-lang/cargo/pull/2604).
+* [Retry network requests]
+  (https://github.com/rust-lang/cargo/pull/2396).
+  By default they are retried twice, which can be customized with the
+  `net.retry` value in `.cargo/config`.
+* [Don't print extra error info for failing subcommands]
+  (https://github.com/rust-lang/cargo/pull/2674).
+* [Add `--force` flag to `cargo install`]
+  (https://github.com/rust-lang/cargo/pull/2405).
+* [Don't use `flock` on NFS mounts]
+  (https://github.com/rust-lang/cargo/pull/2623).
+* [Prefer building `cargo install` artifacts in temporary directories]
+  (https://github.com/rust-lang/cargo/pull/2610).
+  Makes it possible to install multiple crates in parallel.
+* [Add `cargo test --doc`]
+  (https://github.com/rust-lang/cargo/pull/2578).
+* [Add `cargo --explain`]
+  (https://github.com/rust-lang/cargo/pull/2551).
+* [Don't print warnings when `-q` is passed]
+  (https://github.com/rust-lang/cargo/pull/2576).
+* [Add `cargo doc --lib` and `--bin`]
+  (https://github.com/rust-lang/cargo/pull/2577).
+* [Don't require build script output to be UTF-8]
+  (https://github.com/rust-lang/cargo/pull/2560).
+* [Correctly attempt multiple git usernames]
+  (https://github.com/rust-lang/cargo/pull/2584).
+
+Performance
+-----------
+
+* [rustc memory usage was reduced by refactoring the context used for
+  type checking]
+  (https://github.com/rust-lang/rust/pull/33425).
+* [Speed up creation of `HashMap`s by caching the random keys used
+  to initialize the hash state]
+  (https://github.com/rust-lang/rust/pull/33318).
+* [The `find` implementation for `Chain` iterators is 2x faster]
+  (https://github.com/rust-lang/rust/pull/33289).
+* [Trait selection optimizations speed up type checking by 15%]
+  (https://github.com/rust-lang/rust/pull/33138).
+* [Efficient trie lookup for boolean Unicode properties]
+  (https://github.com/rust-lang/rust/pull/33098).
+  10x faster than the previous lookup tables.
+* [Special case `#[derive(Copy, Clone)]` to avoid bloat]
+  (https://github.com/rust-lang/rust/pull/31414).
+
+Usability
+---------
+
+* Many incremental improvements to documentation and rustdoc.
+* [rustdoc: List blanket trait impls]
+  (https://github.com/rust-lang/rust/pull/33514).
+* [rustdoc: Clean up ABI rendering]
+  (https://github.com/rust-lang/rust/pull/33151).
+* [Indexing with the wrong type produces a more informative error]
+  (https://github.com/rust-lang/rust/pull/33401).
+* [Improve diagnostics for constants being used in irrefutable patterns]
+  (https://github.com/rust-lang/rust/pull/33406).
+* [When many method candidates are in scope limit the suggestions to 10]
+  (https://github.com/rust-lang/rust/pull/33338).
+* [Remove confusing suggestion when calling a `fn` type]
+  (https://github.com/rust-lang/rust/pull/33325).
+* [Do not suggest changing `&mut self` to `&mut mut self`]
+  (https://github.com/rust-lang/rust/pull/33319).
+
+Misc
+----
+
+* [Update i686-linux-android features to match Android ABI]
+  (https://github.com/rust-lang/rust/pull/33651).
+* [Update aarch64-linux-android features to match Android ABI]
+  (https://github.com/rust-lang/rust/pull/33500).
+* [`std` no longer prints backtraces on platforms where the running
+  module must be loaded with `env::current_exe`, which can't be relied
+  on](https://github.com/rust-lang/rust/pull/33554).
+* This release includes std binaries for the i586-unknown-linux-gnu,
+  i686-unknown-linux-musl, and armv7-linux-androideabi targets. The
+  i586 target is for old x86 hardware without SSE2, and the armv7
+  target is for Android running on modern ARM architectures.
+* [The `rust-gdb` and `rust-lldb` scripts are distributed on all
+  Unix platforms](https://github.com/rust-lang/rust/pull/32835).
+* [On Unix the runtime aborts by calling `libc::abort` instead of
+  generating an illegal instruction]
+  (https://github.com/rust-lang/rust/pull/31457).
+* [Rust is now bootstrapped from the previous release of Rust,
+  instead of a snapshot from an arbitrary commit]
+  (https://github.com/rust-lang/rust/pull/32942).
+
+Compatibility Notes
+-------------------
+
+* [`AtomicBool` is now bool-sized, not word-sized]
+  (https://github.com/rust-lang/rust/pull/33579).
+* [`target_env` for Linux ARM targets is just `gnu`, not
+  `gnueabihf`, `gnueabi`, etc]
+  (https://github.com/rust-lang/rust/pull/33403).
+* [Consistently panic on overflow in `Duration::new`]
+  (https://github.com/rust-lang/rust/pull/33072).
+* [Change `String::truncate` to panic less]
+  (https://github.com/rust-lang/rust/pull/32977).
+* [Add `:block` to the follow set for `:ty` and `:path`]
+  (https://github.com/rust-lang/rust/pull/32945).
+  Affects how macros are parsed.
+* [Fix macro hygiene bug]
+  (https://github.com/rust-lang/rust/pull/32923).
+* [Feature-gated attributes on macro-generated macro invocations are
+  now rejected]
+  (https://github.com/rust-lang/rust/pull/32791).
+* [Suppress fallback and ambiguity errors during type inference]
+  (https://github.com/rust-lang/rust/pull/32258).
+  This caused some minor changes to type inference.
+
+
 Version 1.9.0 (2016-05-26)
 ==========================
 
index 762b0885289621c6b9dd51313c0fccc455c1e137..6451b87673f628c230d2686f3f7dc3773506bd10 100755 (executable)
--- a/configure
+++ b/configure
@@ -1178,33 +1178,6 @@ do
             ;;
 
         *-msvc)
-            # There are some MSYS python builds which will auto-translate
-            # windows-style paths to MSYS-style paths in Python itself.
-            # Unfortunately this breaks LLVM's build system as somewhere along
-            # the line LLVM prints a path into a file from Python and then CMake
-            # later tries to interpret that path. If Python prints a MSYS path
-            # and CMake tries to use it as a Windows path, you're gonna have a
-            # Bad Time.
-            #
-            # Consequently here we try to detect when that happens and print an
-            # error if it does.
-            if $CFG_PYTHON -c 'import sys; print sys.argv[1]' `pwd` | grep '^/' > /dev/null
-            then
-                err "
-
-python is silently translating windows paths to MSYS paths \
-and the build will fail if this python is used.
-
-Either an official python install must be used or an \
-alternative python package in MinGW must be used.
-
-If you are building under msys2 try installing the mingw-w64-x86_64-python2 \
-package instead of python2:
-
-$ pacman -R python2 && pacman -S mingw-w64-x86_64-python2
-"
-            fi
-
             # There are three builds of cmake on windows: MSVC, MinGW and Cygwin
             # The Cygwin build does not have generators for Visual Studio, so
             # detect that here and error.
@@ -1288,6 +1261,36 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
     esac
 done
 
+if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ]
+then
+    # There are some MSYS python builds which will auto-translate
+    # windows-style paths to MSYS-style paths in Python itself.
+    # Unfortunately this breaks LLVM's build system as somewhere along
+    # the line LLVM prints a path into a file from Python and then CMake
+    # later tries to interpret that path. If Python prints a MSYS path
+    # and CMake tries to use it as a Windows path, you're gonna have a
+    # Bad Time.
+    #
+    # Consequently here we try to detect when that happens and print an
+    # error if it does.
+    if $CFG_PYTHON -c 'import sys; print sys.argv[1]' `pwd` | grep '^/' > /dev/null
+    then
+        err "
+
+python is silently translating windows paths to MSYS paths \
+and the build will fail if this python is used.
+
+Either an official python install must be used or an \
+alternative python package in MinGW must be used.
+
+If you are building under msys2 try installing the mingw-w64-x86_64-python2 \
+package instead of python2:
+
+$ pacman -S mingw-w64-x86_64-python2
+"
+    fi
+fi
+
 if [ -n "$CFG_PERF" ]
 then
     HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'`
@@ -1726,7 +1729,7 @@ do
         msg "configuring LLVM with:"
         msg "$CMAKE_ARGS"
 
-        (cd $LLVM_BUILD_DIR && eval "$CFG_CMAKE" $CMAKE_ARGS)
+        (cd $LLVM_BUILD_DIR && eval "\"$CFG_CMAKE\"" $CMAKE_ARGS)
         need_ok "LLVM cmake configure failed"
     fi
 
index 88c0907f63b2ac8f8be2e4d30078d31fe75db184..129af8ac69609396b0b31cd496f294e0e9ed4d18 100644 (file)
@@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
 CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
 CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
 CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=i686
 CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
 CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread  -lrt -g -m32
 CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
index 6d8601f3dad6d3bee0c8ce725e2efc4418fe85b2..2298565221072acf3e36dc9a4ff148dc16a40379 100644 (file)
@@ -37,8 +37,11 @@ endif
 ifeq ($(CFG_LLVM_ROOT),)
 
 LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp
+LLVM_DONE_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-finished-building
 
-$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS_TARGET_$(1)) $$(LLVM_STAMP_$(1))
+$$(LLVM_CONFIG_$(1)): $$(LLVM_DONE_$(1))
+
+$$(LLVM_DONE_$(1)): $$(LLVM_DEPS_TARGET_$(1)) $$(LLVM_STAMP_$(1))
        @$$(call E, cmake: llvm)
 ifeq ($$(findstring msvc,$(1)),msvc)
        $$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
@@ -46,7 +49,7 @@ ifeq ($$(findstring msvc,$(1)),msvc)
 else
        $$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1))
 endif
-       $$(Q)touch $$(LLVM_CONFIG_$(1))
+       $$(Q)touch $$@
 
 ifeq ($$(findstring msvc,$(1)),msvc)
 clean-llvm$(1):
index 7b0a5d6b6dfc4fcbc38f2f5b46281ad914a3fce6..33de8fd0107673ccbeb97c4699df506e1f2d143c 100644 (file)
@@ -10,6 +10,7 @@
 
 import argparse
 import contextlib
+import datetime
 import hashlib
 import os
 import shutil
@@ -18,6 +19,8 @@ import sys
 import tarfile
 import tempfile
 
+from time import time
+
 
 def get(url, path, verbose=False):
     sha_url = url + ".sha256"
@@ -118,6 +121,9 @@ def stage0_data(rust_root):
             data[a] = b
     return data
 
+def format_build_time(duration):
+    return str(datetime.timedelta(seconds=int(duration)))
+
 class RustBuild:
     def download_stage0(self):
         cache_dst = os.path.join(self.build_dir, "cache")
@@ -265,7 +271,7 @@ class RustBuild:
         try:
             ostype = subprocess.check_output(['uname', '-s']).strip()
             cputype = subprocess.check_output(['uname', '-m']).strip()
-        except subprocess.CalledProcessError:
+        except (subprocess.CalledProcessError, WindowsError):
             if sys.platform == 'win32':
                 return 'x86_64-pc-windows-msvc'
             err = "uname not found"
@@ -372,6 +378,8 @@ def main():
     rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1)
     rb._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1)
 
+    start_time = time()
+
     # Fetch/build the bootstrap
     rb.build = rb.build_triple()
     rb.download_stage0()
@@ -390,5 +398,9 @@ def main():
     env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
     rb.run(args, env)
 
+    end_time = time()
+
+    print("Build completed in %s" % format_build_time(end_time - start_time))
+
 if __name__ == '__main__':
     main()
index 7eb50b8b86dac0abcfad3a0d9fc75094153fc09c..ff0941a97dce1e3fcbfde7bdf64e79dca66ffc33 100644 (file)
@@ -90,6 +90,7 @@ fn set_compiler(cfg: &mut gcc::Config,
         // compiler already takes into account the triple in question.
         t if t.contains("android") => {
             if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
+                let target = target.replace("armv7", "arm");
                 let compiler = format!("{}-{}", target, gnu_compiler);
                 cfg.compiler(ndk.join("bin").join(compiler));
             }
index 154d9556fd7ba2331e248ab1e9c20c7ca72757f7..0a096f8e4de417aea9560ad28f3e5c3f6a3503c4 100644 (file)
@@ -23,6 +23,9 @@
 use bootstrap::{dylib_path, dylib_path_var};
 
 use build::{Build, Compiler, Mode};
+use build::util;
+
+const ADB_TEST_DIR: &'static str = "/data/tmp";
 
 /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
 ///
@@ -88,6 +91,7 @@ pub fn compiletest(build: &Build,
                    target: &str,
                    mode: &str,
                    suite: &str) {
+    println!("Check compiletest {} ({} -> {})", suite, compiler.host, target);
     let mut cmd = build.tool_cmd(compiler, "compiletest");
 
     // compiletest currently has... a lot of arguments, so let's just pass all
@@ -105,21 +109,23 @@ pub fn compiletest(build: &Build,
     cmd.arg("--host").arg(compiler.host);
     cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
 
-    let mut flags = format!("-Crpath");
+    let mut flags = vec!["-Crpath".to_string()];
     if build.config.rust_optimize_tests {
-        flags.push_str(" -O");
+        flags.push("-O".to_string());
     }
     if build.config.rust_debuginfo_tests {
-        flags.push_str(" -g");
+        flags.push("-g".to_string());
     }
 
-    cmd.arg("--host-rustcflags").arg(&flags);
-
-    let linkflag = format!("-Lnative={}", build.test_helpers_out(target).display());
-    cmd.arg("--target-rustcflags").arg(format!("{} {}", flags, linkflag));
+    let mut hostflags = build.rustc_flags(&compiler.host);
+    hostflags.extend(flags.clone());
+    cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
 
-    // FIXME: needs android support
-    cmd.arg("--android-cross-path").arg("");
+    let mut targetflags = build.rustc_flags(&target);
+    targetflags.extend(flags);
+    targetflags.push(format!("-Lnative={}",
+                             build.test_helpers_out(target).display()));
+    cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
 
     // FIXME: CFG_PYTHON should probably be detected more robustly elsewhere
     let python_default = "python";
@@ -180,6 +186,16 @@ pub fn compiletest(build: &Build,
     }
     build.add_bootstrap_key(compiler, &mut cmd);
 
+    cmd.arg("--adb-path").arg("adb");
+    cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
+    if target.contains("android") {
+        // Assume that cc for this target comes from the android sysroot
+        cmd.arg("--android-cross-path")
+           .arg(build.cc(target).parent().unwrap().parent().unwrap());
+    } else {
+        cmd.arg("--android-cross-path").arg("");
+    }
+
     build.run(&mut cmd);
 }
 
@@ -302,7 +318,97 @@ pub fn krate(build: &Build,
     let mut dylib_path = dylib_path();
     dylib_path.insert(0, build.sysroot_libdir(compiler, target));
     cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
-    cargo.args(&build.flags.args);
 
-    build.run(&mut cargo);
+    if target.contains("android") {
+        build.run(cargo.arg("--no-run"));
+        krate_android(build, compiler, target, mode);
+    } else {
+        cargo.args(&build.flags.args);
+        build.run(&mut cargo);
+    }
+}
+
+fn krate_android(build: &Build,
+                 compiler: &Compiler,
+                 target: &str,
+                 mode: Mode) {
+    let mut tests = Vec::new();
+    let out_dir = build.cargo_out(compiler, mode, target);
+    find_tests(&out_dir, target, &mut tests);
+    find_tests(&out_dir.join("deps"), target, &mut tests);
+
+    for test in tests {
+        build.run(Command::new("adb").arg("push").arg(&test).arg(ADB_TEST_DIR));
+
+        let test_file_name = test.file_name().unwrap().to_string_lossy();
+        let log = format!("{}/check-stage{}-T-{}-H-{}-{}.log",
+                          ADB_TEST_DIR,
+                          compiler.stage,
+                          target,
+                          compiler.host,
+                          test_file_name);
+        let program = format!("(cd {dir}; \
+                                LD_LIBRARY_PATH=./{target} ./{test} \
+                                    --logfile {log} \
+                                    {args})",
+                              dir = ADB_TEST_DIR,
+                              target = target,
+                              test = test_file_name,
+                              log = log,
+                              args = build.flags.args.join(" "));
+
+        let output = output(Command::new("adb").arg("shell").arg(&program));
+        println!("{}", output);
+        build.run(Command::new("adb")
+                          .arg("pull")
+                          .arg(&log)
+                          .arg(build.out.join("tmp")));
+        build.run(Command::new("adb").arg("shell").arg("rm").arg(&log));
+        if !output.contains("result: ok") {
+            panic!("some tests failed");
+        }
+    }
+}
+
+fn find_tests(dir: &Path,
+              target: &str,
+              dst: &mut Vec<PathBuf>) {
+    for e in t!(dir.read_dir()).map(|e| t!(e)) {
+        let file_type = t!(e.file_type());
+        if !file_type.is_file() {
+            continue
+        }
+        let filename = e.file_name().into_string().unwrap();
+        if (target.contains("windows") && filename.ends_with(".exe")) ||
+           (!target.contains("windows") && !filename.contains(".")) {
+            dst.push(e.path());
+        }
+    }
+}
+
+pub fn android_copy_libs(build: &Build,
+                         compiler: &Compiler,
+                         target: &str) {
+    println!("Android copy libs to emulator ({})", target);
+    build.run(Command::new("adb").arg("remount"));
+    build.run(Command::new("adb").args(&["shell", "rm", "-r", ADB_TEST_DIR]));
+    build.run(Command::new("adb").args(&["shell", "mkdir", ADB_TEST_DIR]));
+    build.run(Command::new("adb")
+                      .arg("push")
+                      .arg(build.src.join("src/etc/adb_run_wrapper.sh"))
+                      .arg(ADB_TEST_DIR));
+
+    let target_dir = format!("{}/{}", ADB_TEST_DIR, target);
+    build.run(Command::new("adb").args(&["shell", "mkdir", &target_dir[..]]));
+
+    for f in t!(build.sysroot_libdir(compiler, target).read_dir()) {
+        let f = t!(f);
+        let name = f.file_name().into_string().unwrap();
+        if util::is_dylib(&name) {
+            build.run(Command::new("adb")
+                              .arg("push")
+                              .arg(f.path())
+                              .arg(&target_dir));
+        }
+    }
 }
index 1d407c941323545a9745c5e794de5ff5478536de..91334bdb91e2251d3bb635ae3aaf54bda5241c4f 100644 (file)
@@ -21,6 +21,9 @@
 use build::Build;
 
 pub fn clean(build: &Build) {
+    rm_rf(build, "tmp".as_ref());
+    rm_rf(build, &build.out.join("tmp"));
+
     for host in build.config.host.iter() {
 
         let out = build.out.join(host);
index e155bf356a0d8fc85c8f84b87ed93e5785b91af8..498196e9b6dfc12454274e75cd695c2ad2a04b65 100644 (file)
@@ -368,13 +368,13 @@ macro_rules! check {
                     target.ndk = Some(PathBuf::from(value));
                 }
                 "CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => {
-                    let target = "i686-linux-androideabi".to_string();
+                    let target = "i686-linux-android".to_string();
                     let target = self.target_config.entry(target)
                                      .or_insert(Target::default());
                     target.ndk = Some(PathBuf::from(value));
                 }
                 "CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => {
-                    let target = "aarch64-linux-androideabi".to_string();
+                    let target = "aarch64-linux-android".to_string();
                     let target = self.target_config.entry(target)
                                      .or_insert(Target::default());
                     target.ndk = Some(PathBuf::from(value));
index 088e89b658d46699d0d6ff920852b66c44f5043b..6eed7eaf206f4631f584604a5aefa11d70329041 100644 (file)
@@ -135,7 +135,6 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
 
     // Prepare the overlay which is part of the tarball but won't actually be
     // installed
-    t!(fs::create_dir_all(&overlay));
     let cp = |file: &str| {
         install(&build.src.join(file), &overlay, 0o644);
     };
@@ -199,7 +198,6 @@ fn prepare_image(build: &Build, stage: u32, host: &str, image: &Path) {
 
         // Copy runtime DLLs needed by the compiler
         if libdir != "bin" {
-            t!(fs::create_dir_all(image.join(libdir)));
             for entry in t!(src.join(libdir).read_dir()).map(|e| t!(e)) {
                 let name = entry.file_name();
                 if let Some(s) = name.to_str() {
@@ -221,7 +219,6 @@ fn prepare_image(build: &Build, stage: u32, host: &str, image: &Path) {
         let cp = |file: &str| {
             install(&build.src.join(file), &image.join("share/doc/rust"), 0o644);
         };
-        t!(fs::create_dir_all(&image.join("share/doc/rust")));
         cp("COPYRIGHT");
         cp("LICENSE-APACHE");
         cp("LICENSE-MIT");
@@ -289,6 +286,7 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
 
 fn install(src: &Path, dstdir: &Path, perms: u32) {
     let dst = dstdir.join(src.file_name().unwrap());
+    t!(fs::create_dir_all(dstdir));
     t!(fs::copy(src, &dst));
     chmod(&dst, perms);
 }
index dadb0ffa6c98d73bb9b4d7c1dfcf7b75b7434e73..195d1bc90c655fb191f832aeaa46c6bf8e3eb45a 100644 (file)
@@ -128,6 +128,7 @@ pub struct Build {
 ///
 /// These entries currently correspond to the various output directories of the
 /// build system, with each mod generating output in a different directory.
+#[derive(Clone, Copy)]
 pub enum Mode {
     /// This cargo is going to build the standard library, placing output in the
     /// "stageN-std" directory.
@@ -383,8 +384,7 @@ pub fn build(&mut self) {
                                        "ui", "ui");
                 }
                 CheckDebuginfo { compiler } => {
-                    if target.target.contains("msvc") ||
-                       target.target.contains("android") {
+                    if target.target.contains("msvc") {
                         // nothing to do
                     } else if target.target.contains("apple") {
                         check::compiletest(self, &compiler, target.target,
@@ -434,8 +434,14 @@ pub fn build(&mut self) {
                                            target.target);
                 }
 
+                AndroidCopyLibs { compiler } => {
+                    check::android_copy_libs(self, &compiler, target.target);
+                }
+
+                // pseudo-steps
                 Dist { .. } |
-                Doc { .. } | // pseudo-steps
+                Doc { .. } |
+                CheckTarget { .. } |
                 Check { .. } => {}
             }
         }
index 1e677aa48b0f664346ad29af25d756627578b4e7..f6030cfd090d223e314bd93592a04d5e4bca7d62 100644 (file)
 
 use std::path::Path;
 use std::process::Command;
-use std::fs;
+use std::fs::{self, File};
 
 use build_helper::output;
 use cmake;
 use gcc;
 
 use build::Build;
-use build::util::{exe, staticlib, up_to_date};
+use build::util::{staticlib, up_to_date};
 
 /// Compile LLVM for `target`.
 pub fn llvm(build: &Build, target: &str) {
@@ -43,12 +43,14 @@ pub fn llvm(build: &Build, target: &str) {
     // artifacts are missing) then we keep going, otherwise we bail out.
     let dst = build.llvm_out(target);
     let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
-    let llvm_config = dst.join("bin").join(exe("llvm-config", target));
+    let done_stamp = dst.join("llvm-finished-building");
     build.clear_if_dirty(&dst, &stamp);
-    if fs::metadata(llvm_config).is_ok() {
+    if fs::metadata(&done_stamp).is_ok() {
         return
     }
 
+    println!("Building LLVM for {}", target);
+
     let _ = fs::remove_dir_all(&dst.join("build"));
     t!(fs::create_dir_all(&dst.join("build")));
     let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
@@ -111,6 +113,8 @@ pub fn llvm(build: &Build, target: &str) {
     //        tools. Figure out how to filter them down and only build the right
     //        tools and libs on all platforms.
     cfg.build();
+
+    t!(File::create(&done_stamp));
 }
 
 fn check_llvm_version(build: &Build, llvm_config: &Path) {
@@ -165,8 +169,10 @@ pub fn compiler_rt(build: &Build, target: &str) {
             "arm" if target.contains("eabihf") => "armhf",
             _ => arch,
         };
-        let target = format!("clang_rt.builtins-{}{}", builtins_arch, os_extra);
-        ("linux".to_string(), target.clone(), target)
+        let target = format!("clang_rt.builtins-{}", builtins_arch);
+        ("linux".to_string(),
+         target.clone(),
+         format!("{}{}", target, os_extra))
     } else if target.contains("apple-darwin") {
         let builtins_arch = match arch {
             "i686" => "i386",
index fd6cdc702cc3ba4bbc608277851756a70ff21648..5eced00e13973e35109cb32856aa732b16cd9696 100644 (file)
@@ -139,6 +139,10 @@ pub fn check(build: &mut Build) {
 ");
             }
         }
+
+        if target.contains("arm-linux-android") {
+            need_cmd("adb".as_ref());
+        }
     }
 
     for host in build.flags.host.iter() {
index 742fd8575bb809d6abb264ed1c3b49e31432733e..7cbbd6740a2657a5cbbfda23eea3a572fb30d936 100644 (file)
@@ -102,6 +102,7 @@ macro_rules! targets {
             // Steps for running tests. The 'check' target is just a pseudo
             // target to depend on a bunch of others.
             (check, Check { stage: u32, compiler: Compiler<'a> }),
+            (check_target, CheckTarget { stage: u32, compiler: Compiler<'a> }),
             (check_linkcheck, CheckLinkcheck { stage: u32 }),
             (check_cargotest, CheckCargoTest { stage: u32 }),
             (check_tidy, CheckTidy { stage: u32 }),
@@ -138,6 +139,9 @@ macro_rules! targets {
             (dist_mingw, DistMingw { _dummy: () }),
             (dist_rustc, DistRustc { stage: u32 }),
             (dist_std, DistStd { compiler: Compiler<'a> }),
+
+            // Misc targets
+            (android_copy_libs, AndroidCopyLibs { compiler: Compiler<'a> }),
         }
     }
 }
@@ -382,37 +386,80 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
                      self.doc_error_index(stage)]
             }
             Source::Check { stage, compiler } => {
-                vec![
+                // Check is just a pseudo step which means check all targets,
+                // so just depend on checking all targets.
+                build.config.target.iter().map(|t| {
+                    self.target(t).check_target(stage, compiler)
+                }).collect()
+            }
+            Source::CheckTarget { stage, compiler } => {
+                // CheckTarget here means run all possible test suites for this
+                // target. Most of the time, however, we can't actually run
+                // anything if we're not the build triple as we could be cross
+                // compiling.
+                //
+                // As a result, the base set of targets here is quite stripped
+                // down from the standard set of targets. These suites have
+                // their own internal logic to run in cross-compiled situations
+                // if they'll run at all. For example compiletest knows that
+                // when testing Android targets we ship artifacts to the
+                // emulator.
+                //
+                // When in doubt the rule of thumb for adding to this list is
+                // "should this test suite run on the android bot?"
+                let mut base = vec![
                     self.check_rpass(compiler),
-                    self.check_rpass_full(compiler),
                     self.check_rfail(compiler),
-                    self.check_rfail_full(compiler),
-                    self.check_cfail(compiler),
-                    self.check_cfail_full(compiler),
-                    self.check_pfail(compiler),
-                    self.check_incremental(compiler),
-                    self.check_ui(compiler),
                     self.check_crate_std(compiler),
                     self.check_crate_test(compiler),
-                    self.check_crate_rustc(compiler),
-                    self.check_codegen(compiler),
-                    self.check_codegen_units(compiler),
                     self.check_debuginfo(compiler),
-                    self.check_rustdoc(compiler),
-                    self.check_pretty(compiler),
-                    self.check_pretty_rpass(compiler),
-                    self.check_pretty_rpass_full(compiler),
-                    self.check_pretty_rfail(compiler),
-                    self.check_pretty_rfail_full(compiler),
-                    self.check_pretty_rpass_valgrind(compiler),
-                    self.check_rpass_valgrind(compiler),
-                    self.check_error_index(compiler),
-                    self.check_docs(compiler),
-                    self.check_rmake(compiler),
-                    self.check_linkcheck(stage),
-                    self.check_tidy(stage),
                     self.dist(stage),
-                ]
+                ];
+
+                // If we're testing the build triple, then we know we can
+                // actually run binaries and such, so we run all possible tests
+                // that we know about.
+                if self.target == build.config.build {
+                    base.extend(vec![
+                        // docs-related
+                        self.check_docs(compiler),
+                        self.check_error_index(compiler),
+                        self.check_rustdoc(compiler),
+
+                        // UI-related
+                        self.check_cfail(compiler),
+                        self.check_pfail(compiler),
+                        self.check_ui(compiler),
+
+                        // codegen-related
+                        self.check_incremental(compiler),
+                        self.check_codegen(compiler),
+                        self.check_codegen_units(compiler),
+
+                        // misc compiletest-test suites
+                        self.check_rpass_full(compiler),
+                        self.check_rfail_full(compiler),
+                        self.check_cfail_full(compiler),
+                        self.check_pretty_rpass_full(compiler),
+                        self.check_pretty_rfail_full(compiler),
+                        self.check_rpass_valgrind(compiler),
+                        self.check_rmake(compiler),
+
+                        // crates
+                        self.check_crate_rustc(compiler),
+
+                        // pretty
+                        self.check_pretty(compiler),
+                        self.check_pretty_rpass(compiler),
+                        self.check_pretty_rfail(compiler),
+                        self.check_pretty_rpass_valgrind(compiler),
+
+                        // misc
+                        self.check_linkcheck(stage),
+                        self.check_tidy(stage),
+                    ]);
+                }
+                return base
             }
             Source::CheckLinkcheck { stage } => {
                 vec![self.tool_linkchecker(stage), self.doc(stage)]
@@ -437,16 +484,20 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
             Source::CheckCFail { compiler } |
             Source::CheckRPassValgrind { compiler } |
             Source::CheckRPass { compiler } => {
-                vec![
+                let mut base = vec![
                     self.libtest(compiler),
-                    self.tool_compiletest(compiler.stage),
+                    self.target(compiler.host).tool_compiletest(compiler.stage),
                     self.test_helpers(()),
-                ]
+                ];
+                if self.target.contains("android") {
+                    base.push(self.android_copy_libs(compiler));
+                }
+                base
             }
             Source::CheckDebuginfo { compiler } => {
                 vec![
                     self.libtest(compiler),
-                    self.tool_compiletest(compiler.stage),
+                    self.target(compiler.host).tool_compiletest(compiler.stage),
                     self.test_helpers(()),
                     self.debugger_scripts(compiler.stage),
                 ]
@@ -459,13 +510,14 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
             Source::CheckPrettyRPassValgrind { compiler } |
             Source::CheckRMake { compiler } => {
                 vec![self.librustc(compiler),
-                     self.tool_compiletest(compiler.stage)]
+                     self.target(compiler.host).tool_compiletest(compiler.stage)]
             }
             Source::CheckDocs { compiler } => {
                 vec![self.libstd(compiler)]
             }
             Source::CheckErrorIndex { compiler } => {
-                vec![self.libstd(compiler), self.tool_error_index(compiler.stage)]
+                vec![self.libstd(compiler),
+                     self.target(compiler.host).tool_error_index(compiler.stage)]
             }
             Source::CheckCrateStd { compiler } => {
                 vec![self.libtest(compiler)]
@@ -529,6 +581,10 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
                 }
                 return base
             }
+
+            Source::AndroidCopyLibs { compiler } => {
+                vec![self.libtest(compiler)]
+            }
         }
     }
 }
index 1f3ea8f19bb020ae84d99c0c0ed95f29d9207742..c657785d78b6e31f094536b736f7275289c0039a 100644 (file)
@@ -25,6 +25,11 @@ all:
 clean:
        $(Q)$(BOOTSTRAP) --clean
 
+rustc-stage1:
+       $(Q)$(BOOTSTRAP) --step libtest --stage 1
+rustc-stage2:
+       $(Q)$(BOOTSTRAP) --step libtest --stage 2
+
 docs: doc
 doc:
        $(Q)$(BOOTSTRAP) --step doc
index a1ef94b76029780a510bc2dc9c6a791bd091ff19..ac3d1cda612edccb6f1da53cbf7716e248405f3b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a1ef94b76029780a510bc2dc9c6a791bd091ff19
+Subproject commit ac3d1cda612edccb6f1da53cbf7716e248405f3b
index f48e87c42245eca39af7b28289b20903f6c5369a..3fbcbc2f471368ca8cef380ba8a9574724a2b021 100644 (file)
@@ -521,14 +521,14 @@ against `libc` and `libm` by default.
 
 # The "nullable pointer optimization"
 
-Certain types are defined to not be `null`. This includes references (`&T`,
+Certain types are defined to not be NULL. This includes references (`&T`,
 `&mut T`), boxes (`Box<T>`), and function pointers (`extern "abi" fn()`).
-When interfacing with C, pointers that might be null are often used.
+When interfacing with C, pointers that might be NULL are often used.
 As a special case, a generic `enum` that contains exactly two variants, one of
 which contains no data and the other containing a single field, is eligible
 for the "nullable pointer optimization". When such an enum is instantiated
 with one of the non-nullable types, it is represented as a single pointer,
-and the non-data variant is represented as the null pointer. So
+and the non-data variant is represented as the NULL pointer. So
 `Option<extern "C" fn(c_int) -> c_int>` is how one represents a nullable
 function pointer using the C ABI.
 
index 0956580ade0bb0ea3f88fc27a64e22c2a4342549..8aa7fdff94803735f355f8944c60dc0de0c1bdfa 100644 (file)
@@ -46,6 +46,12 @@ must abide by that constraint.
 
 [traits]: traits.html
 
+### Combinators
+
+Combinators are higher-order functions that apply only functions and
+earlier defined combinators to provide a result from its arguments. 
+They can be used to manage control flow in a modular fashion.
+
 ### DST (Dynamically Sized Type)
 
 A type without a statically known size or alignment. ([more info][link])
index cb0757318984db19015035c4d91d3efd7e057d57..f7d9c94bc454f31a052f828a7385623801f7ac5c 100644 (file)
@@ -290,7 +290,7 @@ lifetime parameters using three easily memorizable and unambiguous rules. This m
 acts as a shorthand for writing an item signature, while not hiding
 away the actual types involved as full local inference would if applied to it.
 
-When talking about lifetime elision, we use the term *input lifetime* and
+When talking about lifetime elision, we use the terms *input lifetime* and
 *output lifetime*. An *input lifetime* is a lifetime associated with a parameter
 of a function, and an *output lifetime* is a lifetime associated with the return
 value of a function. For example, this function has an input lifetime:
@@ -335,11 +335,13 @@ fn print<'a>(s: &'a str); // expanded
 
 fn debug(lvl: u32, s: &str); // elided
 fn debug<'a>(lvl: u32, s: &'a str); // expanded
+```
 
-// In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
-// reference (`&`). Only things relating to references (such as a `struct`
-// which contains a reference) need lifetimes.
+In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
+reference (`&`). Only things relating to references (such as a `struct`
+which contains a reference) need lifetimes.
 
+```rust,ignore
 fn substr(s: &str, until: u32) -> &str; // elided
 fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
 
index c3e32e56c42666581f597ad0398f9c8f983d6115..23ca21b3b49923f01ed930a2dbb4acac7d81ff3b 100644 (file)
@@ -214,7 +214,7 @@ But, unlike a move, we can still use `v` afterward. This is because an `i32`
 has no pointers to data somewhere else, copying it is a full copy.
 
 All primitive types implement the `Copy` trait and their ownership is
-therefore not moved like one would assume, following the Â´ownership rules´.
+therefore not moved like one would assume, following the â€˜ownership rules’.
 To give an example, the two following snippets of code only compile because the
 `i32` and `bool` types implement the `Copy` trait.
 
@@ -290,6 +290,6 @@ let (v1, v2, answer) = foo(v1, v2);
 Ugh! The return type, return line, and calling the function gets way more
 complicated.
 
-Luckily, Rust offers a feature, borrowing, which helps us solve this problem.
-It’s the topic of the next section!
+Luckily, Rust offers a feature which helps us solve this problem.
+It’s called borrowing and is the topic of the next section!
 
index 679f5489ea8f4a331f1b25d7d5a0ba945d50052a..ae100aec3b5129c7ab43960e5458bd3dbd74b73e 100644 (file)
@@ -17,7 +17,7 @@ Here are some things to remember about raw pointers that are different than
 other pointer types. They:
 
 - are not guaranteed to point to valid memory and are not even
-  guaranteed to be non-null (unlike both `Box` and `&`);
+  guaranteed to be non-NULL (unlike both `Box` and `&`);
 - do not have any automatic clean-up, unlike `Box`, and so require
   manual resource management;
 - are plain-old-data, that is, they don't move ownership, again unlike
index ef339a14309898fecfef64adecbe686d922d6b04..57bfbce8b84debab2f26a638ae1aed85ecc491ed 100644 (file)
@@ -123,7 +123,7 @@ let v = vec![];
 foo(&v);
 ```
 
-errors with:
+will give us this error:
 
 ```text
 error: cannot borrow immutable borrowed content `*v` as mutable
@@ -152,8 +152,8 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
 If it wasn’t, we couldn’t take a mutable borrow to an immutable value.
 
 You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
-this is because `y` is a `&mut` reference. You'll also need to use them for
-accessing the contents of a reference as well.
+this is because `y` is a `&mut` reference. You'll need to use astrisks to
+access the contents of a reference as well.
 
 Otherwise, `&mut` references are like references. There _is_ a large
 difference between the two, and how they interact, though. You can tell
@@ -179,7 +179,7 @@ As it turns out, there are rules.
 
 # The Rules
 
-Here’s the rules about borrowing in Rust:
+Here are the rules for borrowing in Rust:
 
 First, any borrow must last for a scope no greater than that of the owner.
 Second, you may have one or the other of these two kinds of borrows, but not
@@ -208,12 +208,14 @@ With this in mind, let’s consider our example again.
 Here’s the code:
 
 ```rust,ignore
-let mut x = 5;
-let y = &mut x;
+fn main() {
+    let mut x = 5;
+    let y = &mut x;
 
-*y += 1;
+    *y += 1;
 
-println!("{}", x);
+    println!("{}", x);
+}
 ```
 
 This code gives us this error:
@@ -225,7 +227,7 @@ error: cannot borrow `x` as immutable because it is also borrowed as mutable
 ```
 
 This is because we’ve violated the rules: we have a `&mut T` pointing to `x`,
-and so we aren’t allowed to create any `&T`s. One or the other. The note
+and so we aren’t allowed to create any `&T`s. It's one or the other. The note
 hints at how to think about this problem:
 
 ```text
@@ -243,14 +245,16 @@ In Rust, borrowing is tied to the scope that the borrow is valid for. And our
 scopes look like this:
 
 ```rust,ignore
-let mut x = 5;
-
-let y = &mut x;    // -+ &mut borrow of x starts here
-                   //  |
-*y += 1;           //  |
-                   //  |
-println!("{}", x); // -+ - try to borrow x here
-                   // -+ &mut borrow of x ends here
+fn main() {
+    let mut x = 5;
+
+    let y = &mut x;    // -+ &mut borrow of x starts here
+                       //  |
+    *y += 1;           //  |
+                       //  |
+    println!("{}", x); // -+ - try to borrow x here
+}                      // -+ &mut borrow of x ends here
+                       
 ```
 
 The scopes conflict: we can’t make an `&x` while `y` is in scope.
@@ -269,12 +273,12 @@ println!("{}", x);  // <- try to borrow x here
 ```
 
 There’s no problem. Our mutable borrow goes out of scope before we create an
-immutable one. But scope is the key to seeing how long a borrow lasts for.
+immutable one. So scope is the key to seeing how long a borrow lasts for.
 
 ## Issues borrowing prevents
 
 Why have these restrictive rules? Well, as we noted, these rules prevent data
-races. What kinds of issues do data races cause? Here’s a few.
+races. What kinds of issues do data races cause? Here are a few.
 
 ### Iterator invalidation
 
@@ -323,7 +327,7 @@ for i in &v {
 
 We can’t modify `v` because it’s borrowed by the loop.
 
-### use after free
+### Use after free
 
 References must not live longer than the resource they refer to. Rust will
 check the scopes of your references to ensure that this is true.
index 7be90e785b02b1772570a3cea24df89e83e09987..135778c38b50a2e8bc883b654a331da85389d3dc 100644 (file)
@@ -9,7 +9,7 @@ strings also work differently than in some other systems languages, such as C.
 Let’s dig into the details. A â€˜string’ is a sequence of Unicode scalar values
 encoded as a stream of UTF-8 bytes. All strings are guaranteed to be a valid
 encoding of UTF-8 sequences. Additionally, unlike some systems languages,
-strings are not null-terminated and can contain null bytes.
+strings are not NUL-terminated and can contain NUL bytes.
 
 Rust has two main types of strings: `&str` and `String`. Let’s talk about
 `&str` first. These are called â€˜string slices’. A string slice has a fixed
index af4e351569f7f55920fd2db72c6841682098fe1c..9cab586b82c4713d0ee73597876af5843733e945 100644 (file)
@@ -63,7 +63,7 @@ In addition, the following are all undefined behaviors in Rust, and must be
 avoided, even when writing `unsafe` code:
 
 * Data races
-* Dereferencing a null/dangling raw pointer
+* Dereferencing a NULL/dangling raw pointer
 * Reads of [undef][undef] (uninitialized) memory
 * Breaking the [pointer aliasing rules][aliasing] with raw pointers.
 * `&mut T` and `&T` follow LLVM’s scoped [noalias][noalias] model, except if
@@ -77,7 +77,7 @@ avoided, even when writing `unsafe` code:
   * Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
     intrinsics) on overlapping buffers
 * Invalid values in primitive types, even in private fields/locals:
-  * Null/dangling references or boxes
+  * NULL/dangling references or boxes
   * A value other than `false` (0) or `true` (1) in a `bool`
   * A discriminant in an `enum` not included in its type definition
   * A value in a `char` which is a surrogate or above `char::MAX`
index 06a83c75936fe4a44a6584b9cbf9e09b9a554d1c..b2bb7859661ab63aae27658359731647887741f9 100644 (file)
@@ -139,7 +139,7 @@ class Type(object):
             return TYPE_KIND_STR_SLICE
 
         # REGULAR SLICE
-        if (unqualified_type_name.startswith("&[") and
+        if (unqualified_type_name.startswith(("&[", "&mut [")) and
             unqualified_type_name.endswith("]") and
             self.__conforms_to_field_layout(SLICE_FIELD_NAMES)):
             return TYPE_KIND_SLICE
index 38c9fbf98281a1c42c66fb57782b74fa51f4fddd..33f22e8579664815349f342aa78794639de159e1 100755 (executable)
@@ -211,15 +211,12 @@ class RustSlicePrinter:
                 ("(len: %i)" % length))
 
     def children(self):
-        cs = []
         (length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(self.__val)
         assert data_ptr.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_PTR
         raw_ptr = data_ptr.get_wrapped_value()
 
         for index in range(0, length):
-            cs.append((str(index), (raw_ptr + index).dereference()))
-
-        return cs
+            yield (str(index), (raw_ptr + index).dereference())
 
 
 class RustStringSlicePrinter:
@@ -245,12 +242,10 @@ class RustStdVecPrinter:
                 ("(len: %i, cap: %i)" % (length, cap)))
 
     def children(self):
-        cs = []
         (length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(self.__val)
         gdb_ptr = data_ptr.get_wrapped_value()
         for index in range(0, length):
-            cs.append((str(index), (gdb_ptr + index).dereference()))
-        return cs
+            yield (str(index), (gdb_ptr + index).dereference())
 
 
 class RustStdStringPrinter:
index 79fd7699428895bf2191ba22f4bc1a062919c38a..c8cda4077b79075b4d32a3db7bddcab04b5d4dfd 100644 (file)
@@ -1,6 +1,6 @@
 {
-    "platform": "aarch64",
-    "intrinsic_prefix": "aarch64_v",
+    "platform": "aarch64_v",
+    "intrinsic_prefix": "",
     "llvm_prefix": "llvm.aarch64.neon.",
     "number_info": {
         "signed": {
index 97db7cbb3e0a52fce179bc7c904e4fc460844bba..39e49e239f34dfcc64e67a71933a0f89ec4037ed 100644 (file)
@@ -1,6 +1,6 @@
 {
-    "platform": "arm",
-    "intrinsic_prefix": "arm_v",
+    "platform": "arm_v",
+    "intrinsic_prefix": "",
     "llvm_prefix": "llvm.neon.v",
     "number_info": {
         "signed": {
index a21194962f9b061663203c969ce6c115b4bc097b..a4a91170efb3b5334e9f874a48240059a7f7d903 100644 (file)
@@ -26,10 +26,9 @@ SPEC = re.compile(
 class PlatformInfo(object):
     def __init__(self, json):
         self._platform = json['platform']
-        self._intrinsic_prefix = json['intrinsic_prefix']
 
-    def intrinsic_prefix(self):
-        return self._intrinsic_prefix
+    def platform_prefix(self):
+        return self._platform
 
 class IntrinsicSet(object):
     def __init__(self, platform, json):
@@ -38,6 +37,7 @@ class IntrinsicSet(object):
         self._intrinsics = json['intrinsics']
         self._widths = json['width_info']
         self._platform = platform
+        self._intrinsic_prefix = json['intrinsic_prefix']
 
     def intrinsics(self):
         for raw in self._intrinsics:
@@ -48,6 +48,9 @@ class IntrinsicSet(object):
     def platform(self):
         return self._platform
 
+    def intrinsic_prefix(self):
+        return self._intrinsic_prefix
+
     def llvm_prefix(self):
         return self._llvm_prefix
 
@@ -538,8 +541,14 @@ class MonomorphicIntrinsic(object):
                                       *self._args,
                                       width = self._width)
 
+    def platform_prefix(self):
+        return self._platform.platform().platform_prefix()
+
+    def intrinsic_set_name(self):
+        return self._platform.intrinsic_prefix()
+
     def intrinsic_name(self):
-        return self._platform.platform().intrinsic_prefix() + self.intrinsic_suffix()
+        return self._platform.intrinsic_prefix() + self.intrinsic_suffix()
 
     def compiler_args(self):
         return ', '.join(arg.compiler_ctor_ref() for arg in self._args_raw)
@@ -561,6 +570,27 @@ def parse_args():
         formatter_class = argparse.RawDescriptionHelpFormatter,
         description = 'Render an intrinsic definition JSON to various formats.',
         epilog = textwrap.dedent('''\
+        Quick How-To:
+
+        There are two operating modes: single file and multiple files.
+
+        For example, ARM is specified as a single file. To generate the
+        compiler-definitions for ARM just pass the script the "arm.json" file:
+
+        python generator.py --format compiler-defs arm.json
+
+        The X86 architecture is specified as multiple files (for the different
+        instruction sets that x86 supports). To generate the compiler
+        definitions one needs to pass the script a "platform information file"
+        (with the -i flag) next to the files of the different intruction sets.
+        For example, to generate the X86 compiler-definitions for SSE4.2, just:
+
+        python generator.py --format compiler-defs -i x86/info.json sse42.json
+
+        And to generate the compiler-definitions for SSE4.1 and SSE4.2, just:
+
+        python generator.py --format compiler-defs -i x86/info.json sse41.json sse42.json
+
         An intrinsic definition consists of a map with fields:
         - intrinsic: pattern for the name(s) of the vendor's C intrinsic(s)
         - llvm: pattern for the name(s) of the internal llvm intrinsic(s)
@@ -730,8 +760,9 @@ class ExternBlock(object):
         return 'extern "platform-intrinsic" {'
 
     def render(self, mono):
-        return '    fn {}{};'.format(mono.intrinsic_name(),
-                                     mono.intrinsic_signature())
+        return '    fn {}{}{};'.format(mono.platform_prefix(),
+                                       mono.intrinsic_name(),
+                                       mono.intrinsic_signature())
 
     def close(self):
         return '}'
@@ -765,7 +796,7 @@ use IntrinsicDef::Named;
 #[inline(never)]
 pub fn find(name: &str) -> Option<Intrinsic> {{
     if !name.starts_with("{0}") {{ return None }}
-    Some(match &name["{0}".len()..] {{'''.format(platform.intrinsic_prefix())
+    Some(match &name["{0}".len()..] {{'''.format(platform.platform_prefix())
 
     def render(self, mono):
         return '''\
@@ -773,7 +804,7 @@ pub fn find(name: &str) -> Option<Intrinsic> {{
             inputs: {{ static INPUTS: [&'static Type; {}] = [{}]; &INPUTS }},
             output: {},
             definition: Named("{}")
-        }},'''.format(mono.intrinsic_suffix(),
+        }},'''.format(mono.intrinsic_set_name() + mono.intrinsic_suffix(),
                       len(mono._args_raw),
                       mono.compiler_args(),
                       mono.compiler_ret(),
index 05a4721aed8340e0ce56a1513d899e33e68e2b46..1f41e2ecf3e6d29ba0eb6d4d7d52c981faf40d94 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.avx.",
     "intrinsics": [
         {
index e88ff3d2b806dbf1fe45b6b2448c84cd2bc2e893..4e006c1c4cf417c512e32a5c8582d5f86600f142 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.avx2.",
     "intrinsics": [
         {
diff --git a/src/etc/platform-intrinsics/x86/bmi.json b/src/etc/platform-intrinsics/x86/bmi.json
new file mode 100644 (file)
index 0000000..24e2cbc
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "intrinsic_prefix": "_bmi",
+    "llvm_prefix": "llvm.x86.bmi.",
+    "intrinsics": [
+        {
+            "intrinsic": "_bextr_{0.bitwidth}",
+            "width": ["0"],
+            "llvm": "bextr.{0.bitwidth}",
+            "ret": "S(32-64)u",
+            "args": ["0", "0"]
+        }
+    ]
+}
diff --git a/src/etc/platform-intrinsics/x86/bmi2.json b/src/etc/platform-intrinsics/x86/bmi2.json
new file mode 100644 (file)
index 0000000..f5a0db5
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "intrinsic_prefix": "_bmi2",
+    "llvm_prefix": "llvm.x86.bmi.",
+    "intrinsics": [
+        {
+            "intrinsic": "_bzhi_{0.bitwidth}",
+            "width": ["0"],
+            "llvm": "bzhi.{0.bitwidth}",
+            "ret": "S(32-64)u",
+            "args": ["0", "0"]
+        },
+        {
+            "intrinsic": "_pdep_{0.bitwidth}",
+            "width": ["0"],
+            "llvm": "pdep.{0.bitwidth}",
+            "ret": "S(32-64)u",
+            "args": ["0", "0"]
+        },
+        {
+            "intrinsic": "_pext_{0.bitwidth}",
+            "width": ["0"],
+            "llvm": "pext.{0.bitwidth}",
+            "ret": "S(32-64)u",
+            "args": ["0", "0"]
+        }
+    ]
+}
index c922d166c8fbc831758e8ab0e98a8036d7ca56a7..dcc26cd501c9bdbfaab71869e60baceba59f7663 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.fma.",
     "intrinsics": [
         {
index d48bcd268a0048fd87ee5635ea5f137fcd09dde9..8e90b8579c49ef996a33307d4903f6e95a4862f5 100644 (file)
@@ -1,26 +1,30 @@
 {
     "platform": "x86",
-    "intrinsic_prefix": "x86_mm",
     "number_info": {
         "signed": {
             "kind": "s",
             "kind_short": "",
             "data_type": { "pattern": "epi{bitwidth}" },
+            "bitwidth": { "pattern": "{bitwidth}" },
             "data_type_short": { "8": "b", "16": "w", "32": "d", "64": "q" }
         },
         "unsigned": {
             "kind": "u",
             "kind_short": "u",
             "data_type": { "pattern": "epu{bitwidth}" },
+            "bitwidth": { "pattern": "{bitwidth}" },
             "data_type_short": { "8": "b", "16": "w", "32": "d", "64": "q" }
         },
         "float": {
             "kind": "f",
             "data_type": { "32": "ps", "64": "pd" },
+            "bitwidth": { "pattern": "{bitwidth}" },
             "data_type_short": { "32": "ps", "64": "pd" }
         }
     },
     "width_info": {
+        "32":  { "width_mm": "32", "width_suffix": "" },
+        "64":  { "width_mm": "64", "width_suffix": "" },
         "128": { "width_mm": "", "width_suffix": "" },
         "256": { "width_mm": "256", "width_suffix": ".256" },
         "512": { "width_mm": "512", "width_suffix": ".512" }
index adff0dc41b2afd8221eb8f0a4dc7535a43c28790..d8eef8a3514aec7267107d6526dcdc214d596ad2 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.sse.",
     "intrinsics": [
         {
index d09980d95f31b8d09d73e503e4548cb298da9f0a..4d6317d80a57e306ce117902e31570b33c21bb83 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.sse2.",
     "intrinsics": [
         {
index ed13595929d1b24c752333eb702cfe638bee1e7e..119bf208f7e3437d48e8e143f982891da8c176e7 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.sse3.",
     "intrinsics": [
         {
index de792cd1060bbec74a67560efab31e9e743b9ec7..b499637e0d3c6f5046a5a3107c5da7cfaf2afacf 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.sse41.",
     "intrinsics": [
         {
index c43ffef0dc578cc7459be1fa520401ed880aba79..fdee9c8a6671b9e2d914185b6629da4da20be93c 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.sse42.",
     "intrinsics": [
         {
index af6afbb19a26d0669d852c7e78f12f0ef6e8252b..5a5617957b3e5b78597a0b4a86cadd3e4838d646 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "intrinsic_prefix": "_mm",
     "llvm_prefix": "llvm.x86.ssse3.",
     "intrinsics": [
         {
diff --git a/src/etc/platform-intrinsics/x86/tbm.json b/src/etc/platform-intrinsics/x86/tbm.json
new file mode 100644 (file)
index 0000000..d1322cd
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "intrinsic_prefix": "_tbm",
+    "llvm_prefix": "llvm.x86.tbm.",
+    "intrinsics": [
+        {
+            "intrinsic": "_bextri_u{0.bitwidth}",
+            "width": ["0"],
+            "llvm": "bextri.u{0.bitwidth}",
+            "ret": "S(32-64)u",
+            "args": ["0", "0"]
+        }
+    ]
+}
index 42902b06aee13637bc432039a93bcac16123de6b..f70ab65bce717044d448d893c445339268293795 100755 (executable)
 # Exit if anything fails
 set -e
 
+LLDB_VERSION=`lldb --version 2>/dev/null | head -1 | cut -d. -f1`
+
+if [ "$LLDB_VERSION" = "lldb-350" ]
+then
+    echo "***"
+       echo \
+"WARNING: This version of LLDB has known issues with Rust and cannot \
+display the contents of local variables!"
+    echo "***"
+fi
+
 # Create a tempfile containing the LLDB script we want to execute on startup
 TMPFILE=`mktemp /tmp/rust-lldb-commands.XXXXXX`
 
index 140801737bc4c28166a379584fc70edc32cb830b..b9f5c6fcab9092a3d4565c5980a82f65888ff664 100644 (file)
@@ -825,8 +825,6 @@ fn rebuild(&mut self) {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(binary_heap_append)]
-    ///
     /// use std::collections::BinaryHeap;
     ///
     /// let v = vec![-10, 1, 2, 3, 3];
@@ -840,9 +838,7 @@ fn rebuild(&mut self) {
     /// assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
     /// assert!(b.is_empty());
     /// ```
-    #[unstable(feature = "binary_heap_append",
-           reason = "needs to be audited",
-           issue = "32526")]
+    #[stable(feature = "binary_heap_append", since = "1.11.0")]
     pub fn append(&mut self, other: &mut Self) {
         if self.len() < other.len() {
             swap(self, other);
index 6ca0db68a88ce42a1c87330c47fe1b8a34b38dc5..37dbeb4eae17d6d61f7dad0929e8ae3c9830c72d 100644 (file)
@@ -15,6 +15,7 @@
 use core::clone::Clone;
 use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
 use core::convert::AsRef;
+use core::default::Default;
 use core::hash::{Hash, Hasher};
 use core::marker::Sized;
 use core::ops::Deref;
@@ -248,6 +249,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "default", since = "1.11.0")]
+impl<'a, B: ?Sized> Default for Cow<'a, B>
+    where B: ToOwned,
+          <B as ToOwned>::Owned: Default
+{
+    fn default() -> Cow<'a, B> {
+        Owned(<B as ToOwned>::Owned::default())
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned {
     #[inline]
index 3b775dc2865eea0b2cb9ba1ea83731592098c600..aea7a1c13a28171778b427920c78c8cd89d3a1d0 100644 (file)
@@ -559,7 +559,6 @@ pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
     /// # Examples
     ///
     /// ```
-    /// #![feature(btree_append)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut a = BTreeMap::new();
@@ -583,8 +582,7 @@ pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
     /// assert_eq!(a[&4], "e");
     /// assert_eq!(a[&5], "f");
     /// ```
-    #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2",
-               issue = "34152")]
+    #[stable(feature = "btree_append", since = "1.11.0")]
     pub fn append(&mut self, other: &mut Self) {
         // Do we have to append anything at all?
         if other.len() == 0 {
@@ -914,7 +912,6 @@ fn fix_right_edge(&mut self) {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(btree_split_off)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut a = BTreeMap::new();
@@ -936,9 +933,7 @@ fn fix_right_edge(&mut self) {
     /// assert_eq!(b[&17], "d");
     /// assert_eq!(b[&41], "e");
     /// ```
-    #[unstable(feature = "btree_split_off",
-               reason = "recently added as part of collections reform 2",
-               issue = "34152")]
+    #[stable(feature = "btree_split_off", since = "1.11.0")]
     pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self
         where K: Borrow<Q>
     {
index c47eb0b3fad457afed6967f39df3afc43ebbcd3c..0f885bc2950a6b3426778e7508445b286c76e47e 100644 (file)
@@ -551,7 +551,6 @@ pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
     /// # Examples
     ///
     /// ```
-    /// #![feature(btree_append)]
     /// use std::collections::BTreeSet;
     ///
     /// let mut a = BTreeSet::new();
@@ -575,8 +574,7 @@ pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
     /// assert!(a.contains(&4));
     /// assert!(a.contains(&5));
     /// ```
-    #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2",
-               issue = "34152")]
+    #[stable(feature = "btree_append", since = "1.11.0")]
     pub fn append(&mut self, other: &mut Self) {
         self.map.append(&mut other.map);
     }
@@ -589,7 +587,6 @@ pub fn append(&mut self, other: &mut Self) {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(btree_split_off)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut a = BTreeMap::new();
@@ -611,9 +608,7 @@ pub fn append(&mut self, other: &mut Self) {
     /// assert_eq!(b[&17], "d");
     /// assert_eq!(b[&41], "e");
     /// ```
-    #[unstable(feature = "btree_split_off",
-               reason = "recently added as part of collections reform 2",
-               issue = "34152")]
+    #[stable(feature = "btree_split_off", since = "1.11.0")]
     pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where T: Borrow<Q> {
         BTreeSet { map: self.map.split_off(key) }
     }
index 7ac01103d61fe8637c5f9c0046d0aaaaf4dda97e..f027d074cb6f0bc8175db50364576b4311b35122 100644 (file)
@@ -38,7 +38,6 @@
 #![feature(fmt_internals)]
 #![feature(heap_api)]
 #![feature(inclusive_range)]
-#![feature(iter_arith)]
 #![feature(lang_items)]
 #![feature(nonzero)]
 #![feature(pattern)]
index 6161bad7468c6c330efbabaf35ab697f6d6e0ad2..8ae63808f27404b9abdc4406b6eab7ef40b251f6 100644 (file)
 #![deny(warnings)]
 
 #![feature(binary_heap_extras)]
-#![feature(binary_heap_append)]
 #![feature(binary_heap_peek_mut)]
 #![feature(box_syntax)]
-#![feature(btree_append)]
-#![feature(btree_split_off)]
 #![feature(btree_range)]
 #![feature(collections)]
 #![feature(collections_bound)]
 #![feature(const_fn)]
 #![feature(fn_traits)]
 #![feature(enumset)]
-#![feature(iter_arith)]
 #![feature(linked_list_contains)]
 #![feature(pattern)]
 #![feature(rand)]
index 2700f016751dcd83fe279530e0f3a10a5ae392fd..9435be3b0124b60bfb1fd36be9842558548ba449 100644 (file)
@@ -238,7 +238,7 @@ pub fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
     /// This call borrows `Cell` mutably (at compile-time) which guarantees
     /// that we possess the only reference.
     #[inline]
-    #[unstable(feature = "cell_get_mut", issue = "33444")]
+    #[stable(feature = "cell_get_mut", since = "1.11.0")]
     pub fn get_mut(&mut self) -> &mut T {
         unsafe {
             &mut *self.value.get()
@@ -509,7 +509,7 @@ pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
     /// This call borrows `RefCell` mutably (at compile-time) so there is no
     /// need for dynamic checks.
     #[inline]
-    #[unstable(feature = "cell_get_mut", issue="33444")]
+    #[stable(feature = "cell_get_mut", since = "1.11.0")]
     pub fn get_mut(&mut self) -> &mut T {
         unsafe {
             &mut *self.value.get()
index 4ac134c2b59c8d9535d1b1d449809be809d449a4..895a679fc3dccf76b1d7efae56248e31733b3f54 100644 (file)
@@ -840,11 +840,8 @@ pub fn write(output: &mut Write, args: Arguments) -> Result {
     }
 
     // There can be only one trailing string piece left.
-    match pieces.next() {
-        Some(piece) => {
-            formatter.buf.write_str(*piece)?;
-        }
-        None => {}
+    if let Some(piece) = pieces.next() {
+        formatter.buf.write_str(*piece)?;
     }
 
     Ok(())
index 051eb974895ce7a59031e36c1edd33bc677050eb..9e3f7a4a84a814b318a9833f18fb6352fca5b1e3 100644 (file)
@@ -80,6 +80,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::sip::SipHasher;
 
+#[unstable(feature = "sip_hash_13", issue = "29754")]
+pub use self::sip::{SipHasher13, SipHasher24};
+
 mod sip;
 
 /// A hashable type.
index fd1dab7a1f043b141cf6367ed980c1a3b2cf4a4b..c52c0b0730be785d8d8aad84bdd68577df4023e3 100644 (file)
@@ -8,12 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! An implementation of SipHash 2-4.
+//! An implementation of SipHash.
 
 use prelude::v1::*;
 
+use marker::PhantomData;
 use ptr;
-use super::Hasher;
+
+/// An implementation of SipHash 1-3.
+///
+/// See: https://131002.net/siphash/
+#[unstable(feature = "sip_hash_13", issue = "29754")]
+#[derive(Debug, Clone, Default)]
+pub struct SipHasher13 {
+    hasher: Hasher<Sip13Rounds>,
+}
+
+/// An implementation of SipHash 2-4.
+///
+/// See: https://131002.net/siphash/
+#[unstable(feature = "sip_hash_13", issue = "29754")]
+#[derive(Debug, Clone, Default)]
+pub struct SipHasher24 {
+    hasher: Hasher<Sip24Rounds>,
+}
 
 /// An implementation of SipHash 2-4.
 ///
 /// Although the SipHash algorithm is considered to be generally strong,
 /// it is not intended for cryptographic purposes. As such, all
 /// cryptographic uses of this implementation are _strongly discouraged_.
-#[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct SipHasher {
+#[derive(Debug, Clone, Default)]
+pub struct SipHasher(SipHasher24);
+
+#[derive(Debug)]
+struct Hasher<S: Sip> {
     k0: u64,
     k1: u64,
     length: usize, // how many bytes we've processed
+    state: State, // hash State
+    tail: u64, // unprocessed bytes le
+    ntail: usize, // how many bytes in tail are valid
+    _marker: PhantomData<S>,
+}
+
+#[derive(Debug, Clone, Copy)]
+struct State {
     // v0, v2 and v1, v3 show up in pairs in the algorithm,
     // and simd implementations of SipHash will use vectors
     // of v02 and v13. By placing them in this order in the struct,
     // the compiler can pick up on just a few simd optimizations by itself.
-    v0: u64, // hash state
+    v0: u64,
     v2: u64,
     v1: u64,
     v3: u64,
-    tail: u64, // unprocessed bytes le
-    ntail: usize, // how many bytes in tail are valid
 }
 
 // sadly, these macro definitions can't appear later,
@@ -93,6 +120,9 @@ macro_rules! rotl {
 }
 
 macro_rules! compress {
+    ($state:expr) => ({
+        compress!($state.v0, $state.v1, $state.v2, $state.v3)
+    });
     ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
     ({
         $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
@@ -101,7 +131,7 @@ macro_rules! compress {
         $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
         $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
         $v2 = rotl!($v2, 32);
-    })
+    });
 }
 
 impl SipHasher {
@@ -116,16 +146,63 @@ pub fn new() -> SipHasher {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
-        let mut state = SipHasher {
+        SipHasher(SipHasher24::new_with_keys(key0, key1))
+    }
+}
+
+
+impl SipHasher13 {
+    /// Creates a new `SipHasher13` with the two initial keys set to 0.
+    #[inline]
+    #[unstable(feature = "sip_hash_13", issue = "29754")]
+    pub fn new() -> SipHasher13 {
+        SipHasher13::new_with_keys(0, 0)
+    }
+
+    /// Creates a `SipHasher13` that is keyed off the provided keys.
+    #[inline]
+    #[unstable(feature = "sip_hash_13", issue = "29754")]
+    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
+        SipHasher13 {
+            hasher: Hasher::new_with_keys(key0, key1)
+        }
+    }
+}
+
+impl SipHasher24 {
+    /// Creates a new `SipHasher24` with the two initial keys set to 0.
+    #[inline]
+    #[unstable(feature = "sip_hash_13", issue = "29754")]
+    pub fn new() -> SipHasher24 {
+        SipHasher24::new_with_keys(0, 0)
+    }
+
+    /// Creates a `SipHasher24` that is keyed off the provided keys.
+    #[inline]
+    #[unstable(feature = "sip_hash_13", issue = "29754")]
+    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {
+        SipHasher24 {
+            hasher: Hasher::new_with_keys(key0, key1)
+        }
+    }
+}
+
+impl<S: Sip> Hasher<S> {
+    #[inline]
+    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
+        let mut state = Hasher {
             k0: key0,
             k1: key1,
             length: 0,
-            v0: 0,
-            v1: 0,
-            v2: 0,
-            v3: 0,
+            state: State {
+                v0: 0,
+                v1: 0,
+                v2: 0,
+                v3: 0,
+            },
             tail: 0,
             ntail: 0,
+            _marker: PhantomData,
         };
         state.reset();
         state
@@ -134,16 +211,54 @@ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
     #[inline]
     fn reset(&mut self) {
         self.length = 0;
-        self.v0 = self.k0 ^ 0x736f6d6570736575;
-        self.v1 = self.k1 ^ 0x646f72616e646f6d;
-        self.v2 = self.k0 ^ 0x6c7967656e657261;
-        self.v3 = self.k1 ^ 0x7465646279746573;
+        self.state.v0 = self.k0 ^ 0x736f6d6570736575;
+        self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
+        self.state.v2 = self.k0 ^ 0x6c7967656e657261;
+        self.state.v3 = self.k1 ^ 0x7465646279746573;
         self.ntail = 0;
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Hasher for SipHasher {
+impl super::Hasher for SipHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.0.write(msg)
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.0.finish()
+    }
+}
+
+#[unstable(feature = "sip_hash_13", issue = "29754")]
+impl super::Hasher for SipHasher13 {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.hasher.write(msg)
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.hasher.finish()
+    }
+}
+
+#[unstable(feature = "sip_hash_13", issue = "29754")]
+impl super::Hasher for SipHasher24 {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.hasher.write(msg)
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.hasher.finish()
+    }
+}
+
+impl<S: Sip> super::Hasher for Hasher<S> {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
@@ -161,10 +276,9 @@ fn write(&mut self, msg: &[u8]) {
 
             let m = self.tail | u8to64_le!(msg, 0, needed) << 8 * self.ntail;
 
-            self.v3 ^= m;
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            self.v0 ^= m;
+            self.state.v3 ^= m;
+            S::c_rounds(&mut self.state);
+            self.state.v0 ^= m;
 
             self.ntail = 0;
         }
@@ -177,10 +291,9 @@ fn write(&mut self, msg: &[u8]) {
         while i < len - left {
             let mi = unsafe { load_u64_le(msg, i) };
 
-            self.v3 ^= mi;
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            self.v0 ^= mi;
+            self.state.v3 ^= mi;
+            S::c_rounds(&mut self.state);
+            self.state.v0 ^= mi;
 
             i += 8;
         }
@@ -191,49 +304,81 @@ fn write(&mut self, msg: &[u8]) {
 
     #[inline]
     fn finish(&self) -> u64 {
-        let mut v0 = self.v0;
-        let mut v1 = self.v1;
-        let mut v2 = self.v2;
-        let mut v3 = self.v3;
+        let mut state = self.state;
 
         let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
 
-        v3 ^= b;
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        v0 ^= b;
+        state.v3 ^= b;
+        S::c_rounds(&mut state);
+        state.v0 ^= b;
 
-        v2 ^= 0xff;
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
+        state.v2 ^= 0xff;
+        S::d_rounds(&mut state);
 
-        v0 ^ v1 ^ v2 ^ v3
+        state.v0 ^ state.v1 ^ state.v2 ^ state.v3
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for SipHasher {
+impl<S: Sip> Clone for Hasher<S> {
     #[inline]
-    fn clone(&self) -> SipHasher {
-        SipHasher {
+    fn clone(&self) -> Hasher<S> {
+        Hasher {
             k0: self.k0,
             k1: self.k1,
             length: self.length,
-            v0: self.v0,
-            v1: self.v1,
-            v2: self.v2,
-            v3: self.v3,
+            state: self.state,
             tail: self.tail,
             ntail: self.ntail,
+            _marker: self._marker,
         }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Default for SipHasher {
-    fn default() -> SipHasher {
-        SipHasher::new()
+impl<S: Sip> Default for Hasher<S> {
+    #[inline]
+    fn default() -> Hasher<S> {
+        Hasher::new_with_keys(0, 0)
+    }
+}
+
+#[doc(hidden)]
+trait Sip {
+    fn c_rounds(&mut State);
+    fn d_rounds(&mut State);
+}
+
+#[derive(Debug, Clone, Default)]
+struct Sip13Rounds;
+
+impl Sip for Sip13Rounds {
+    #[inline]
+    fn c_rounds(state: &mut State) {
+        compress!(state);
+    }
+
+    #[inline]
+    fn d_rounds(state: &mut State) {
+        compress!(state);
+        compress!(state);
+        compress!(state);
+    }
+}
+
+#[derive(Debug, Clone, Default)]
+struct Sip24Rounds;
+
+impl Sip for Sip24Rounds {
+    #[inline]
+    fn c_rounds(state: &mut State) {
+        compress!(state);
+        compress!(state);
+    }
+
+    #[inline]
+    fn d_rounds(state: &mut State) {
+        compress!(state);
+        compress!(state);
+        compress!(state);
+        compress!(state);
     }
 }
index edb965c1962e3bf6433b487165f8d164c39616e4..94baf188bcaeea9d28f582e6071fed9eb30c8afc 100644 (file)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn transmute<T, U>(e: T) -> U;
 
+    /// Gives the address for the return value of the enclosing function.
+    ///
+    /// Using this intrinsic in a function that does not use an out pointer
+    /// will trigger a compiler error.
+    pub fn return_address() -> *const u8;
+
     /// Returns `true` if the actual type given as `T` requires drop
     /// glue; returns `false` if the actual type provided for `T`
     /// implements `Copy`.
index 6f5bb2747df8f251a2b4cf809b0135d8d8b88d74..6b01ccaceea2f31c3726597244a23ccefdda2fc1 100644 (file)
 use clone::Clone;
 use cmp::{Ord, PartialOrd, PartialEq, Ordering};
 use default::Default;
-use num::{Zero, One};
-use ops::{Add, FnMut, Mul};
+use ops::FnMut;
 use option::Option::{self, Some, None};
 use marker::Sized;
 
-use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse,
-            Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev,
-            Zip};
+use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse};
+use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev};
+use super::{Zip, Sum, Product};
 use super::ChainState;
-use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator,
-            IntoIterator};
-use super::ZipImpl;
+use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator};
+use super::{IntoIterator, ZipImpl};
 
 fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 
@@ -1820,36 +1818,41 @@ fn cycle(self) -> Cycle<Self> where Self: Sized + Clone {
     ///
     /// An empty iterator returns the zero value of the type.
     ///
+    /// # Panics
+    ///
+    /// When calling `sum` and a primitive integer type is being returned, this
+    /// method will panic if the computation overflows.
+    ///
     /// # Examples
     ///
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_arith)]
-    ///
     /// let a = [1, 2, 3];
     /// let sum: i32 = a.iter().sum();
     ///
     /// assert_eq!(sum, 6);
     /// ```
-    #[unstable(feature = "iter_arith", reason = "bounds recently changed",
-               issue = "27739")]
-    fn sum<S>(self) -> S where
-        S: Add<Self::Item, Output=S> + Zero,
-        Self: Sized,
+    #[stable(feature = "iter_arith", since = "1.11.0")]
+    fn sum<S>(self) -> S
+        where Self: Sized,
+              S: Sum<Self::Item>,
     {
-        self.fold(Zero::zero(), |s, e| s + e)
+        Sum::sum(self)
     }
 
     /// Iterates over the entire iterator, multiplying all the elements
     ///
     /// An empty iterator returns the one value of the type.
     ///
+    /// # Panics
+    ///
+    /// When calling `product` and a primitive integer type is being returned,
+    /// this method will panic if the computation overflows.
+    ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(iter_arith)]
-    ///
     /// fn factorial(n: u32) -> u32 {
     ///     (1..).take_while(|&i| i <= n).product()
     /// }
@@ -1857,13 +1860,12 @@ fn sum<S>(self) -> S where
     /// assert_eq!(factorial(1), 1);
     /// assert_eq!(factorial(5), 120);
     /// ```
-    #[unstable(feature="iter_arith", reason = "bounds recently changed",
-               issue = "27739")]
-    fn product<P>(self) -> P where
-        P: Mul<Self::Item, Output=P> + One,
-        Self: Sized,
+    #[stable(feature = "iter_arith", since = "1.11.0")]
+    fn product<P>(self) -> P
+        where Self: Sized,
+              P: Product<Self::Item>,
     {
-        self.fold(One::one(), |p, e| p * e)
+        Product::product(self)
     }
 
     /// Lexicographically compares the elements of this `Iterator` with those
index b866655bbd53d1b24688357e1e213b4171112731..3ebab266e2ffed5494cc069a90172e64833f9b83 100644 (file)
 pub use self::sources::{Once, once};
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend,
-                       ExactSizeIterator};
+pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::traits::{ExactSizeIterator, Sum, Product};
 
 mod iterator;
 mod range;
index 08143567beaf3892cfb82ff66ab5ab94c531fed8..c234ef21db6d12878e09e722ed507d058948a42a 100644 (file)
@@ -11,7 +11,6 @@
 use clone::Clone;
 use cmp::PartialOrd;
 use mem;
-use num::{Zero, One};
 use ops::{self, Add, Sub};
 use option::Option::{self, Some, None};
 use marker::Sized;
@@ -36,6 +35,24 @@ pub trait Step: PartialOrd + Sized {
     /// Returns `None` if it is not possible to calculate `steps_between`
     /// without overflow.
     fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
+
+    /// Same as `steps_between`, but with a `by` of 1
+    fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize>;
+
+    /// Tests whether this step is negative or not (going backwards)
+    fn is_negative(&self) -> bool;
+
+    /// Replaces this step with `1`, returning itself
+    fn replace_one(&mut self) -> Self;
+
+    /// Replaces this step with `0`, returning itself
+    fn replace_zero(&mut self) -> Self;
+
+    /// Adds one to this step, returning the result
+    fn add_one(&self) -> Self;
+
+    /// Subtracts one to this step, returning the result
+    fn sub_one(&self) -> Self;
 }
 
 macro_rules! step_impl_unsigned {
@@ -65,6 +82,36 @@ fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
                     Some(0)
                 }
             }
+
+            #[inline]
+            fn is_negative(&self) -> bool {
+                false
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -106,6 +153,36 @@ fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
                     Some(diff / by_u)
                 }
             }
+
+            #[inline]
+            fn is_negative(&self) -> bool {
+                *self < 0
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -124,6 +201,37 @@ fn step(&self, by: &$t) -> Option<$t> {
             fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
                 None
             }
+
+            #[inline]
+            #[allow(unused_comparisons)]
+            fn is_negative(&self) -> bool {
+                *self < 0
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -269,12 +377,12 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
+impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let rev = self.step_by < A::zero();
+        let rev = self.step_by.is_negative();
         if (rev && self.range.start > self.range.end) ||
            (!rev && self.range.start < self.range.end)
         {
@@ -308,7 +416,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 #[unstable(feature = "inclusive_range",
            reason = "recently added, follows RFC",
            issue = "28237")]
-impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
+impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
     type Item = A;
 
     #[inline]
@@ -322,8 +430,7 @@ fn next(&mut self) -> Option<A> {
             Empty { .. } => return None, // empty iterators yield no values
 
             NonEmpty { ref mut start, ref mut end } => {
-                let zero = A::zero();
-                let rev = self.step_by < zero;
+                let rev = self.step_by.is_negative();
 
                 // march start towards (maybe past!) end and yield the old value
                 if (rev && start >= end) ||
@@ -342,7 +449,7 @@ fn next(&mut self) -> Option<A> {
                     }
                 } else {
                     // found range in inconsistent state (start at or past end), so become empty
-                    (Some(mem::replace(end, zero)), None)
+                    (Some(end.replace_zero()), None)
                 }
             }
         };
@@ -386,7 +493,7 @@ impl ExactSizeIterator for ops::RangeInclusive<$t> { }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One> Iterator for ops::Range<A> where
+impl<A: Step> Iterator for ops::Range<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
@@ -394,7 +501,7 @@ impl<A: Step + One> Iterator for ops::Range<A> where
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.start < self.end {
-            let mut n = &self.start + &A::one();
+            let mut n = self.start.add_one();
             mem::swap(&mut n, &mut self.start);
             Some(n)
         } else {
@@ -404,7 +511,7 @@ fn next(&mut self) -> Option<A> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        match Step::steps_between(&self.start, &self.end, &A::one()) {
+        match Step::steps_between_by_one(&self.start, &self.end) {
             Some(hint) => (hint, Some(hint)),
             None => (0, None)
         }
@@ -416,14 +523,14 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
+impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
     for<'a> &'a A: Add<&'a A, Output = A>,
     for<'a> &'a A: Sub<&'a A, Output = A>
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         if self.start < self.end {
-            self.end = &self.end - &A::one();
+            self.end = self.end.sub_one();
             Some(self.end.clone())
         } else {
             None
@@ -432,21 +539,21 @@ fn next_back(&mut self) -> Option<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One> Iterator for ops::RangeFrom<A> where
+impl<A: Step> Iterator for ops::RangeFrom<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let mut n = &self.start + &A::one();
+        let mut n = self.start.add_one();
         mem::swap(&mut n, &mut self.start);
         Some(n)
     }
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<A: Step + One> Iterator for ops::RangeInclusive<A> where
+impl<A: Step> Iterator for ops::RangeInclusive<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
@@ -463,23 +570,22 @@ fn next(&mut self) -> Option<A> {
 
             NonEmpty { ref mut start, ref mut end } => {
                 if start == end {
-                    (Some(mem::replace(end, A::one())), Some(mem::replace(start, A::one())))
+                    (Some(end.replace_one()), Some(start.replace_one()))
                 } else if start < end {
-                    let one = A::one();
-                    let mut n = &*start + &one;
+                    let mut n = start.add_one();
                     mem::swap(&mut n, start);
 
-                    // if the iterator is done iterating, it will change from NonEmpty to Empty
-                    // to avoid unnecessary drops or clones, we'll reuse either start or end
-                    // (they are equal now, so it doesn't matter which)
-                    // to pull out end, we need to swap something back in -- use the previously
-                    // created A::one() as a dummy value
+                    // if the iterator is done iterating, it will change from
+                    // NonEmpty to Empty to avoid unnecessary drops or clones,
+                    // we'll reuse either start or end (they are equal now, so
+                    // it doesn't matter which) to pull out end, we need to swap
+                    // something back in
 
-                    (if n == *end { Some(mem::replace(end, one)) } else { None },
+                    (if n == *end { Some(end.replace_one()) } else { None },
                     // ^ are we done yet?
                     Some(n)) // < the value to output
                 } else {
-                    (Some(mem::replace(start, A::one())), None)
+                    (Some(start.replace_one()), None)
                 }
             }
         };
@@ -500,7 +606,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
             Empty { .. } => (0, Some(0)),
 
             NonEmpty { ref start, ref end } =>
-                match Step::steps_between(start, end, &A::one()) {
+                match Step::steps_between_by_one(start, end) {
                     Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
                     None => (0, None),
                 }
@@ -509,7 +615,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<A: Step + One> DoubleEndedIterator for ops::RangeInclusive<A> where
+impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
     for<'a> &'a A: Add<&'a A, Output = A>,
     for<'a> &'a A: Sub<&'a A, Output = A>
 {
@@ -524,16 +630,15 @@ fn next_back(&mut self) -> Option<A> {
 
             NonEmpty { ref mut start, ref mut end } => {
                 if start == end {
-                    (Some(mem::replace(start, A::one())), Some(mem::replace(end, A::one())))
+                    (Some(start.replace_one()), Some(end.replace_one()))
                 } else if start < end {
-                    let one = A::one();
-                    let mut n = &*end - &one;
+                    let mut n = end.sub_one();
                     mem::swap(&mut n, end);
 
-                    (if n == *start { Some(mem::replace(start, one)) } else { None },
+                    (if n == *start { Some(start.replace_one()) } else { None },
                      Some(n))
                 } else {
-                    (Some(mem::replace(end, A::one())), None)
+                    (Some(end.replace_one()), None)
                 }
             }
         };
index 67503984450a45806a3af0bd1f8667397269a058..3549bd6a3bc68f4fcfa52cab27ed36a9817b5378 100644 (file)
@@ -524,3 +524,104 @@ fn len(&self) -> usize {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {}
 
+/// Trait to represent types that can be created by summing up an iterator.
+///
+/// This trait is used to implement the `sum` method on iterators. Types which
+/// implement the trait can be generated by the `sum` method. Like
+/// `FromIterator` this trait should rarely be called directly and instead
+/// interacted with through `Iterator::sum`.
+#[unstable(feature = "iter_arith_traits", issue = "34529")]
+pub trait Sum<A = Self>: Sized {
+    /// Method which takes an iterator and generates `Self` from the elements by
+    /// "summing up" the items.
+    fn sum<I: Iterator<Item=A>>(iter: I) -> Self;
+}
+
+/// Trait to represent types that can be created by multiplying elements of an
+/// iterator.
+///
+/// This trait is used to implement the `product` method on iterators. Types
+/// which implement the trait can be generated by the `product` method. Like
+/// `FromIterator` this trait should rarely be called directly and instead
+/// interacted with through `Iterator::product`.
+#[unstable(feature = "iter_arith_traits", issue = "34529")]
+pub trait Product<A = Self>: Sized {
+    /// Method which takes an iterator and generates `Self` from the elements by
+    /// multiplying the items.
+    fn product<I: Iterator<Item=A>>(iter: I) -> Self;
+}
+
+macro_rules! integer_sum_product {
+    ($($a:ident)*) => ($(
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Sum for $a {
+            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(0, |a, b| {
+                    a.checked_add(b).expect("overflow in sum")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Product for $a {
+            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(1, |a, b| {
+                    a.checked_mul(b).expect("overflow in product")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Sum<&'a $a> for $a {
+            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(0, |a, b| {
+                    a.checked_add(*b).expect("overflow in sum")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Product<&'a $a> for $a {
+            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(1, |a, b| {
+                    a.checked_mul(*b).expect("overflow in product")
+                })
+            }
+        }
+    )*)
+}
+
+macro_rules! float_sum_product {
+    ($($a:ident)*) => ($(
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Sum for $a {
+            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(0.0, |a, b| a + b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Product for $a {
+            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(1.0, |a, b| a * b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Sum<&'a $a> for $a {
+            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(0.0, |a, b| a + *b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Product<&'a $a> for $a {
+            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(1.0, |a, b| a * *b)
+            }
+        }
+    )*)
+}
+
+integer_sum_product! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+float_sum_product! { f32 f64 }
index db73f4759a5ffcd368d38646b35e8a65d6c49a95..e849369d647c4754967d63f3d7cd627ae0fc8929 100644 (file)
@@ -59,6 +59,8 @@
 #![deny(missing_debug_implementations)]
 #![cfg_attr(not(stage0), deny(warnings))]
 
+#![cfg_attr(stage0, allow(unused_attributes))]
+
 #![feature(allow_internal_unstable)]
 #![feature(asm)]
 #![feature(associated_type_defaults)]
index c7af46a1e4f6ba62e5598baaf1800f7606654120..4761727cec03ff93594b2fb4d706c960ba99479a 100644 (file)
@@ -321,7 +321,7 @@ pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T {
             return underflow(x, v, rem);
         }
         if k > T::max_exp_int() {
-            return T::infinity();
+            return T::infinity2();
         }
         if x < min_sig {
             u.mul_pow2(1);
index 022bd84f4c8417e3ef352a0f493f618b4de0749b..ff2d85307b1060ef6cb2c5a2bcc619a80fe2b7f5 100644 (file)
@@ -215,11 +215,11 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
     let (sign, s) = extract_sign(s);
     let flt = match parse_decimal(s) {
         ParseResult::Valid(decimal) => convert(decimal)?,
-        ParseResult::ShortcutToInf => T::infinity(),
-        ParseResult::ShortcutToZero => T::zero(),
+        ParseResult::ShortcutToInf => T::infinity2(),
+        ParseResult::ShortcutToZero => T::zero2(),
         ParseResult::Invalid => match s {
-            "inf" => T::infinity(),
-            "NaN" => T::nan(),
+            "inf" => T::infinity2(),
+            "NaN" => T::nan2(),
             _ => { return Err(pfe_invalid()); }
         }
     };
@@ -316,7 +316,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
 fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
     // There were zeros but they were stripped by simplify()
     if decimal.integral.is_empty() && decimal.fractional.is_empty() {
-        return Some(T::zero());
+        return Some(T::zero2());
     }
     // This is a crude approximation of ceil(log10(the real value)). We don't need to worry too
     // much about overflow here because the input length is tiny (at least compared to 2^64) and
@@ -324,9 +324,9 @@ fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
     // (which is still 10^19 short of 2^64).
     let max_place = decimal.exp + decimal.integral.len() as i64;
     if max_place > T::inf_cutoff() {
-        return Some(T::infinity());
+        return Some(T::infinity2());
     } else if max_place < T::zero_cutoff() {
-        return Some(T::zero());
+        return Some(T::zero2());
     }
     None
 }
index 2099c6a7baa7649960065f6688d4fae745339368..68e4dc4b359efa73fb3ee5373004d569f756fcd9 100644 (file)
@@ -61,6 +61,27 @@ pub fn new(sig: u64, k: i16) -> Self {
 pub trait RawFloat : Float + Copy + Debug + LowerExp
                     + Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self>
 {
+    // suffix of "2" because Float::infinity is deprecated
+    #[allow(deprecated)]
+    fn infinity2() -> Self {
+        Float::infinity()
+    }
+
+    // suffix of "2" because Float::nan is deprecated
+    #[allow(deprecated)]
+    fn nan2() -> Self {
+        Float::nan()
+    }
+
+    // suffix of "2" because Float::zero is deprecated
+    fn zero2() -> Self;
+
+    // suffix of "2" because Float::integer_decode is deprecated
+    #[allow(deprecated)]
+    fn integer_decode2(self) -> (u64, i16, i8) {
+        Float::integer_decode(self)
+    }
+
     /// Get the raw binary representation of the float.
     fn transmute(self) -> u64;
 
@@ -146,6 +167,10 @@ fn min_sig() -> u64 {
 }
 
 impl RawFloat for f32 {
+    fn zero2() -> Self {
+        0.0
+    }
+
     fn sig_bits() -> u8 {
         24
     }
@@ -169,7 +194,7 @@ fn from_bits(bits: u64) -> f32 {
     }
 
     fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
+        let (sig, exp, _sig) = self.integer_decode2();
         Unpacked::new(sig, exp)
     }
 
@@ -198,6 +223,10 @@ fn zero_cutoff() -> i64 {
 
 
 impl RawFloat for f64 {
+    fn zero2() -> Self {
+        0.0
+    }
+
     fn sig_bits() -> u8 {
         53
     }
@@ -220,7 +249,7 @@ fn from_bits(bits: u64) -> f64 {
     }
 
     fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
+        let (sig, exp, _sig) = self.integer_decode2();
         Unpacked::new(sig, exp)
     }
 
@@ -351,7 +380,7 @@ pub fn prev_float<T: RawFloat>(x: T) -> T {
 pub fn next_float<T: RawFloat>(x: T) -> T {
     match x.classify() {
         Nan => panic!("next_float: argument is NaN"),
-        Infinite => T::infinity(),
+        Infinite => T::infinity2(),
         // This seems too good to be true, but it works.
         // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
         // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
index c24eaa3eabc754956e1ef4027328b813632b941e..79e1462eaa135eb58013a157fb584f6823b5485f 100644 (file)
@@ -168,7 +168,7 @@ fn is_nan(self) -> bool { self != self }
     /// Returns `true` if the number is infinite.
     #[inline]
     fn is_infinite(self) -> bool {
-        self == Float::infinity() || self == Float::neg_infinity()
+        self == INFINITY || self == NEG_INFINITY
     }
 
     /// Returns `true` if the number is neither infinite or NaN.
@@ -230,7 +230,7 @@ fn abs(self) -> f32 {
     #[inline]
     fn signum(self) -> f32 {
         if self.is_nan() {
-            Float::nan()
+            NAN
         } else {
             unsafe { intrinsics::copysignf32(1.0, self) }
         }
@@ -240,14 +240,14 @@ fn signum(self) -> f32 {
     /// `Float::infinity()`.
     #[inline]
     fn is_sign_positive(self) -> bool {
-        self > 0.0 || (1.0 / self) == Float::infinity()
+        self > 0.0 || (1.0 / self) == INFINITY
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
     fn is_sign_negative(self) -> bool {
-        self < 0.0 || (1.0 / self) == Float::neg_infinity()
+        self < 0.0 || (1.0 / self) == NEG_INFINITY
     }
 
     /// Returns the reciprocal (multiplicative inverse) of the number.
index beeee80902525f16c0684bda05e2debc1832d99f..35557f61c45420b5ff291aa369876a63e94be7aa 100644 (file)
@@ -168,7 +168,7 @@ fn is_nan(self) -> bool { self != self }
     /// Returns `true` if the number is infinite.
     #[inline]
     fn is_infinite(self) -> bool {
-        self == Float::infinity() || self == Float::neg_infinity()
+        self == INFINITY || self == NEG_INFINITY
     }
 
     /// Returns `true` if the number is neither infinite or NaN.
@@ -230,7 +230,7 @@ fn abs(self) -> f64 {
     #[inline]
     fn signum(self) -> f64 {
         if self.is_nan() {
-            Float::nan()
+            NAN
         } else {
             unsafe { intrinsics::copysignf64(1.0, self) }
         }
@@ -240,14 +240,14 @@ fn signum(self) -> f64 {
     /// `Float::infinity()`.
     #[inline]
     fn is_sign_positive(self) -> bool {
-        self > 0.0 || (1.0 / self) == Float::infinity()
+        self > 0.0 || (1.0 / self) == INFINITY
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
     fn is_sign_negative(self) -> bool {
-        self < 0.0 || (1.0 / self) == Float::neg_infinity()
+        self < 0.0 || (1.0 / self) == NEG_INFINITY
     }
 
     /// Returns the reciprocal (multiplicative inverse) of the number.
index 6265691bde9e9ff278c1d73aa50b76d02653b4ca..5420e7bdd2a5a064092b398387c89ec884c97c6b 100644 (file)
@@ -13,7 +13,8 @@
 use prelude::v1::*;
 
 use {f32, f64};
-use num::{Float, FpCategory};
+use num::FpCategory;
+use num::dec2flt::rawfp::RawFloat;
 
 /// Decoded unsigned finite value, such that:
 ///
@@ -52,7 +53,7 @@ pub enum FullDecoded {
 }
 
 /// A floating point type which can be `decode`d.
-pub trait DecodableFloat: Float + Copy {
+pub trait DecodableFloat: RawFloat + Copy {
     /// The minimum positive normalized value.
     fn min_pos_norm_value() -> Self;
 }
@@ -68,7 +69,7 @@ fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE }
 /// Returns a sign (true when negative) and `FullDecoded` value
 /// from given floating point number.
 pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
-    let (mant, exp, sign) = v.integer_decode();
+    let (mant, exp, sign) = v.integer_decode2();
     let even = (mant & 1) == 0;
     let decoded = match v.classify() {
         FpCategory::Nan => FullDecoded::Nan,
@@ -82,7 +83,7 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
                                           exp: exp, inclusive: even })
         }
         FpCategory::Normal => {
-            let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode();
+            let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode2();
             if mant == minnorm.0 {
                 // neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
                 // where maxmant = minnormmant * 2 - 1
index 06398fc094e8584fcf1704ff645c3cc456414e31..0d79398a8f1d51bd26e975a0a45fe16fe5b58aab 100644 (file)
@@ -109,6 +109,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[unstable(feature = "zero_one",
            reason = "unsure of placement, wants to use associated constants",
            issue = "27739")]
+#[rustc_deprecated(since = "1.11.0", reason = "no longer used for \
+                                               Iterator::sum")]
 pub trait Zero: Sized {
     /// The "zero" (usually, additive identity) for this type.
     fn zero() -> Self;
@@ -121,6 +123,8 @@ pub trait Zero: Sized {
 #[unstable(feature = "zero_one",
            reason = "unsure of placement, wants to use associated constants",
            issue = "27739")]
+#[rustc_deprecated(since = "1.11.0", reason = "no longer used for \
+                                               Iterator::product")]
 pub trait One: Sized {
     /// The "one" (usually, multiplicative identity) for this type.
     fn one() -> Self;
@@ -131,6 +135,7 @@ macro_rules! zero_one_impl {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl Zero for $t {
             #[inline]
             fn zero() -> Self { 0 }
@@ -138,6 +143,7 @@ fn zero() -> Self { 0 }
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl One for $t {
             #[inline]
             fn one() -> Self { 1 }
@@ -151,6 +157,7 @@ macro_rules! zero_one_impl_float {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl Zero for $t {
             #[inline]
             fn zero() -> Self { 0.0 }
@@ -158,6 +165,7 @@ fn zero() -> Self { 0.0 }
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl One for $t {
             #[inline]
             fn one() -> Self { 1.0 }
@@ -604,7 +612,7 @@ pub fn checked_shr(self, rhs: u32) -> Option<Self> {
         pub fn saturating_add(self, other: Self) -> Self {
             match self.checked_add(other) {
                 Some(x) => x,
-                None if other >= Self::zero() => Self::max_value(),
+                None if other >= 0 => Self::max_value(),
                 None => Self::min_value(),
             }
         }
@@ -625,7 +633,7 @@ pub fn saturating_add(self, other: Self) -> Self {
         pub fn saturating_sub(self, other: Self) -> Self {
             match self.checked_sub(other) {
                 Some(x) => x,
-                None if other >= Self::zero() => Self::min_value(),
+                None if other >= 0 => Self::min_value(),
                 None => Self::max_value(),
             }
         }
@@ -1064,7 +1072,7 @@ pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
         #[rustc_inherit_overflow_checks]
         pub fn pow(self, mut exp: u32) -> Self {
             let mut base = self;
-            let mut acc = Self::one();
+            let mut acc = 1;
 
             while exp > 1 {
                 if (exp & 1) == 1 {
@@ -2092,7 +2100,7 @@ pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
         #[rustc_inherit_overflow_checks]
         pub fn pow(self, mut exp: u32) -> Self {
             let mut base = self;
-            let mut acc = Self::one();
+            let mut acc = 1;
 
             let mut prev_base = self;
             let mut base_oflo = false;
@@ -2129,8 +2137,7 @@ pub fn pow(self, mut exp: u32) -> Self {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn is_power_of_two(self) -> bool {
-            (self.wrapping_sub(Self::one())) & self == Self::zero() &&
-                !(self == Self::zero())
+            (self.wrapping_sub(1)) & self == 0 && !(self == 0)
         }
 
         /// Returns the smallest power of two greater than or equal to `self`.
@@ -2148,7 +2155,7 @@ pub fn is_power_of_two(self) -> bool {
         #[inline]
         pub fn next_power_of_two(self) -> Self {
             let bits = size_of::<Self>() * 8;
-            let one: Self = Self::one();
+            let one: Self = 1;
             one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
         }
 
@@ -2303,26 +2310,44 @@ pub trait Float: Sized {
     /// Returns the NaN value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn nan() -> Self;
     /// Returns the infinite value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn infinity() -> Self;
     /// Returns the negative infinite value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn neg_infinity() -> Self;
     /// Returns -0.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn neg_zero() -> Self;
     /// Returns 0.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn zero() -> Self;
     /// Returns 1.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn one() -> Self;
 
     /// Returns true if this value is NaN and false otherwise.
@@ -2345,6 +2370,9 @@ pub trait Float: Sized {
     /// Returns the mantissa, exponent and sign as integers, respectively.
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn integer_decode(self) -> (u64, i16, i8);
 
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
@@ -2379,12 +2407,10 @@ pub trait Float: Sized {
     fn powi(self, n: i32) -> Self;
 
     /// Convert radians to degrees.
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "deg_rad_conversions", since="1.7.0")]
     fn to_degrees(self) -> Self;
     /// Convert degrees to radians.
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "deg_rad_conversions", since="1.7.0")]
     fn to_radians(self) -> Self;
 }
 
index 7258c8a1b6b3dc97cb4111dece310eac916886d7..7753aae147a88d722d532d7198e1d52bf7b3e9cd 100644 (file)
@@ -69,9 +69,7 @@
 
 use cmp::PartialOrd;
 use fmt;
-use convert::From;
 use marker::{Sized, Unsize};
-use num::One;
 
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
@@ -1494,7 +1492,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// # Examples
 ///
 /// ```
-/// #![feature(iter_arith)]
 /// fn main() {
 ///     assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3..6).sum());
@@ -1558,7 +1555,6 @@ pub fn contains(&self, item: Idx) -> bool {
 /// # Examples
 ///
 /// ```
-/// #![feature(iter_arith)]
 /// fn main() {
 ///     assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
 ///     assert_eq!(2+3+4, (2..).take(3).sum());
@@ -1660,7 +1656,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// # Examples
 ///
 /// ```
-/// #![feature(inclusive_range,inclusive_range_syntax,iter_arith)]
+/// #![feature(inclusive_range,inclusive_range_syntax)]
 /// fn main() {
 ///     assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3...5).sum());
@@ -1714,24 +1710,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<Idx: PartialOrd + One + Sub<Output=Idx>> From<Range<Idx>> for RangeInclusive<Idx> {
-    fn from(range: Range<Idx>) -> RangeInclusive<Idx> {
-        use self::RangeInclusive::*;
-
-        if range.start < range.end {
-            NonEmpty {
-                start: range.start,
-                end: range.end - Idx::one() // can't underflow because end > start >= MIN
-            }
-        } else {
-            Empty {
-                at: range.start
-            }
-        }
-    }
-}
-
 #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
 impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// # Examples
index 4d9f042fddedc03db74c4647848032836efdae04..94c6c636ce8fce6469f374dbfdb730f60051ea3b 100644 (file)
 //! }
 //!
 //! fn write_info(info: &Info) -> io::Result<()> {
-//!     let mut file = try!(File::create("my_best_friends.txt"));
 //!     // Early return on error
+//!     let mut file = match File::create("my_best_friends.txt") {
+//!            Err(e) => return Err(e),
+//!            Ok(f) => f,
+//!     };
 //!     if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) {
 //!         return Err(e)
 //!     }
index 9b6cedd25b741a43071d70c2d71f59bf47388dcb..a5e6005545bd73d8407ca7985c6c4463c3c1f213 100644 (file)
@@ -10,7 +10,7 @@
 use test::{Bencher, black_box};
 
 use core::hash::{Hash, Hasher};
-use core::hash::SipHasher;
+use core::hash::{SipHasher, SipHasher13, SipHasher24};
 
 // Hash just the bytes of the slice, without length prefix
 struct Bytes<'a>(&'a [u8]);
@@ -45,27 +45,117 @@ macro_rules! u8to64_le {
     });
 }
 
-fn hash<T: Hash>(x: &T) -> u64 {
-    let mut st = SipHasher::new();
+fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
     x.hash(&mut st);
     st.finish()
 }
 
-fn hash_with_keys<T: Hash>(k1: u64, k2: u64, x: &T) -> u64 {
-    let mut st = SipHasher::new_with_keys(k1, k2);
-    x.hash(&mut st);
-    st.finish()
+fn hash<T: Hash>(x: &T) -> u64 {
+    hash_with(SipHasher::new(), x)
 }
 
-fn hash_bytes(x: &[u8]) -> u64 {
-    let mut s = SipHasher::default();
+fn hash_bytes<H: Hasher>(mut s: H, x: &[u8]) -> u64 {
     Hasher::write(&mut s, x);
     s.finish()
 }
 
 #[test]
 #[allow(unused_must_use)]
-fn test_siphash() {
+fn test_siphash_1_3() {
+    let vecs : [[u8; 8]; 64] = [
+        [ 0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab ],
+        [ 0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9 ],
+        [ 0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82 ],
+        [ 0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b ],
+        [ 0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf ],
+        [ 0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde ],
+        [ 0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5 ],
+        [ 0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3 ],
+        [ 0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36 ],
+        [ 0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25 ],
+        [ 0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79 ],
+        [ 0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70 ],
+        [ 0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78 ],
+        [ 0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30 ],
+        [ 0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60 ],
+        [ 0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3 ],
+        [ 0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc ],
+        [ 0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c ],
+        [ 0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f ],
+        [ 0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2 ],
+        [ 0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0 ],
+        [ 0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9 ],
+        [ 0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f ],
+        [ 0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52 ],
+        [ 0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4 ],
+        [ 0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45 ],
+        [ 0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a ],
+        [ 0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9 ],
+        [ 0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb ],
+        [ 0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88 ],
+        [ 0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54 ],
+        [ 0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23 ],
+        [ 0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81 ],
+        [ 0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d ],
+        [ 0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75 ],
+        [ 0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce ],
+        [ 0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c ],
+        [ 0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6 ],
+        [ 0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3 ],
+        [ 0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62 ],
+        [ 0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1 ],
+        [ 0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66 ],
+        [ 0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65 ],
+        [ 0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24 ],
+        [ 0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2 ],
+        [ 0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2 ],
+        [ 0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1 ],
+        [ 0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49 ],
+        [ 0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f ],
+        [ 0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6 ],
+        [ 0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e ],
+        [ 0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c ],
+        [ 0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4 ],
+        [ 0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36 ],
+        [ 0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31 ],
+        [ 0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2 ],
+        [ 0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4 ],
+        [ 0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23 ],
+        [ 0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f ],
+        [ 0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8 ],
+        [ 0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6 ],
+        [ 0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae ],
+        [ 0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3 ],
+        [ 0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d ]
+    ];
+
+    let k0 = 0x_07_06_05_04_03_02_01_00;
+    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
+    let mut buf = Vec::new();
+    let mut t = 0;
+    let mut state_inc = SipHasher13::new_with_keys(k0, k1);
+
+    while t < 64 {
+        let vec = u8to64_le!(vecs[t], 0);
+        let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
+        assert_eq!(vec, out);
+
+        let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
+        let i = state_inc.finish();
+
+        assert_eq!(full, i);
+        assert_eq!(full, vec);
+
+        buf.push(t as u8);
+        Hasher::write(&mut state_inc, &[t as u8]);
+
+        t += 1;
+    }
+}
+
+#[test]
+#[allow(unused_must_use)]
+fn test_siphash_2_4() {
     let vecs : [[u8; 8]; 64] = [
         [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
         [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
@@ -137,14 +227,14 @@ fn test_siphash() {
     let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
     let mut buf = Vec::new();
     let mut t = 0;
-    let mut state_inc = SipHasher::new_with_keys(k0, k1);
+    let mut state_inc = SipHasher24::new_with_keys(k0, k1);
 
     while t < 64 {
         let vec = u8to64_le!(vecs[t], 0);
-        let out = hash_with_keys(k0, k1, &Bytes(&buf));
+        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
         assert_eq!(vec, out);
 
-        let full = hash_with_keys(k0, k1, &Bytes(&buf));
+        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
         let i = state_inc.finish();
 
         assert_eq!(full, i);
@@ -156,7 +246,6 @@ fn test_siphash() {
         t += 1;
     }
 }
-
 #[test] #[cfg(target_arch = "arm")]
 fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
@@ -289,7 +378,7 @@ fn bench_u32_keyed(b: &mut Bencher) {
     let k1 = black_box(0x1);
     let k2 = black_box(0x2);
     b.iter(|| {
-        hash_with_keys(k1, k2, &u)
+        hash_with(SipHasher::new_with_keys(k1, k2), &u)
     });
     b.bytes = 8;
 }
@@ -308,7 +397,7 @@ fn bench_u64(b: &mut Bencher) {
 fn bench_bytes_4(b: &mut Bencher) {
     let data = black_box([b' '; 4]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 4;
 }
@@ -317,7 +406,7 @@ fn bench_bytes_4(b: &mut Bencher) {
 fn bench_bytes_7(b: &mut Bencher) {
     let data = black_box([b' '; 7]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 7;
 }
@@ -326,7 +415,7 @@ fn bench_bytes_7(b: &mut Bencher) {
 fn bench_bytes_8(b: &mut Bencher) {
     let data = black_box([b' '; 8]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 8;
 }
@@ -335,7 +424,7 @@ fn bench_bytes_8(b: &mut Bencher) {
 fn bench_bytes_a_16(b: &mut Bencher) {
     let data = black_box([b' '; 16]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 16;
 }
@@ -344,7 +433,7 @@ fn bench_bytes_a_16(b: &mut Bencher) {
 fn bench_bytes_b_32(b: &mut Bencher) {
     let data = black_box([b' '; 32]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 32;
 }
@@ -353,7 +442,7 @@ fn bench_bytes_b_32(b: &mut Bencher) {
 fn bench_bytes_c_128(b: &mut Bencher) {
     let data = black_box([b' '; 128]);
     b.iter(|| {
-        hash_bytes(&data)
+        hash_bytes(SipHasher::default(), &data)
     });
     b.bytes = 128;
 }
index 88d73df937f7e26d28ce5810d177421b77274a9a..053158c14bf20ffb5ac4f6618cc23a5685a78796 100644 (file)
 #![feature(core_private_diy_float)]
 #![feature(dec2flt)]
 #![feature(fixed_size_array)]
-#![feature(float_extras)]
 #![feature(flt2dec)]
-#![feature(iter_arith)]
 #![feature(libc)]
 #![feature(nonzero)]
 #![feature(rand)]
 #![feature(raw)]
+#![feature(sip_hash_13)]
 #![feature(slice_patterns)]
 #![feature(step_by)]
 #![feature(test)]
index 4c0a403e574a3c1a2e312b4f61053aa9c1793b3c..1a3533317dae68c57aed2528469ed575e738e58d 100644 (file)
@@ -9,9 +9,24 @@
 // except according to those terms.
 
 use std::f64;
+use std::mem;
 use core::num::diy_float::Fp;
 use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
 
+fn integer_decode(f: f64) -> (u64, i16, i8) {
+    let bits: u64 = unsafe { mem::transmute(f) };
+    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
+    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
+    let mantissa = if exponent == 0 {
+        (bits & 0xfffffffffffff) << 1
+    } else {
+        (bits & 0xfffffffffffff) | 0x10000000000000
+    };
+    // Exponent bias + mantissa shift
+    exponent -= 1023 + 52;
+    (mantissa, exponent, sign)
+}
+
 #[test]
 fn fp_to_float_half_to_even() {
     fn is_normalized(sig: u64) -> bool {
@@ -21,12 +36,12 @@ fn is_normalized(sig: u64) -> bool {
 
     fn conv(sig: u64) -> u64 {
         // The significands are perfectly in range, so the exponent should not matter
-        let (m1, e1, _) = fp_to_float::<f64>(Fp { f: sig, e: 0 }).integer_decode();
+        let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 }));
         assert_eq!(e1, 0 + 64 - 53);
-        let (m2, e2, _) = fp_to_float::<f64>(Fp { f: sig, e: 55 }).integer_decode();
+        let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 }));
         assert_eq!(e2, 55 + 64 - 53);
         assert_eq!(m2, m1);
-        let (m3, e3, _) = fp_to_float::<f64>(Fp { f: sig, e: -78 }).integer_decode();
+        let (m3, e3, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: -78 }));
         assert_eq!(e3, -78 + 64 - 53);
         assert_eq!(m3, m2);
         m3
@@ -65,7 +80,7 @@ fn integers_to_f64() {
 #[test]
 fn human_f64_roundtrip() {
     for &x in &SOME_FLOATS {
-        let (f, e, _) = x.integer_decode();
+        let (f, e, _) = integer_decode(x);
         let fp = Fp { f: f, e: e};
         assert_eq!(fp_to_float::<f64>(fp), x);
     }
index 21260c520f6235e26f0129dd141dec9a07f58146..857aae72c8a5bd5d92a0088a36bbe3c37fc58b37 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::f64;
 use core::num::flt2dec::estimator::*;
 
 #[test]
@@ -54,7 +53,7 @@ macro_rules! assert_almost_eq {
     assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
 
     for i in -1074..972 {
-        let expected = f64::ldexp(1.0, i).log10().ceil();
+        let expected = super::ldexp_f64(1.0, i).log10().ceil();
         assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
     }
 }
index 1a592f3ad4249f3489cffec79b70bb8e01bc9432..0f4d19e7092571495405338fb31ef9f3a1f5fd9b 100644 (file)
@@ -89,6 +89,17 @@ macro_rules! try_fixed {
     })
 }
 
+fn ldexp_f32(a: f32, b: i32) -> f32 {
+    ldexp_f64(a as f64, b) as f32
+}
+
+fn ldexp_f64(a: f64, b: i32) -> f64 {
+    extern {
+        fn ldexp(x: f64, n: i32) -> f64;
+    }
+    unsafe { ldexp(a, b) }
+}
+
 fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
         where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
     // use a large enough buffer
@@ -237,7 +248,7 @@ pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     // 10^8 * 0.3355443
     // 10^8 * 0.33554432
     // 10^8 * 0.33554436
-    check_shortest!(f(f32::ldexp(1.0, 25)) => b"33554432", 8);
+    check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8);
 
     // 10^39 * 0.340282326356119256160033759537265639424
     // 10^39 * 0.34028234663852885981170418348451692544
@@ -252,13 +263,13 @@ pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     // 10^-44 * 0
     // 10^-44 * 0.1401298464324817070923729583289916131280...
     // 10^-44 * 0.2802596928649634141847459166579832262560...
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
     check_shortest!(f(minf32) => b"1", -44);
 }
 
 pub fn f32_exact_sanity_test<F>(mut f: F)
         where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
 
     check_exact!(f(0.1f32)            => b"100000001490116119384765625             ", 0);
     check_exact!(f(0.5f32)            => b"5                                       ", 0);
@@ -336,7 +347,7 @@ pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     // 10^20 * 0.18446744073709549568
     // 10^20 * 0.18446744073709551616
     // 10^20 * 0.18446744073709555712
-    check_shortest!(f(f64::ldexp(1.0, 64)) => b"18446744073709552", 20);
+    check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20);
 
     // pathological case: high = 10^23 (exact). tie breaking should always prefer that.
     // 10^24 * 0.099999999999999974834176
@@ -357,13 +368,13 @@ pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     // 10^-323 * 0
     // 10^-323 * 0.4940656458412465441765687928682213723650...
     // 10^-323 * 0.9881312916824930883531375857364427447301...
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
     check_shortest!(f(minf64) => b"5", -323);
 }
 
 pub fn f64_exact_sanity_test<F>(mut f: F)
         where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
 
     check_exact!(f(0.1f64)            => b"1000000000000000055511151231257827021181", 0);
     check_exact!(f(0.45f64)           => b"4500000000000000111022302462515654042363", 0);
@@ -616,7 +627,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool)
     assert_eq!(to_string(f, f32::MAX, Minus, 1, false), format!("34028235{:0>31}.0", ""));
     assert_eq!(to_string(f, f32::MAX, Minus, 8, false), format!("34028235{:0>31}.00000000", ""));
 
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
     assert_eq!(to_string(f, minf32, Minus,  0, false), format!("0.{:0>44}1", ""));
     assert_eq!(to_string(f, minf32, Minus, 45, false), format!("0.{:0>44}1", ""));
     assert_eq!(to_string(f, minf32, Minus, 46, false), format!("0.{:0>44}10", ""));
@@ -628,7 +639,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool)
     assert_eq!(to_string(f, f64::MAX, Minus, 8, false),
                format!("17976931348623157{:0>292}.00000000", ""));
 
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
     assert_eq!(to_string(f, minf64, Minus,   0, false), format!("0.{:0>323}5", ""));
     assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
     assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
@@ -730,7 +741,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: b
     assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38");
     assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", ""));
 
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
     assert_eq!(to_string(f, minf32, Minus, ( -4, 16), false), "1e-45");
     assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45");
     assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", ""));
@@ -742,7 +753,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: b
     assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false),
                "1.7976931348623157e308");
 
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
     assert_eq!(to_string(f, minf64, Minus, (  -4,  16), false), "5e-324");
     assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", ""));
     assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324");
@@ -874,7 +885,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) ->
     assert_eq!(to_string(f, f32::MAX, Minus, 64, false),
                "3.402823466385288598117041834845169254400000000000000000000000000e38");
 
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
     assert_eq!(to_string(f, minf32, Minus,   1, false), "1e-45");
     assert_eq!(to_string(f, minf32, Minus,   2, false), "1.4e-45");
     assert_eq!(to_string(f, minf32, Minus,   4, false), "1.401e-45");
@@ -914,7 +925,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) ->
                  0000000000000000000000000000000000000000000000000000000000000000e308");
 
     // okay, this is becoming tough. fortunately for us, this is almost the worst case.
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
     assert_eq!(to_string(f, minf64, Minus,    1, false), "5e-324");
     assert_eq!(to_string(f, minf64, Minus,    2, false), "4.9e-324");
     assert_eq!(to_string(f, minf64, Minus,    4, false), "4.941e-324");
@@ -1120,7 +1131,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool)
     assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
                "340282346638528859811704183484516925440.00");
 
-    let minf32 = f32::ldexp(1.0, -149);
+    let minf32 = ldexp_f32(1.0, -149);
     assert_eq!(to_string(f, minf32, Minus,   0, false), "0");
     assert_eq!(to_string(f, minf32, Minus,   1, false), "0.0");
     assert_eq!(to_string(f, minf32, Minus,   2, false), "0.00");
@@ -1152,7 +1163,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool)
                 9440758685084551339423045832369032229481658085593321233482747978\
                 26204144723168738177180919299881250404026184124858368.0000000000");
 
-    let minf64 = f64::ldexp(1.0, -1074);
+    let minf64 = ldexp_f64(1.0, -1074);
     assert_eq!(to_string(f, minf64, Minus, 0, false), "0");
     assert_eq!(to_string(f, minf64, Minus, 1, false), "0.0");
     assert_eq!(to_string(f, minf64, Minus, 10, false), "0.0000000000");
index 1185ad25485bd32ca3efbe67dd32871ed1c7025d..41ad089ecd235d0f753de2b6da8d50043ac4463b 100644 (file)
@@ -144,9 +144,8 @@ fn rand<R: Rng>(rng: &mut R) -> char {
             // Rejection sampling. About 0.2% of numbers with at most
             // 21-bits are invalid codepoints (surrogates), so this
             // will succeed first go almost every time.
-            match char::from_u32(rng.next_u32() & CHAR_MASK) {
-                Some(c) => return c,
-                None => {}
+            if let Some(c) = char::from_u32(rng.next_u32() & CHAR_MASK) {
+                return c;
             }
         }
     }
index 70d0a4e315c3743501a9e2a1afc43c9baf5b6449..4e16fae187070ee13880b1a8c189cf91c724d409 100644 (file)
@@ -118,8 +118,6 @@ pub fn query(&self) -> DepGraphQuery<DefId> {
     /// the buffer is full, this may swap.)
     #[inline]
     pub fn enqueue(&self, message: DepMessage) {
-        debug!("enqueue: {:?} tasks_pushed={}", message, self.tasks_pushed.get());
-
         // Regardless of whether dep graph construction is enabled, we
         // still want to check that we always have a valid task on the
         // stack when a read/write/etc event occurs.
index 598a2cfca1320de342cee8c50dc7d75af1c7b221..bf6188faa2fbdf160d7c60032e0bb8613c186042 100644 (file)
@@ -1697,13 +1697,10 @@ fn print_path_parameters(&mut self,
                 self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(&ty))?;
                 word(&mut self.s, ")")?;
 
-                match data.output {
-                    None => {}
-                    Some(ref ty) => {
-                        self.space_if_not_bol()?;
-                        self.word_space("->")?;
-                        self.print_type(&ty)?;
-                    }
+                if let Some(ref ty) = data.output {
+                    self.space_if_not_bol()?;
+                    self.word_space("->")?;
+                    self.print_type(&ty)?;
                 }
             }
         }
index ebfa942e5e415d880d74f03d12c545166623117f..d3b4afa2cee7915caa98b010a4b792d8713ea5df 100644 (file)
@@ -842,11 +842,8 @@ pub fn combine_vars<F>(&self,
         where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region, Region)
     {
         let vars = TwoRegions { a: a, b: b };
-        match self.combine_map(t).borrow().get(&vars) {
-            Some(&c) => {
-                return ReVar(c);
-            }
-            None => {}
+        if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
+            return ReVar(c);
         }
         let c = self.new_region_var(MiscVariable(origin.span()));
         self.combine_map(t).borrow_mut().insert(vars, c);
index eb9dd7dfcb36f8d57818042e1c50b973f4b40ce1..48ea953cc1e8b05a137d32659ab11caa20bde3a8 100644 (file)
@@ -30,7 +30,6 @@
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(enumset)]
-#![feature(iter_arith)]
 #![feature(libc)]
 #![feature(nonzero)]
 #![feature(quote)]
index 3e101e1934f294ce80a5d6d76220523321dfe50f..01e14ad71b39c8c0e7e1e384950b00cc1b046559 100644 (file)
@@ -1055,13 +1055,10 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) {
 // Output any lints that were previously added to the session.
 impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> {
     fn visit_id(&mut self, id: ast::NodeId) {
-        match self.sess().lints.borrow_mut().remove(&id) {
-            None => {}
-            Some(lints) => {
-                debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
-                for (lint_id, span, msg) in lints {
-                    self.span_lint(lint_id.lint, span, &msg[..])
-                }
+        if let Some(lints) = self.sess().lints.borrow_mut().remove(&id) {
+            debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
+            for (lint_id, span, msg) in lints {
+                self.span_lint(lint_id.lint, span, &msg[..])
             }
         }
     }
index 4d01b59001c5daf167ce709612d63f334bd9bae7..fc1294c86c44f518e1b9a7faa5caba80c5e3da20 100644 (file)
@@ -168,9 +168,8 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
     // into cfg itself?  i.e. introduce a fn-based flow-graph in
     // addition to the current block-based flow-graph, rather than
     // have to put traversals like this here?
-    match decl {
-        None => {}
-        Some(decl) => add_entries_from_fn_decl(&mut index, decl, cfg.entry)
+    if let Some(decl) = decl {
+        add_entries_from_fn_decl(&mut index, decl, cfg.entry);
     }
 
     cfg.graph.each_node(|node_idx, node| {
index 0b398fd0d47c510c61502a6dd1b4afa1955f00f7..cf6905ecf439ab24400902c25129f22647894715 100644 (file)
@@ -105,9 +105,8 @@ fn calculate_type(sess: &session::Session,
         // If the global prefer_dynamic switch is turned off, first attempt
         // static linkage (this can fail).
         config::CrateTypeExecutable if !sess.opts.cg.prefer_dynamic => {
-            match attempt_static(sess) {
-                Some(v) => return v,
-                None => {}
+            if let Some(v) = attempt_static(sess) {
+                return v;
             }
         }
 
@@ -119,9 +118,8 @@ fn calculate_type(sess: &session::Session,
         // to be found, we generate some nice pretty errors.
         config::CrateTypeStaticlib |
         config::CrateTypeCdylib => {
-            match attempt_static(sess) {
-                Some(v) => return v,
-                None => {}
+            if let Some(v) = attempt_static(sess) {
+                return v;
             }
             for cnum in sess.cstore.crates() {
                 let src = sess.cstore.used_crate_source(cnum);
@@ -136,9 +134,8 @@ fn calculate_type(sess: &session::Session,
         // to try to eagerly statically link all dependencies. This is normally
         // done for end-product dylibs, not intermediate products.
         config::CrateTypeDylib if !sess.opts.cg.prefer_dynamic => {
-            match attempt_static(sess) {
-                Some(v) => return v,
-                None => {}
+            if let Some(v) = attempt_static(sess) {
+                return v;
             }
         }
 
index 4e0b76365041c45530dcd99b1284b8c5919839ca..c8b8c5dbdbbcbc878f2d51cc386a49475253a80f 100644 (file)
@@ -735,26 +735,23 @@ fn walk_autoderefs(&mut self,
 
         for i in 0..autoderefs {
             let deref_id = ty::MethodCall::autoderef(expr.id, i as u32);
-            match self.mc.infcx.node_method_ty(deref_id) {
-                None => {}
-                Some(method_ty) => {
-                    let cmt = return_if_err!(self.mc.cat_expr_autoderefd(expr, i));
-
-                    // the method call infrastructure should have
-                    // replaced all late-bound regions with variables:
-                    let self_ty = method_ty.fn_sig().input(0);
-                    let self_ty = self.tcx().no_late_bound_regions(&self_ty).unwrap();
-
-                    let (m, r) = match self_ty.sty {
-                        ty::TyRef(r, ref m) => (m.mutbl, r),
-                        _ => span_bug!(expr.span,
-                                "bad overloaded deref type {:?}",
-                                method_ty)
-                    };
-                    let bk = ty::BorrowKind::from_mutbl(m);
-                    self.delegate.borrow(expr.id, expr.span, cmt,
-                                         *r, bk, AutoRef);
-                }
+            if let Some(method_ty) = self.mc.infcx.node_method_ty(deref_id) {
+                let cmt = return_if_err!(self.mc.cat_expr_autoderefd(expr, i));
+
+                // the method call infrastructure should have
+                // replaced all late-bound regions with variables:
+                let self_ty = method_ty.fn_sig().input(0);
+                let self_ty = self.tcx().no_late_bound_regions(&self_ty).unwrap();
+
+                let (m, r) = match self_ty.sty {
+                    ty::TyRef(r, ref m) => (m.mutbl, r),
+                    _ => span_bug!(expr.span,
+                                   "bad overloaded deref type {:?}",
+                                   method_ty)
+                };
+                let bk = ty::BorrowKind::from_mutbl(m);
+                self.delegate.borrow(expr.id, expr.span, cmt,
+                                     *r, bk, AutoRef);
             }
         }
     }
index cb2f68bb5539706ee0c8ca703a6d94eb0de0df6e..ea3765c76f89b2ec425fb845286e69338d7e685d 100644 (file)
@@ -598,11 +598,8 @@ fn pat_bindings<F>(&mut self, pat: &hir::Pat, mut f: F) where
     fn arm_pats_bindings<F>(&mut self, pat: Option<&hir::Pat>, f: F) where
         F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
     {
-        match pat {
-            Some(pat) => {
-                self.pat_bindings(pat, f);
-            }
-            None => {}
+        if let Some(pat) = pat {
+            self.pat_bindings(pat, f);
         }
     }
 
index 2ba05b4ae3212bbf81409f449b8c5ab0615a94ba..7f6614a959c894634e2d3898ed0a89c083863f97 100644 (file)
@@ -284,9 +284,8 @@ fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
     fn visit_generics(&mut self, generics: &hir::Generics) {
         for ty_param in generics.ty_params.iter() {
             walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
-            match ty_param.default {
-                Some(ref ty) => self.visit_ty(&ty),
-                None => {}
+            if let Some(ref ty) = ty_param.default {
+                self.visit_ty(&ty);
             }
         }
         for predicate in &generics.where_clause.predicates {
index 20c5320fd6464f274bc5291c52ff35a39ffd5e83..6fb1b16705fe47fce509e180202bc25cf0a75cdd 100644 (file)
@@ -123,9 +123,8 @@ fn register(&mut self, name: &str, span: Span) {
 
 impl<'a, 'v> Visitor<'v> for Context<'a> {
     fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
-        match lang_items::extract(&i.attrs) {
-            None => {}
-            Some(lang_item) => self.register(&lang_item, i.span),
+        if let Some(lang_item) = lang_items::extract(&i.attrs) {
+            self.register(&lang_item, i.span);
         }
         intravisit::walk_foreign_item(self, i)
     }
index fdaf182c6054246e0ed2d62b6958f8dc38c1c5f1..57c4af6bed569406138d3096914b43e092ee0ae8 100644 (file)
@@ -250,15 +250,12 @@ pub fn add_lint(&self,
                     msg: String) {
         let lint_id = lint::LintId::of(lint);
         let mut lints = self.lints.borrow_mut();
-        match lints.get_mut(&id) {
-            Some(arr) => {
-                let tuple = (lint_id, sp, msg);
-                if !arr.contains(&tuple) {
-                    arr.push(tuple);
-                }
-                return;
+        if let Some(arr) = lints.get_mut(&id) {
+            let tuple = (lint_id, sp, msg);
+            if !arr.contains(&tuple) {
+                arr.push(tuple);
             }
-            None => {}
+            return;
         }
         lints.insert(id, vec!((lint_id, sp, msg)));
     }
index b6591471f0eef76277f2eb60a98e304bbe706587..3b9ecb88258540cd011bb543b07be1a8bd5145e7 100644 (file)
@@ -908,6 +908,9 @@ fn note_obligation_cause_code<T>(&self,
                 err.note("only the last field of a struct or enum variant \
                           may have a dynamically sized type");
             }
+            ObligationCauseCode::ConstSized => {
+                err.note("constant expressions must have a statically known size");
+            }
             ObligationCauseCode::SharedStatic => {
                 err.note("shared static variables must have a type that implements `Sync`");
             }
index 68db5f864763964757e3680b980b6fecc2f5160c..17aa6544fe798d169244c092d16fa17ecf6a45e4 100644 (file)
@@ -127,6 +127,9 @@ pub enum ObligationCauseCode<'tcx> {
     // Types of fields (other than the last) in a struct must be sized.
     FieldSized,
 
+    // Constant expressions must be sized.
+    ConstSized,
+
     // static items must have `Sync` type
     SharedStatic,
 
index 33b33092b25c04c672558f9411904c891be416ec..14b0a8070983c84a3628b665e1d07648689768ea 100644 (file)
@@ -168,13 +168,12 @@ fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // which is incorrect.  This value was computed based on the crutch
             // value for the type contents of list.  The correct value is
             // TC::OwnsOwned.  This manifested as issue #4821.
-            match cache.get(&ty) {
-                Some(tc) => { return *tc; }
-                None => {}
+            if let Some(tc) = cache.get(&ty) {
+                return *tc;
             }
-            match tcx.tc_cache.borrow().get(&ty) {    // Must check both caches!
-                Some(tc) => { return *tc; }
-                None => {}
+            // Must check both caches!
+            if let Some(tc) = tcx.tc_cache.borrow().get(&ty) {
+                return *tc;
             }
             cache.insert(ty, TC::None);
 
index 1a944e04effd76475221e67bcc3ac73a02c03696..b334964bf489b4e4fac8e9e533e4fc771b887b88 100644 (file)
@@ -521,9 +521,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionEraser<'a, 'gcx, 'tcx> {
             fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.0 }
 
             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-                match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
-                    None => {}
-                    Some(u) => return u
+                if let Some(u) = self.tcx().normalized_cache.borrow().get(&ty).cloned() {
+                    return u;
                 }
 
                 // FIXME(eddyb) should local contexts have a cache too?
@@ -714,4 +713,3 @@ fn visit_region(&mut self, r: ty::Region) -> bool {
         false
     }
 }
-
index ee7fb5fc94b7752ea8ac31d2e8a778b319f93810..21c14e6fe4c3b16c2d39eac6769274bcb445c47b 100644 (file)
@@ -712,16 +712,13 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         // struct Foo;
                         // struct Bar<T> { x: Bar<Foo> }
 
-                        match iter.next() {
-                            Some(&seen_type) => {
-                                if same_struct_or_enum(seen_type, def) {
-                                    debug!("SelfRecursive: {:?} contains {:?}",
-                                           seen_type,
-                                           ty);
-                                    return Representability::SelfRecursive;
-                                }
+                        if let Some(&seen_type) = iter.next() {
+                            if same_struct_or_enum(seen_type, def) {
+                                debug!("SelfRecursive: {:?} contains {:?}",
+                                       seen_type,
+                                       ty);
+                                return Representability::SelfRecursive;
                             }
-                            None => {}
                         }
 
                         // We also need to know whether the first item contains other types
index 4b8cbbffaa5efafd942300e05aed64a1d4c71fbd..c9822a4fee7498b4da41c83a2bffe357df515eb5 100644 (file)
@@ -274,11 +274,8 @@ fn is_var_path(&self, index: MovePathIndex) -> bool {
     /// `lp` and any of its base paths that do not yet have an index.
     pub fn move_path(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                      lp: Rc<LoanPath<'tcx>>) -> MovePathIndex {
-        match self.path_map.borrow().get(&lp) {
-            Some(&index) => {
-                return index;
-            }
-            None => {}
+        if let Some(&index) = self.path_map.borrow().get(&lp) {
+            return index;
         }
 
         let index = match lp.kind {
index c878edcd4b2a80c45865add1582093f72441adf8..a5a9dea61ad7c99661851be39303634677eb4198 100644 (file)
@@ -176,9 +176,8 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
 
                 // Second, if there is a guard on each arm, make sure it isn't
                 // assigning or borrowing anything mutably.
-                match arm.guard {
-                    Some(ref guard) => check_for_mutation_in_guard(cx, &guard),
-                    None => {}
+                if let Some(ref guard) = arm.guard {
+                    check_for_mutation_in_guard(cx, &guard);
                 }
             }
 
index 2da9a55f1fd441c7f1e4d58b04b9a857c7f6354d..726ba4fc1924fd48f3b3fc25b7c0d38df381c0f3 100644 (file)
@@ -27,7 +27,6 @@
 #![feature(staged_api)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
-#![feature(iter_arith)]
 #![feature(question_mark)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
index b3918f1e4bc8b271900f9ceb329374348885e93e..9123463149936da2b434d8e4c84c14288261f12f 100644 (file)
@@ -15,6 +15,7 @@
 use std::ops::{Index, IndexMut, Range};
 use std::fmt;
 use std::vec;
+use std::u32;
 
 use rustc_serialize as serialize;
 
@@ -31,6 +32,11 @@ fn new(idx: usize) -> Self { idx }
     fn index(self) -> usize { self }
 }
 
+impl Idx for u32 {
+    fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 }
+    fn index(self) -> usize { self as usize }
+}
+
 #[derive(Clone)]
 pub struct IndexVec<I: Idx, T> {
     pub raw: Vec<T>,
index b713b2285a65feb4418b9f7336c41b48e1c45522..c079146edbf42bbe59989fca939aa519fa374662 100644 (file)
@@ -208,11 +208,17 @@ pub fn in_snapshot(&self) -> bool {
     ///
     /// This CAN be done in a snapshot
     pub fn register_obligation(&mut self, obligation: O) {
-        self.register_obligation_at(obligation, None)
+        // Ignore errors here - there is no guarantee of success.
+        let _ = self.register_obligation_at(obligation, None);
     }
 
-    fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>) {
-        if self.done_cache.contains(obligation.as_predicate()) { return }
+    // returns Err(()) if we already know this obligation failed.
+    fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>)
+                              -> Result<(), ()>
+    {
+        if self.done_cache.contains(obligation.as_predicate()) {
+            return Ok(())
+        }
 
         match self.waiting_cache.entry(obligation.as_predicate().clone()) {
             Entry::Occupied(o) => {
@@ -226,6 +232,11 @@ fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>) {
                         self.nodes[o.get().get()].dependents.push(parent);
                     }
                 }
+                if let NodeState::Error = self.nodes[o.get().get()].state.get() {
+                    Err(())
+                } else {
+                    Ok(())
+                }
             }
             Entry::Vacant(v) => {
                 debug!("register_obligation_at({:?}, {:?}) - ok",
@@ -233,8 +244,9 @@ fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>) {
                 v.insert(NodeIndex::new(self.nodes.len()));
                 self.cache_list.push(obligation.as_predicate().clone());
                 self.nodes.push(Node::new(parent, obligation));
+                Ok(())
             }
-        };
+        }
     }
 
     /// Convert all remaining obligations to the given error.
@@ -306,12 +318,19 @@ pub fn process_obligations<P>(&mut self, processor: &mut P) -> Outcome<O, P::Err
                 Ok(Some(children)) => {
                     // if we saw a Some(_) result, we are not (yet) stalled
                     stalled = false;
+                    self.nodes[index].state.set(NodeState::Success);
+
                     for child in children {
-                        self.register_obligation_at(child,
-                                                    Some(NodeIndex::new(index)));
+                        let st = self.register_obligation_at(
+                            child,
+                            Some(NodeIndex::new(index))
+                        );
+                        if let Err(()) = st {
+                            // error already reported - propagate it
+                            // to our node.
+                            self.error_at(index);
+                        }
                     }
-
-                    self.nodes[index].state.set(NodeState::Success);
                 }
                 Err(err) => {
                     let backtrace = self.error_at(index);
index 8eac8892a3efe42c65f874bc0d5c14370a0aacd1..a95b2b84b34c85471ebac43575d7748570784a15 100644 (file)
@@ -418,3 +418,43 @@ fn orphan() {
     let errors = forest.to_errors(());
     assert_eq!(errors.len(), 0);
 }
+
+#[test]
+fn simultaneous_register_and_error() {
+    // check that registering a failed obligation works correctly
+    let mut forest = ObligationForest::new();
+    forest.register_obligation("A");
+    forest.register_obligation("B");
+
+    let Outcome { completed: ok, errors: err, .. } =
+        forest.process_obligations(&mut C(|obligation| {
+            match *obligation {
+                "A" => Err("An error"),
+                "B" => Ok(Some(vec!["A"])),
+                _ => unreachable!(),
+            }
+        }, |_|{}));
+    assert_eq!(ok.len(), 0);
+    assert_eq!(err, vec![super::Error {
+        error: "An error",
+        backtrace: vec!["A"]
+    }]);
+
+    let mut forest = ObligationForest::new();
+    forest.register_obligation("B");
+    forest.register_obligation("A");
+
+    let Outcome { completed: ok, errors: err, .. } =
+        forest.process_obligations(&mut C(|obligation| {
+            match *obligation {
+                "A" => Err("An error"),
+                "B" => Ok(Some(vec!["A"])),
+                _ => unreachable!(),
+            }
+        }, |_|{}));
+    assert_eq!(ok.len(), 0);
+    assert_eq!(err, vec![super::Error {
+        error: "An error",
+        backtrace: vec!["A"]
+    }]);
+}
index 46009e581309444f7496ba886aff3f180899840f..277789f5312eee0dd9ce8c73e133714ec6d0832a 100644 (file)
@@ -116,34 +116,20 @@ macro_rules! controller_entry_point {
         let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
         let id = link::find_crate_name(Some(sess), &krate.attrs, input);
         let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
-            let make_glob_map = control.make_glob_map;
-            phase_2_configure_and_expand(sess, &cstore, krate, &id, addl_plugins, make_glob_map)?
+            phase_2_configure_and_expand(
+                sess, &cstore, krate, &id, addl_plugins, control.make_glob_map,
+                |expanded_crate| {
+                    let mut state = CompileState::state_after_expand(
+                        input, sess, outdir, output, &cstore, expanded_crate, &id,
+                    );
+                    controller_entry_point!(after_expand, sess, state, Ok(()));
+                    Ok(())
+                }
+            )?
         };
 
-        controller_entry_point!(after_expand,
-                                sess,
-                                CompileState::state_after_expand(input,
-                                                                 sess,
-                                                                 outdir,
-                                                                 output,
-                                                                 &cstore,
-                                                                 &expanded_crate,
-                                                                 &id),
-                                Ok(()));
-
         write_out_deps(sess, &outputs, &id);
 
-        controller_entry_point!(after_write_deps,
-                                sess,
-                                CompileState::state_after_write_deps(input,
-                                                                     sess,
-                                                                     outdir,
-                                                                     output,
-                                                                     &cstore,
-                                                                     &expanded_crate,
-                                                                     &id),
-                                Ok(()));
-
         let arenas = ty::CtxtArenas::new();
 
         // Construct the HIR map
@@ -239,8 +225,15 @@ macro_rules! controller_entry_point {
                             phase5_result);
     phase5_result?;
 
+    write::cleanup_llvm(&trans);
+
     phase_6_link_output(sess, &trans, &outputs);
 
+    controller_entry_point!(compilation_done,
+                            sess,
+                            CompileState::state_when_compilation_done(input, sess, outdir, output),
+                            Ok(()));
+
     Ok(())
 }
 
@@ -285,10 +278,10 @@ pub fn source_name(input: &Input) -> String {
 pub struct CompileController<'a> {
     pub after_parse: PhaseController<'a>,
     pub after_expand: PhaseController<'a>,
-    pub after_write_deps: PhaseController<'a>,
     pub after_hir_lowering: PhaseController<'a>,
     pub after_analysis: PhaseController<'a>,
     pub after_llvm: PhaseController<'a>,
+    pub compilation_done: PhaseController<'a>,
 
     pub make_glob_map: MakeGlobMap,
 }
@@ -298,10 +291,10 @@ pub fn basic() -> CompileController<'a> {
         CompileController {
             after_parse: PhaseController::basic(),
             after_expand: PhaseController::basic(),
-            after_write_deps: PhaseController::basic(),
             after_hir_lowering: PhaseController::basic(),
             after_analysis: PhaseController::basic(),
             after_llvm: PhaseController::basic(),
+            compilation_done: PhaseController::basic(),
             make_glob_map: MakeGlobMap::No,
         }
     }
@@ -406,23 +399,6 @@ fn state_after_expand(input: &'a Input,
         }
     }
 
-    fn state_after_write_deps(input: &'a Input,
-                              session: &'ast Session,
-                              out_dir: &'a Option<PathBuf>,
-                              out_file: &'a Option<PathBuf>,
-                              cstore: &'a CStore,
-                              krate: &'a ast::Crate,
-                              crate_name: &'a str)
-                              -> CompileState<'a, 'b, 'ast, 'tcx> {
-        CompileState {
-            crate_name: Some(crate_name),
-            cstore: Some(cstore),
-            expanded_crate: Some(krate),
-            out_file: out_file.as_ref().map(|s| &**s),
-            ..CompileState::empty(input, session, out_dir)
-        }
-    }
-
     fn state_after_hir_lowering(input: &'a Input,
                                 session: &'ast Session,
                                 out_dir: &'a Option<PathBuf>,
@@ -486,6 +462,17 @@ fn state_after_llvm(input: &'a Input,
             ..CompileState::empty(input, session, out_dir)
         }
     }
+
+    fn state_when_compilation_done(input: &'a Input,
+                                    session: &'ast Session,
+                                    out_dir: &'a Option<PathBuf>,
+                                    out_file: &'a Option<PathBuf>)
+                                    -> CompileState<'a, 'b, 'ast, 'tcx> {
+        CompileState {
+            out_file: out_file.as_ref().map(|s| &**s),
+            ..CompileState::empty(input, session, out_dir)
+        }
+    }
 }
 
 pub fn phase_1_parse_input<'a>(sess: &'a Session,
@@ -556,13 +543,16 @@ pub struct ExpansionResult<'a> {
 /// standard library and prelude, and name resolution.
 ///
 /// Returns `None` if we're aborting after handling -W help.
-pub fn phase_2_configure_and_expand<'a>(sess: &Session,
-                                        cstore: &CStore,
-                                        mut krate: ast::Crate,
-                                        crate_name: &'a str,
-                                        addl_plugins: Option<Vec<String>>,
-                                        make_glob_map: MakeGlobMap)
-                                        -> Result<ExpansionResult<'a>, usize> {
+pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
+                                           cstore: &CStore,
+                                           mut krate: ast::Crate,
+                                           crate_name: &'a str,
+                                           addl_plugins: Option<Vec<String>>,
+                                           make_glob_map: MakeGlobMap,
+                                           after_expand: F)
+                                           -> Result<ExpansionResult<'a>, usize>
+    where F: FnOnce(&ast::Crate) -> CompileResult,
+{
     let time_passes = sess.time_passes();
 
     // strip before anything else because crate metadata may use #[cfg_attr]
@@ -745,9 +735,23 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
          "AST validation",
          || ast_validation::check_crate(sess, &krate));
 
-    time(sess.time_passes(), "name resolution", || {
+    time(sess.time_passes(), "name resolution", || -> CompileResult {
+        // Currently, we ignore the name resolution data structures for the purposes of dependency
+        // tracking. Instead we will run name resolution and include its output in the hash of each
+        // item, much like we do for macro expansion. In other words, the hash reflects not just
+        // its contents but the results of name resolution on those contents. Hopefully we'll push
+        // this back at some point.
+        let _ignore = sess.dep_graph.in_ignore();
+        resolver.build_reduced_graph(&krate);
+        resolver.resolve_imports();
+
+        // Since import resolution will eventually happen in expansion,
+        // don't perform `after_expand` until after import resolution.
+        after_expand(&krate)?;
+
         resolver.resolve_crate(&krate);
-    });
+        Ok(())
+    })?;
 
     // Lower ast -> hir.
     let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
index 32eb3fdd7109232f543b8533637d568bd82c1879..c9569a63436f5f1b2e5a891d1260d1324d54704d 100644 (file)
@@ -511,7 +511,7 @@ fn build_controller(&mut self,
         }
 
         if sess.opts.no_analysis || sess.opts.debugging_opts.ast_json {
-            control.after_write_deps.stop = Compilation::Stop;
+            control.after_hir_lowering.stop = Compilation::Stop;
         }
 
         if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
index fad0af19a127037ad0861b1842860cecb2eb621b..f2020303089d2e3d52fef55df7ca4d3986b4e98a 100644 (file)
 const X86_WHITELIST: &'static [&'static str] = &[
     "avx\0",
     "avx2\0",
+    "bmi\0",
+    "bmi2\0",
     "sse\0",
     "sse2\0",
     "sse3\0",
     "sse4.1\0",
     "sse4.2\0",
     "ssse3\0",
+    "tbm\0",
 ];
 
 /// Add `target_feature = "..."` cfgs for a variety of platform
index 0f5977cf06618822a0438fc935845a2502568ac3..15a0ab0f284b3efdde3be345078029b4be4446af 100644 (file)
@@ -116,9 +116,11 @@ fn test_env<F>(source_string: &str,
         input: source_string.to_string(),
     };
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input).unwrap();
-    let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } =
-        driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None, MakeGlobMap::No)
-            .expect("phase 2 aborted");
+    let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = {
+        driver::phase_2_configure_and_expand(
+            &sess, &cstore, krate, "test", None, MakeGlobMap::No, |_| Ok(()),
+        ).expect("phase 2 aborted")
+    };
     let _ignore = dep_graph.in_ignore();
 
     let arenas = ty::CtxtArenas::new();
index b5b87718d2df7c352d5d36971aa39a9d47200fbf..4dc1a5e4f5e9f6dda3e8bc63fa9ffab1af28c15e 100644 (file)
@@ -150,12 +150,9 @@ fn check_must_use(cx: &LateContext, attrs: &[ast::Attribute], sp: Span) -> bool
                 if attr.check_name("must_use") {
                     let mut msg = "unused result which must be used".to_string();
                     // check for #[must_use="..."]
-                    match attr.value_str() {
-                        None => {}
-                        Some(s) => {
-                            msg.push_str(": ");
-                            msg.push_str(&s);
-                        }
+                    if let Some(s) = attr.value_str() {
+                        msg.push_str(": ");
+                        msg.push_str(&s);
                     }
                     cx.span_lint(UNUSED_MUST_USE, sp, &msg);
                     return true;
index 250aafd77a82664e22a09b0b5503cafaa6d13dd2..a2c808cbcb6b6dae988880d354dc5528b01ea85c 100644 (file)
@@ -24,19 +24,17 @@ fn main() {
     let llvm_config = env::var_os("LLVM_CONFIG")
                           .map(PathBuf::from)
                           .unwrap_or_else(|| {
-                              match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
-                                  Some(dir) => {
-                                      let to_test = dir.parent()
-                                                       .unwrap()
-                                                       .parent()
-                                                       .unwrap()
-                                                       .join(&target)
-                                                       .join("llvm/bin/llvm-config");
-                                      if Command::new(&to_test).output().is_ok() {
-                                          return to_test;
-                                      }
+                              if let Some(dir) = env::var_os("CARGO_TARGET_DIR")
+                                      .map(PathBuf::from) {
+                                  let to_test = dir.parent()
+                                                   .unwrap()
+                                                   .parent()
+                                                   .unwrap()
+                                                   .join(&target)
+                                                   .join("llvm/bin/llvm-config");
+                                  if Command::new(&to_test).output().is_ok() {
+                                      return to_test;
                                   }
-                                  None => {}
                               }
                               PathBuf::from("llvm-config")
                           });
index 11896e176301b3bb00057f6167f22528af3c8a80..2d3302c2eef3a8078a4c6683a94f546770ed19b0 100644 (file)
@@ -16,6 +16,7 @@ rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
 rustc_const_math = { path = "../librustc_const_math" }
+rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_llvm = { path = "../librustc_llvm" }
 serialize = { path = "../libserialize" }
index 7ef00b971c57ba6262f24be7b313c4798c9621ee..2e8c5a7c23418ba137017befcbd86b4a57613481 100644 (file)
@@ -60,7 +60,7 @@
 
 struct DecodeContext<'a, 'b, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    cdata: &'b cstore::crate_metadata,
+    cdata: &'b cstore::CrateMetadata,
     from_id_range: IdRange,
     to_id_range: IdRange,
     // Cache the last used filemap for translating spans as an optimization.
@@ -121,7 +121,7 @@ fn new_span(&self, span: syntax_pos::Span) -> syntax_pos::Span {
 
 /// Decodes an item from its AST in the cdata's metadata and adds it to the
 /// ast-map.
-pub fn decode_inlined_item<'a, 'tcx>(cdata: &cstore::crate_metadata,
+pub fn decode_inlined_item<'a, 'tcx>(cdata: &cstore::CrateMetadata,
                                      tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      parent_def_path: ast_map::DefPath,
                                      parent_did: DefId,
@@ -246,7 +246,7 @@ fn emit_def_id(&mut self, did: DefId) {
 trait def_id_decoder_helpers {
     fn read_def_id(&mut self, dcx: &DecodeContext) -> DefId;
     fn read_def_id_nodcx(&mut self,
-                         cdata: &cstore::crate_metadata) -> DefId;
+                         cdata: &cstore::CrateMetadata) -> DefId;
 }
 
 impl<D:serialize::Decoder> def_id_decoder_helpers for D
@@ -258,7 +258,7 @@ fn read_def_id(&mut self, dcx: &DecodeContext) -> DefId {
     }
 
     fn read_def_id_nodcx(&mut self,
-                         cdata: &cstore::crate_metadata)
+                         cdata: &cstore::CrateMetadata)
                          -> DefId {
         let did: DefId = Decodable::decode(self).unwrap();
         decoder::translate_def_id(cdata, did)
@@ -858,17 +858,17 @@ fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
     // Versions of the type reading functions that don't need the full
     // DecodeContext.
     fn read_ty_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                         cdata: &cstore::crate_metadata) -> Ty<'tcx>;
+                         cdata: &cstore::CrateMetadata) -> Ty<'tcx>;
     fn read_tys_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>>;
+                          cdata: &cstore::CrateMetadata) -> Vec<Ty<'tcx>>;
     fn read_substs_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             cdata: &cstore::crate_metadata)
+                             cdata: &cstore::CrateMetadata)
                              -> subst::Substs<'tcx>;
 }
 
 impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     fn read_ty_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
-                         cdata: &cstore::crate_metadata)
+                         cdata: &cstore::CrateMetadata)
                          -> Ty<'tcx> {
         self.read_opaque(|_, doc| {
             Ok(
@@ -879,7 +879,7 @@ fn read_ty_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
     }
 
     fn read_tys_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
-                          cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>> {
+                          cdata: &cstore::CrateMetadata) -> Vec<Ty<'tcx>> {
         self.read_to_vec(|this| Ok(this.read_ty_nodcx(tcx, cdata)) )
             .unwrap()
             .into_iter()
@@ -887,7 +887,7 @@ fn read_tys_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
     }
 
     fn read_substs_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
-                             cdata: &cstore::crate_metadata)
+                             cdata: &cstore::CrateMetadata)
                              -> subst::Substs<'tcx>
     {
         self.read_opaque(|_, doc| {
index 74f97de26589839266d2b33040ce700092192d7c..ff072cce5db9667ccd5cb998ee0cdcb6384cdd78 100644 (file)
@@ -252,3 +252,7 @@ pub fn rustc_version() -> String {
 }
 
 pub const tag_panic_strategy: usize = 0x114;
+
+// NB: increment this if you change the format of metadata such that
+// rustc_version can't be found.
+pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2];
index 2ccac91ae910545de2e0d3f0c822ab6c942623bb..269e284b22d6cb268d3d5aceca737da1fc90be13 100644 (file)
@@ -12,7 +12,6 @@
 
 //! Validates all used crates and extern libraries and loads their metadata
 
-use common::rustc_version;
 use cstore::{self, CStore, CrateSource, MetadataBlob};
 use decoder;
 use loader::{self, CratePaths};
@@ -24,7 +23,7 @@
 use rustc::session::config::PanicStrategy;
 use rustc::session::search_paths::PathKind;
 use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
-use rustc::util::nodemap::FnvHashMap;
+use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
 use rustc::hir::map as hir_map;
 
 use std::cell::{RefCell, Cell};
@@ -132,7 +131,7 @@ struct ExtensionCrate {
 }
 
 enum PMDSource {
-    Registered(Rc<cstore::crate_metadata>),
+    Registered(Rc<cstore::CrateMetadata>),
     Owned(MetadataBlob),
 }
 
@@ -236,25 +235,6 @@ fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
         return ret;
     }
 
-    fn verify_rustc_version(&self,
-                            name: &str,
-                            span: Span,
-                            metadata: &MetadataBlob) {
-        let crate_rustc_version = decoder::crate_rustc_version(metadata.as_slice());
-        if crate_rustc_version != Some(rustc_version()) {
-            let mut err = struct_span_fatal!(self.sess, span, E0514,
-                                             "the crate `{}` has been compiled with {}, which is \
-                                              incompatible with this version of rustc",
-                                              name,
-                                              crate_rustc_version
-                                              .as_ref().map(|s| &**s)
-                                              .unwrap_or("an old version of rustc"));
-            err.help("consider removing the compiled binaries and recompiling \
-                      with your current version of rustc");
-            err.emit();
-        }
-    }
-
     fn verify_no_symbol_conflicts(&self,
                                   span: Span,
                                   metadata: &MetadataBlob) {
@@ -294,9 +274,8 @@ fn register_crate(&mut self,
                       span: Span,
                       lib: loader::Library,
                       explicitly_linked: bool)
-                      -> (ast::CrateNum, Rc<cstore::crate_metadata>,
+                      -> (ast::CrateNum, Rc<cstore::CrateMetadata>,
                           cstore::CrateSource) {
-        self.verify_rustc_version(name, span, &lib.metadata);
         self.verify_no_symbol_conflicts(span, &lib.metadata);
 
         // Claim this crate number and cache it
@@ -318,10 +297,10 @@ fn register_crate(&mut self,
 
         let loader::Library { dylib, rlib, metadata } = lib;
 
-        let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), span);
+        let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), cnum, span);
         let staged_api = self.is_staged_api(metadata.as_slice());
 
-        let cmeta = Rc::new(cstore::crate_metadata {
+        let cmeta = Rc::new(cstore::CrateMetadata {
             name: name.to_string(),
             extern_crate: Cell::new(None),
             index: decoder::load_index(metadata.as_slice()),
@@ -364,7 +343,7 @@ fn resolve_crate(&mut self,
                      span: Span,
                      kind: PathKind,
                      explicitly_linked: bool)
-                     -> (ast::CrateNum, Rc<cstore::crate_metadata>, cstore::CrateSource) {
+                     -> (ast::CrateNum, Rc<cstore::CrateMetadata>, cstore::CrateSource) {
         let result = match self.existing_match(name, hash, kind) {
             Some(cnum) => LoadResult::Previous(cnum),
             None => {
@@ -381,6 +360,7 @@ fn resolve_crate(&mut self,
                     rejected_via_hash: vec!(),
                     rejected_via_triple: vec!(),
                     rejected_via_kind: vec!(),
+                    rejected_via_version: vec!(),
                     should_match_name: true,
                 };
                 match self.load(&mut load_ctxt) {
@@ -438,8 +418,11 @@ fn load(&mut self, loader: &mut loader::Context) -> Option<LoadResult> {
 
     fn update_extern_crate(&mut self,
                            cnum: ast::CrateNum,
-                           mut extern_crate: ExternCrate)
+                           mut extern_crate: ExternCrate,
+                           visited: &mut FnvHashSet<(ast::CrateNum, bool)>)
     {
+        if !visited.insert((cnum, extern_crate.direct)) { return }
+
         let cmeta = self.cstore.get_crate_data(cnum);
         let old_extern_crate = cmeta.extern_crate.get();
 
@@ -458,11 +441,10 @@ fn update_extern_crate(&mut self,
         }
 
         cmeta.extern_crate.set(Some(extern_crate));
-
         // Propagate the extern crate info to dependencies.
         extern_crate.direct = false;
-        for &dep_cnum in cmeta.cnum_map.borrow().values() {
-            self.update_extern_crate(dep_cnum, extern_crate);
+        for &dep_cnum in cmeta.cnum_map.borrow().iter() {
+            self.update_extern_crate(dep_cnum, extern_crate, visited);
         }
     }
 
@@ -470,12 +452,13 @@ fn update_extern_crate(&mut self,
     fn resolve_crate_deps(&mut self,
                           root: &Option<CratePaths>,
                           cdata: &[u8],
-                          span : Span)
-                          -> cstore::cnum_map {
+                          krate: ast::CrateNum,
+                          span: Span)
+                          -> cstore::CrateNumMap {
         debug!("resolving deps of external crate");
         // The map from crate numbers in the crate we're resolving to local crate
         // numbers
-        decoder::get_crate_deps(cdata).iter().map(|dep| {
+        let map: FnvHashMap<_, _> = decoder::get_crate_deps(cdata).iter().map(|dep| {
             debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
             let (local_cnum, _, _) = self.resolve_crate(root,
                                                         &dep.name,
@@ -485,7 +468,13 @@ fn resolve_crate_deps(&mut self,
                                                         PathKind::Dependency,
                                                         dep.explicitly_linked);
             (dep.cnum, local_cnum)
-        }).collect()
+        }).collect();
+
+        let max_cnum = map.values().cloned().max().unwrap_or(0);
+
+        // we map 0 and all other holes in the map to our parent crate. The "additional"
+        // self-dependencies should be harmless.
+        (0..max_cnum+1).map(|cnum| map.get(&cnum).cloned().unwrap_or(krate)).collect()
     }
 
     fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCrate {
@@ -508,6 +497,7 @@ fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCra
             rejected_via_hash: vec!(),
             rejected_via_triple: vec!(),
             rejected_via_kind: vec!(),
+            rejected_via_version: vec!(),
             should_match_name: true,
         };
         let library = self.load(&mut load_ctxt).or_else(|| {
@@ -826,7 +816,7 @@ fn inject_allocator_crate(&mut self) {
     fn inject_dependency_if(&self,
                             krate: ast::CrateNum,
                             what: &str,
-                            needs_dep: &Fn(&cstore::crate_metadata) -> bool) {
+                            needs_dep: &Fn(&cstore::CrateMetadata) -> bool) {
         // don't perform this validation if the session has errors, as one of
         // those errors may indicate a circular dependency which could cause
         // this to stack overflow.
@@ -837,7 +827,17 @@ fn inject_dependency_if(&self,
         // Before we inject any dependencies, make sure we don't inject a
         // circular dependency by validating that this crate doesn't
         // transitively depend on any crates satisfying `needs_dep`.
-        validate(self, krate, krate, what, needs_dep);
+        for dep in self.cstore.crate_dependencies_in_rpo(krate) {
+            let data = self.cstore.get_crate_data(dep);
+            if needs_dep(&data) {
+                self.sess.err(&format!("the crate `{}` cannot depend \
+                                        on a crate that needs {}, but \
+                                        it depends on `{}`",
+                                       self.cstore.get_crate_data(krate).name(),
+                                       what,
+                                       data.name()));
+            }
+        }
 
         // All crates satisfying `needs_dep` do not explicitly depend on the
         // crate provided for this compile, but in order for this compilation to
@@ -849,32 +849,8 @@ fn inject_dependency_if(&self,
             }
 
             info!("injecting a dep from {} to {}", cnum, krate);
-            let mut cnum_map = data.cnum_map.borrow_mut();
-            let remote_cnum = cnum_map.len() + 1;
-            let prev = cnum_map.insert(remote_cnum as ast::CrateNum, krate);
-            assert!(prev.is_none());
+            data.cnum_map.borrow_mut().push(krate);
         });
-
-        fn validate(me: &CrateReader,
-                    krate: ast::CrateNum,
-                    root: ast::CrateNum,
-                    what: &str,
-                    needs_dep: &Fn(&cstore::crate_metadata) -> bool) {
-            let data = me.cstore.get_crate_data(krate);
-            if needs_dep(&data) {
-                let krate_name = data.name();
-                let data = me.cstore.get_crate_data(root);
-                let root_name = data.name();
-                me.sess.err(&format!("the crate `{}` cannot depend \
-                                      on a crate that needs {}, but \
-                                      it depends on `{}`", root_name, what,
-                                      krate_name));
-            }
-
-            for (_, &dep) in data.cnum_map.borrow().iter() {
-                validate(me, dep, root, what, needs_dep);
-            }
-        }
     }
 }
 
@@ -948,7 +924,8 @@ fn process_item(&mut self, i: &ast::Item) {
                                                          span: i.span,
                                                          direct: true,
                                                          path_len: len,
-                                                     });
+                                                     },
+                                                     &mut FnvHashSet());
                     self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
                 }
             }
index 3134a3844bc050caac4bf8732efd1784da49ec43..95e3c53ecb40245e420bff18e81a92d8c9bb6b2e 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use cstore;
+use common;
 use decoder;
 use encoder;
 use loader;
@@ -588,7 +589,7 @@ fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     fn metadata_encoding_version(&self) -> &[u8]
     {
-        encoder::metadata_encoding_version
+        common::metadata_encoding_version
     }
 
     /// Returns a map from a sufficiently visible external item (i.e. an external item that is
index e89f428c96f8c1953f9c4048d6da89e768a430dd..774d0f7ea188608820c21df7a014c87ecdac6cfb 100644 (file)
@@ -15,6 +15,7 @@
 
 pub use self::MetadataBlob::*;
 
+use common;
 use creader;
 use decoder;
 use index;
@@ -26,6 +27,7 @@
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::{ExternCrate};
 use rustc::session::config::PanicStrategy;
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
 
 use std::cell::{RefCell, Ref, Cell};
@@ -46,7 +48,7 @@
 // local crate numbers (as generated during this session). Each external
 // crate may refer to types in other external crates, and each has their
 // own crate numbers.
-pub type cnum_map = FnvHashMap<ast::CrateNum, ast::CrateNum>;
+pub type CrateNumMap = IndexVec<ast::CrateNum, ast::CrateNum>;
 
 pub enum MetadataBlob {
     MetadataVec(Bytes),
@@ -64,7 +66,7 @@ pub struct ImportedFileMap {
     pub translated_filemap: Rc<syntax_pos::FileMap>
 }
 
-pub struct crate_metadata {
+pub struct CrateMetadata {
     pub name: String,
 
     /// Information about the extern crate that caused this crate to
@@ -73,7 +75,7 @@ pub struct crate_metadata {
     pub extern_crate: Cell<Option<ExternCrate>>,
 
     pub data: MetadataBlob,
-    pub cnum_map: RefCell<cnum_map>,
+    pub cnum_map: RefCell<CrateNumMap>,
     pub cnum: ast::CrateNum,
     pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
     pub staged_api: bool,
@@ -97,7 +99,7 @@ pub struct crate_metadata {
 
 pub struct CStore {
     pub dep_graph: DepGraph,
-    metas: RefCell<FnvHashMap<ast::CrateNum, Rc<crate_metadata>>>,
+    metas: RefCell<FnvHashMap<ast::CrateNum, Rc<CrateMetadata>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
     extern_mod_crate_map: RefCell<NodeMap<ast::CrateNum>>,
     used_crate_sources: RefCell<Vec<CrateSource>>,
@@ -128,7 +130,7 @@ pub fn next_crate_num(&self) -> ast::CrateNum {
         self.metas.borrow().len() as ast::CrateNum + 1
     }
 
-    pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc<crate_metadata> {
+    pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc<CrateMetadata> {
         self.metas.borrow().get(&cnum).unwrap().clone()
     }
 
@@ -137,12 +139,12 @@ pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
         decoder::get_crate_hash(cdata.data())
     }
 
-    pub fn set_crate_data(&self, cnum: ast::CrateNum, data: Rc<crate_metadata>) {
+    pub fn set_crate_data(&self, cnum: ast::CrateNum, data: Rc<CrateMetadata>) {
         self.metas.borrow_mut().insert(cnum, data);
     }
 
     pub fn iter_crate_data<I>(&self, mut i: I) where
-        I: FnMut(ast::CrateNum, &Rc<crate_metadata>),
+        I: FnMut(ast::CrateNum, &Rc<CrateMetadata>),
     {
         for (&k, v) in self.metas.borrow().iter() {
             i(k, v);
@@ -151,7 +153,7 @@ pub fn iter_crate_data<I>(&self, mut i: I) where
 
     /// Like `iter_crate_data`, but passes source paths (if available) as well.
     pub fn iter_crate_data_origins<I>(&self, mut i: I) where
-        I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>),
+        I: FnMut(ast::CrateNum, &CrateMetadata, Option<CrateSource>),
     {
         for (&k, v) in self.metas.borrow().iter() {
             let origin = self.opt_used_crate_source(k);
@@ -182,6 +184,30 @@ pub fn reset(&self) {
         self.statically_included_foreign_items.borrow_mut().clear();
     }
 
+    pub fn crate_dependencies_in_rpo(&self, krate: ast::CrateNum) -> Vec<ast::CrateNum>
+    {
+        let mut ordering = Vec::new();
+        self.push_dependencies_in_postorder(&mut ordering, krate);
+        ordering.reverse();
+        ordering
+    }
+
+    pub fn push_dependencies_in_postorder(&self,
+                                          ordering: &mut Vec<ast::CrateNum>,
+                                          krate: ast::CrateNum)
+    {
+        if ordering.contains(&krate) { return }
+
+        let data = self.get_crate_data(krate);
+        for &dep in data.cnum_map.borrow().iter() {
+            if dep != krate {
+                self.push_dependencies_in_postorder(ordering, dep);
+            }
+        }
+
+        ordering.push(krate);
+    }
+
     // This method is used when generating the command line to pass through to
     // system linker. The linker expects undefined symbols on the left of the
     // command line to be defined in libraries on the right, not the other way
@@ -194,17 +220,8 @@ pub fn reset(&self) {
     pub fn do_get_used_crates(&self, prefer: LinkagePreference)
                               -> Vec<(ast::CrateNum, Option<PathBuf>)> {
         let mut ordering = Vec::new();
-        fn visit(cstore: &CStore, cnum: ast::CrateNum,
-                 ordering: &mut Vec<ast::CrateNum>) {
-            if ordering.contains(&cnum) { return }
-            let meta = cstore.get_crate_data(cnum);
-            for (_, &dep) in meta.cnum_map.borrow().iter() {
-                visit(cstore, dep, ordering);
-            }
-            ordering.push(cnum);
-        }
         for (&num, _) in self.metas.borrow().iter() {
-            visit(self, num, &mut ordering);
+            self.push_dependencies_in_postorder(&mut ordering, num);
         }
         info!("topological ordering: {:?}", ordering);
         ordering.reverse();
@@ -264,7 +281,7 @@ pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::Crate
     }
 }
 
-impl crate_metadata {
+impl CrateMetadata {
     pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
     pub fn name(&self) -> &str { decoder::get_crate_name(self.data()) }
     pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
@@ -312,20 +329,25 @@ pub fn panic_strategy(&self) -> PanicStrategy {
 }
 
 impl MetadataBlob {
-    pub fn as_slice<'a>(&'a self) -> &'a [u8] {
-        let slice = match *self {
+    pub fn as_slice_raw<'a>(&'a self) -> &'a [u8] {
+        match *self {
             MetadataVec(ref vec) => &vec[..],
             MetadataArchive(ref ar) => ar.as_slice(),
-        };
-        if slice.len() < 4 {
+        }
+    }
+
+    pub fn as_slice<'a>(&'a self) -> &'a [u8] {
+        let slice = self.as_slice_raw();
+        let len_offset = 4 + common::metadata_encoding_version.len();
+        if slice.len() < len_offset+4 {
             &[] // corrupt metadata
         } else {
-            let len = (((slice[0] as u32) << 24) |
-                       ((slice[1] as u32) << 16) |
-                       ((slice[2] as u32) << 8) |
-                       ((slice[3] as u32) << 0)) as usize;
-            if len + 4 <= slice.len() {
-                &slice[4.. len + 4]
+            let len = (((slice[len_offset+0] as u32) << 24) |
+                       ((slice[len_offset+1] as u32) << 16) |
+                       ((slice[len_offset+2] as u32) << 8) |
+                       ((slice[len_offset+3] as u32) << 0)) as usize;
+            if len <= slice.len() - 4 - len_offset {
+                &slice[len_offset + 4..len_offset + len + 4]
             } else {
                 &[] // corrupt or old metadata
             }
index 3efdf36acd9734673def1463563a8e2d2bc87a9f..eada2a9cd7a63332f6b30aeb10712a785d047f3e 100644 (file)
@@ -15,7 +15,7 @@
 use self::Family::*;
 
 use astencode::decode_inlined_item;
-use cstore::{self, crate_metadata};
+use cstore::{self, CrateMetadata};
 use common::*;
 use def_key;
 use encoder::def_to_u64;
@@ -30,7 +30,7 @@
 use rustc::hir;
 use rustc::session::config::PanicStrategy;
 
-use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
+use middle::cstore::{FoundAst, InlinedItem, LinkagePreference};
 use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{DefId, DefIndex};
@@ -61,9 +61,9 @@
 use syntax::ptr::P;
 use syntax_pos::{self, Span, BytePos, NO_EXPANSION};
 
-pub type Cmd<'a> = &'a crate_metadata;
+pub type Cmd<'a> = &'a CrateMetadata;
 
-impl crate_metadata {
+impl CrateMetadata {
     fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> {
         self.index.lookup_item(self.data(), item_id).map(|pos| {
             reader::doc_at(self.data(), pos as usize).unwrap().doc
@@ -663,7 +663,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
                                      mut get_crate_data: G,
                                      mut callback: F) where
     F: FnMut(DefLike, ast::Name, ty::Visibility),
-    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
+    G: FnMut(ast::CrateNum) -> Rc<CrateMetadata>,
 {
     // Iterate over all children.
     for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) {
@@ -682,15 +682,12 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
         };
 
         // Get the item.
-        match crate_data.get_item(child_def_id.index) {
-            None => {}
-            Some(child_item_doc) => {
-                // Hand off the item to the callback.
-                let child_name = item_name(&intr, child_item_doc);
-                let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
-                let visibility = item_visibility(child_item_doc);
-                callback(def_like, child_name, visibility);
-            }
+        if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
+            // Hand off the item to the callback.
+            let child_name = item_name(&intr, child_item_doc);
+            let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
+            let visibility = item_visibility(child_item_doc);
+            callback(def_like, child_name, visibility);
         }
     }
 
@@ -758,7 +755,7 @@ pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
                                get_crate_data: G,
                                callback: F) where
     F: FnMut(DefLike, ast::Name, ty::Visibility),
-    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
+    G: FnMut(ast::CrateNum) -> Rc<CrateMetadata>,
 {
     // Find the item.
     let item_doc = match cdata.get_item(id) {
@@ -779,7 +776,7 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
                                           get_crate_data: G,
                                           callback: F) where
     F: FnMut(DefLike, ast::Name, ty::Visibility),
-    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
+    G: FnMut(ast::CrateNum) -> Rc<CrateMetadata>,
 {
     let root_doc = rbml::Doc::new(cdata.data());
     let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
@@ -1348,25 +1345,16 @@ pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
         return DefId { krate: cdata.cnum, index: did.index };
     }
 
-    match cdata.cnum_map.borrow().get(&did.krate) {
-        Some(&n) => {
-            DefId {
-                krate: n,
-                index: did.index,
-            }
-        }
-        None => bug!("didn't find a crate in the cnum_map")
+    DefId {
+        krate: cdata.cnum_map.borrow()[did.krate],
+        index: did.index
     }
 }
 
 // Translate a DefId from the current compilation environment to a DefId
 // for an external crate.
 fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
-    if did.krate == cdata.cnum {
-        return Some(DefId { krate: LOCAL_CRATE, index: did.index });
-    }
-
-    for (&local, &global) in cdata.cnum_map.borrow().iter() {
+    for (local, &global) in cdata.cnum_map.borrow().iter_enumerated() {
         if global == did.krate {
             return Some(DefId { krate: local, index: did.index });
         }
@@ -1545,10 +1533,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
         let cnum = spec.split(':').nth(0).unwrap();
         let link = spec.split(':').nth(1).unwrap();
         let cnum: ast::CrateNum = cnum.parse().unwrap();
-        let cnum = match cdata.cnum_map.borrow().get(&cnum) {
-            Some(&n) => n,
-            None => bug!("didn't find a crate in the cnum_map")
-        };
+        let cnum = cdata.cnum_map.borrow()[cnum];
         result.push((cnum, if link == "d" {
             LinkagePreference::RequireDynamic
         } else {
index c23ad6d5f078fa2c284b8d379bedb43a15d2c794..b6f49569958d68189effffc864b47396c1029410 100644 (file)
@@ -1351,6 +1351,7 @@ fn my_visit_expr(expr: &hir::Expr,
 
             rbml_w.start_tag(tag_items_data_item);
             encode_def_id_and_key(ecx, rbml_w, def_id);
+            encode_name(rbml_w, syntax::parse::token::intern("<closure>"));
 
             rbml_w.start_tag(tag_items_closure_ty);
             write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]);
@@ -1505,7 +1506,7 @@ fn encode_polarity(rbml_w: &mut Encoder, polarity: hir::ImplPolarity) {
 
 fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
     fn get_ordered_deps(cstore: &cstore::CStore)
-                        -> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
+                        -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
         // Pull the cnums and name,vers,hash out of cstore
         let mut deps = Vec::new();
         cstore.iter_crate_data(|cnum, val| {
@@ -1736,7 +1737,7 @@ fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 }
 
 fn encode_crate_dep(rbml_w: &mut Encoder,
-                    dep: &cstore::crate_metadata) {
+                    dep: &cstore::CrateMetadata) {
     rbml_w.start_tag(tag_crate_dep);
     rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
     let hash = decoder::get_crate_hash(dep.data());
@@ -1798,10 +1799,6 @@ fn encode_panic_strategy(rbml_w: &mut Encoder, ecx: &EncodeContext) {
     }
 }
 
-// NB: Increment this as you change the metadata encoding version.
-#[allow(non_upper_case_globals)]
-pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
-
 pub fn encode_metadata(ecx: EncodeContext, krate: &hir::Crate) -> Vec<u8> {
     let mut wr = Cursor::new(Vec::new());
 
@@ -1835,12 +1832,25 @@ pub fn encode_metadata(ecx: EncodeContext, krate: &hir::Crate) -> Vec<u8> {
     // the length of the metadata to the start of the metadata. Later on this
     // will allow us to slice the metadata to the precise length that we just
     // generated regardless of trailing bytes that end up in it.
-    let len = v.len() as u32;
-    v.insert(0, (len >>  0) as u8);
-    v.insert(0, (len >>  8) as u8);
-    v.insert(0, (len >> 16) as u8);
-    v.insert(0, (len >> 24) as u8);
-    return v;
+    //
+    // We also need to store the metadata encoding version here, because
+    // rlibs don't have it. To get older versions of rustc to ignore
+    // this metadata, there are 4 zero bytes at the start, which are
+    // treated as a length of 0 by old compilers.
+
+    let len = v.len();
+    let mut result = vec![];
+    result.push(0);
+    result.push(0);
+    result.push(0);
+    result.push(0);
+    result.extend(metadata_encoding_version.iter().cloned());
+    result.push((len >> 24) as u8);
+    result.push((len >> 16) as u8);
+    result.push((len >>  8) as u8);
+    result.push((len >>  0) as u8);
+    result.extend(v);
+    result
 }
 
 fn encode_metadata_inner(rbml_w: &mut Encoder,
index 1cf7282e9e95fe4bce706151681e275a7ac67f33..cd92493e3db703adc8e7931d51357fbc6292406f 100644 (file)
@@ -36,6 +36,7 @@
 
 #[macro_use]
 extern crate rustc;
+extern crate rustc_data_structures;
 extern crate rustc_back;
 extern crate rustc_llvm;
 extern crate rustc_const_math;
index 56393b79980f62a75107e315267ee7556fd1df24..48c8bcff1ec560a12db7bdba3f24b9be15b922ba 100644 (file)
 //! metadata::loader or metadata::creader for all the juicy details!
 
 use cstore::{MetadataBlob, MetadataVec, MetadataArchive};
+use common::{metadata_encoding_version, rustc_version};
 use decoder;
-use encoder;
 
 use rustc::hir::svh::Svh;
 use rustc::session::Session;
@@ -260,6 +260,7 @@ pub struct Context<'a> {
     pub rejected_via_hash: Vec<CrateMismatch>,
     pub rejected_via_triple: Vec<CrateMismatch>,
     pub rejected_via_kind: Vec<CrateMismatch>,
+    pub rejected_via_version: Vec<CrateMismatch>,
     pub should_match_name: bool,
 }
 
@@ -336,6 +337,10 @@ pub fn report_load_errs(&mut self) -> ! {
             struct_span_err!(self.sess, self.span, E0462,
                              "found staticlib `{}` instead of rlib or dylib{}",
                              self.ident, add)
+        } else if !self.rejected_via_version.is_empty() {
+            struct_span_err!(self.sess, self.span, E0514,
+                             "found crate `{}` compiled by an incompatible version of rustc{}",
+                             self.ident, add)
         } else {
             struct_span_err!(self.sess, self.span, E0463,
                              "can't find crate for `{}`{}",
@@ -350,7 +355,7 @@ pub fn report_load_errs(&mut self) -> ! {
             }
         }
         if !self.rejected_via_hash.is_empty() {
-            err.note("perhaps this crate needs to be recompiled?");
+            err.note("perhaps that crate needs to be recompiled?");
             let mismatches = self.rejected_via_hash.iter();
             for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
                 err.note(&format!("crate `{}` path #{}: {}",
@@ -367,13 +372,22 @@ pub fn report_load_errs(&mut self) -> ! {
             }
         }
         if !self.rejected_via_kind.is_empty() {
-            err.help("please recompile this crate using --crate-type lib");
+            err.help("please recompile that crate using --crate-type lib");
             let mismatches = self.rejected_via_kind.iter();
             for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
                 err.note(&format!("crate `{}` path #{}: {}",
                                   self.ident, i+1, path.display()));
             }
         }
+        if !self.rejected_via_version.is_empty() {
+            err.help(&format!("please recompile that crate using this compiler ({})",
+                              rustc_version()));
+            let mismatches = self.rejected_via_version.iter();
+            for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() {
+                err.note(&format!("crate `{}` path #{}: {} compiled by {:?}",
+                                  self.ident, i+1, path.display(), got));
+            }
+        }
 
         err.emit();
         self.sess.abort_if_errors();
@@ -489,19 +503,11 @@ fn find_library_crate(&mut self) -> Option<Library> {
                                                self.crate_name);
                 err.note("candidates:");
                 for (_, lib) in libraries {
-                    match lib.dylib {
-                        Some((ref p, _)) => {
-                            err.note(&format!("path: {}",
-                                              p.display()));
-                        }
-                        None => {}
+                    if let Some((ref p, _)) = lib.dylib {
+                        err.note(&format!("path: {}", p.display()));
                     }
-                    match lib.rlib {
-                        Some((ref p, _)) => {
-                            err.note(&format!("path: {}",
-                                              p.display()));
-                        }
-                        None => {}
+                    if let Some((ref p, _)) = lib.rlib {
+                        err.note(&format!("path: {}", p.display()));
                     }
                     let data = lib.metadata.as_slice();
                     let name = decoder::get_crate_name(data);
@@ -591,6 +597,17 @@ fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: CrateFlavor,
     }
 
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> Option<Svh> {
+        let crate_rustc_version = decoder::crate_rustc_version(crate_data);
+        if crate_rustc_version != Some(rustc_version()) {
+            let message = crate_rustc_version.unwrap_or(format!("an unknown compiler"));
+            info!("Rejecting via version: expected {} got {}", rustc_version(), message);
+            self.rejected_via_version.push(CrateMismatch {
+                path: libpath.to_path_buf(),
+                got: message
+            });
+            return None;
+        }
+
         if self.should_match_name {
             match decoder::maybe_get_crate_name(crate_data) {
                 Some(ref name) if self.crate_name == *name => {}
@@ -742,6 +759,21 @@ fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
     pub fn as_slice<'a>(&'a self) -> &'a [u8] { unsafe { &*self.data } }
 }
 
+fn verify_decompressed_encoding_version(blob: &MetadataBlob, filename: &Path)
+                                        -> Result<(), String>
+{
+    let data = blob.as_slice_raw();
+    if data.len() < 4+metadata_encoding_version.len() ||
+        !<[u8]>::eq(&data[..4], &[0, 0, 0, 0]) ||
+        &data[4..4+metadata_encoding_version.len()] != metadata_encoding_version
+    {
+        Err((format!("incompatible metadata version found: '{}'",
+                     filename.display())))
+    } else {
+        Ok(())
+    }
+}
+
 // Just a small wrapper to time how long reading metadata takes.
 fn get_metadata_section(target: &Target, flavor: CrateFlavor, filename: &Path)
                         -> Result<MetadataBlob, String> {
@@ -772,7 +804,10 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
         return match ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)) {
             None => Err(format!("failed to read rlib metadata: '{}'",
                                 filename.display())),
-            Some(blob) => Ok(blob)
+            Some(blob) => {
+                try!(verify_decompressed_encoding_version(&blob, filename));
+                Ok(blob)
+            }
         };
     }
     unsafe {
@@ -801,12 +836,12 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
                 let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
                 let cvbuf: *const u8 = cbuf as *const u8;
-                let vlen = encoder::metadata_encoding_version.len();
+                let vlen = metadata_encoding_version.len();
                 debug!("checking {} bytes of metadata-version stamp",
                        vlen);
                 let minsz = cmp::min(vlen, csz);
                 let buf0 = slice::from_raw_parts(cvbuf, minsz);
-                let version_ok = buf0 == encoder::metadata_encoding_version;
+                let version_ok = buf0 == metadata_encoding_version;
                 if !version_ok {
                     return Err((format!("incompatible metadata version found: '{}'",
                                         filename.display())));
@@ -817,7 +852,11 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
                        csz - vlen);
                 let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
                 match flate::inflate_bytes(bytes) {
-                    Ok(inflated) => return Ok(MetadataVec(inflated)),
+                    Ok(inflated) => {
+                        let blob = MetadataVec(inflated);
+                        try!(verify_decompressed_encoding_version(&blob, filename));
+                        return Ok(blob);
+                    }
                     Err(_) => {}
                 }
             }
index d96996a017986ca2304080948a7f83d0740c1779..119640af463aa8bf768dddfc23ede46bd996df88 100644 (file)
@@ -396,16 +396,13 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
 
                 let pos = self.parse_vuint();
                 let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
-                match tcx.rcache.borrow().get(&key).cloned() {
-                    Some(tt) => {
-                        // If there is a closure buried in the type some where, then we
-                        // need to re-convert any def ids (see case 'k', below). That means
-                        // we can't reuse the cached version.
-                        if !tt.has_closure_types() {
-                            return tt;
-                        }
+                if let Some(tt) = tcx.rcache.borrow().get(&key).cloned() {
+                    // If there is a closure buried in the type some where, then we
+                    // need to re-convert any def ids (see case 'k', below). That means
+                    // we can't reuse the cached version.
+                    if !tt.has_closure_types() {
+                        return tt;
                     }
-                    None => {}
                 }
 
                 let mut substate = TyDecoder::new(self.data,
index 2b8ba107fefc6c35586c6fd7db3bc2ec2d9c4cbb..1afeccdf8e3a9b9a6735f0472f7f8e21aa60e40c 100644 (file)
@@ -64,9 +64,9 @@ pub struct ty_abbrev {
 pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
 
 pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
-    match cx.abbrevs.borrow_mut().get(&t) {
-        Some(a) => { w.write_all(&a.s); return; }
-        None => {}
+    if let Some(a) = cx.abbrevs.borrow_mut().get(&t) {
+        w.write_all(&a.s);
+        return;
     }
 
     let pos = w.position();
index 54e2cb929b87a38ebab56d1aa1285941ee3199b5..91ecad8402fd40b2df5e50b97da5d7910d8c7614 100644 (file)
 // LLVM, which causes makes compilation very slow. See #28273.
 #[inline(never)]
 pub fn find(name: &str) -> Option<Intrinsic> {
-    if !name.starts_with("x86_mm") { return None }
-    Some(match &name["x86_mm".len()..] {
-        "_movemask_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse.movmsk.ps")
+    if !name.starts_with("x86") { return None }
+    Some(match &name["x86".len()..] {
+        "_mm256_abs_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.pabs.b")
         },
-        "_max_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse.max.ps")
+        "_mm256_abs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pabs.w")
         },
-        "_min_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse.min.ps")
+        "_mm256_abs_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.pabs.d")
         },
-        "_rsqrt_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse.rsqrt.ps")
+        "_mm256_adds_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.padds.b")
         },
-        "_rcp_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse.rcp.ps")
+        "_mm256_adds_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.paddus.b")
         },
-        "_sqrt_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.sqrt.v4f32")
+        "_mm256_adds_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.padds.w")
         },
-        "_storeu_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), false); &PTR }, &::F32x4]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.sse.storeu.ps")
+        "_mm256_adds_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.paddus.w")
         },
-        "_adds_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse2.padds.b")
+        "_mm256_avg_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.pavg.b")
         },
-        "_adds_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.paddus.b")
+        "_mm256_avg_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.pavg.w")
         },
-        "_adds_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.padds.w")
+        "_mm256_hadd_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.phadd.w")
         },
-        "_adds_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse2.paddus.w")
+        "_mm256_hadd_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.phadd.d")
         },
-        "_avg_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.pavg.b")
+        "_mm256_hadds_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.phadd.sw")
         },
-        "_avg_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse2.pavg.w")
+        "_mm256_hsub_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.phsub.w")
         },
-        "_lfence" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.sse2.lfence")
+        "_mm256_hsub_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.phsub.d")
         },
-        "_madd_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+        "_mm256_hsubs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.phsub.sw")
+        },
+        "_mm256_madd_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.pmadd.wd")
+        },
+        "_mm256_maddubs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pmadd.ub.sw")
+        },
+        "_mm_mask_i32gather_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I32x4, &::I32x4, &::I32_8]; &INPUTS },
             output: &::I32x4,
-            definition: Named("llvm.x86.sse2.pmadd.wd")
+            definition: Named("llvm.x86.avx2.gather.d.d")
         },
-        "_maskmoveu_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x16, &::U8x16, { static PTR: Type = Type::Pointer(&::U8, None, false); &PTR }]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.sse2.maskmov.dqu")
+        "_mm_mask_i32gather_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x4, &::I32x4_F32, &::I32_8]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.avx2.gather.d.ps")
         },
-        "_max_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.pmaxs.w")
+        "_mm256_mask_i32gather_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x8, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I32x8, &::I32x8, &::I32_8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.gather.d.d.256")
         },
-        "_max_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.pmaxu.b")
+        "_mm256_mask_i32gather_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x8, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x8, &::I32x8_F32, &::I32_8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.avx2.gather.d.ps.256")
         },
-        "_max_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+        "_mm_mask_i32gather_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x2, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x2, &::I32_8]; &INPUTS },
+            output: &::I64x2,
+            definition: Named("llvm.x86.avx2.gather.d.q")
+        },
+        "_mm_mask_i32gather_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x2, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x2_F64, &::I32_8]; &INPUTS },
             output: &::F64x2,
-            definition: Named("llvm.x86.sse2.max.pd")
+            definition: Named("llvm.x86.avx2.gather.d.pd")
         },
-        "_mfence" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.sse2.fence")
+        "_mm256_mask_i32gather_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x4, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x4, &::I32_8]; &INPUTS },
+            output: &::I64x4,
+            definition: Named("llvm.x86.avx2.gather.d.q.256")
         },
-        "_min_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.pmins.w")
+        "_mm256_mask_i32gather_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x4, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x4_F64, &::I32_8]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.avx2.gather.d.pd.256")
         },
-        "_min_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.pminu.b")
+        "_mm_mask_i64gather_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I64x2, &::I32x4, &::I32_8]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.avx2.gather.q.d")
         },
-        "_min_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.sse2.min.pd")
+        "_mm_mask_i64gather_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I64x2, &::I32x4_F32, &::I32_8]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.avx2.gather.q.ps")
         },
-        "_movemask_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F64x2]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse2.movmsk.pd")
+        "_mm256_mask_i64gather_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I64x4, &::I32x4, &::I32_8]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.avx2.gather.q.d")
         },
-        "_movemask_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x16]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse2.pmovmskb.128")
+        "_mm256_mask_i64gather_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I64x4, &::I32x4_F32, &::I32_8]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.avx2.gather.q.ps")
         },
-        "_mul_epu32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
-            output: &::U64x2,
-            definition: Named("llvm.x86.sse2.pmulu.dq")
+        "_mm_mask_i64gather_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x2, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I64x2, &::I64x2, &::I32_8]; &INPUTS },
+            output: &::I64x2,
+            definition: Named("llvm.x86.avx2.gather.q.q")
         },
-        "_mulhi_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.pmulh.w")
+        "_mm_mask_i64gather_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x2, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x2, &::I64x2_F64, &::I32_8]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.avx2.gather.q.pd")
         },
-        "_mulhi_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse2.pmulhu.w")
+        "_mm256_mask_i64gather_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x4, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I64x4, &::I64x4, &::I32_8]; &INPUTS },
+            output: &::I64x4,
+            definition: Named("llvm.x86.avx2.gather.q.q.256")
         },
-        "_packs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse2.packsswb.128")
+        "_mm256_mask_i64gather_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x4, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x4, &::I64x4_F64, &::I32_8]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.avx2.gather.q.pd.256")
         },
-        "_packs_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.packssdw.128")
+        "_mm_maskload_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I32x4, Some(&::I8), true); &PTR }, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.avx2.maskload.d")
         },
-        "_packus_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.packuswb.128")
+        "_mm_maskload_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I64x2, Some(&::I8), true); &PTR }, &::I64x2]; &INPUTS },
+            output: &::I64x2,
+            definition: Named("llvm.x86.avx2.maskload.q")
         },
-        "_sad_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U64x2,
-            definition: Named("llvm.x86.sse2.psad.bw")
+        "_mm256_maskload_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I32x8, Some(&::I8), true); &PTR }, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.maskload.d.256")
         },
-        "_sfence" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
+        "_mm256_maskload_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I64x4, Some(&::I8), true); &PTR }, &::I64x4]; &INPUTS },
+            output: &::I64x4,
+            definition: Named("llvm.x86.avx2.maskload.q.256")
+        },
+        "_mm_maskstore_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I32, Some(&::I8), false); &PTR }, &::I32x4, &::I32x4]; &INPUTS },
             output: &::VOID,
-            definition: Named("llvm.x86.sse2.sfence")
+            definition: Named("llvm.x86.avx2.maskstore.d")
         },
-        "_sqrt_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.sqrt.v2f64")
+        "_mm_maskstore_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I64, Some(&::I8), false); &PTR }, &::I64x2, &::I64x2]; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.avx2.maskstore.q")
         },
-        "_storeu_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::U8), false); &PTR }, &::F64x2]; &INPUTS },
+        "_mm256_maskstore_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I32, Some(&::I8), false); &PTR }, &::I32x8, &::I32x8]; &INPUTS },
             output: &::VOID,
-            definition: Named("llvm.x86.sse2.storeu.pd")
+            definition: Named("llvm.x86.avx2.maskstore.d.256")
         },
-        "_storeu_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::U8x16, Some(&::U8), false); &PTR }, &::U8x16]; &INPUTS },
+        "_mm256_maskstore_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I64, Some(&::I8), false); &PTR }, &::I64x4, &::I64x4]; &INPUTS },
             output: &::VOID,
-            definition: Named("llvm.x86.sse2.storeu.dq")
+            definition: Named("llvm.x86.avx2.maskstore.q.256")
         },
-        "_subs_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse2.psubs.b")
+        "_mm256_max_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.pmaxs.b")
         },
-        "_subs_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse2.psubus.b")
+        "_mm256_max_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.pmaxu.b")
         },
-        "_subs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.sse2.psubs.w")
+        "_mm256_max_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pmaxs.w")
         },
-        "_subs_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse2.psubus.w")
+        "_mm256_max_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.pmaxu.w")
         },
-        "_addsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse3.addsub.ps")
+        "_mm256_max_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.pmaxs.d")
         },
-        "_addsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.sse3.addsub.pd")
-        },
-        "_hadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse3.hadd.ps")
-        },
-        "_hadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.sse3.hadd.pd")
-        },
-        "_hsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse3.hsub.ps")
-        },
-        "_hsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.sse3.hsub.pd")
-        },
-        "_lddqu_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [{ static PTR: Type = Type::Pointer(&::U8x16, Some(&::I8), true); &PTR }]; &INPUTS },
-            output: &::U8x16,
-            definition: Named("llvm.x86.sse3.ldu.dq")
-        },
-        "_abs_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.ssse3.pabs.b.128")
-        },
-        "_abs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.pabs.w.128")
-        },
-        "_abs_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.ssse3.pabs.d.128")
-        },
-        "_hadd_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.phadd.w.128")
-        },
-        "_hadd_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.ssse3.phadd.d.128")
-        },
-        "_hadds_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.phadd.sw.128")
-        },
-        "_hsub_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.phsub.w.128")
-        },
-        "_hsub_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.ssse3.phsub.d.128")
-        },
-        "_hsubs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.phsub.sw.128")
-        },
-        "_maddubs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::I8x16]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.pmadd.ub.sw.128")
-        },
-        "_mulhrs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.pmul.hr.sw.128")
-        },
-        "_shuffle_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.ssse3.pshuf.b.128")
-        },
-        "_sign_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.ssse3.psign.b.128")
-        },
-        "_sign_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
-            output: &::I16x8,
-            definition: Named("llvm.x86.ssse3.psign.w.128")
-        },
-        "_sign_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.ssse3.psign.d.128")
-        },
-        "_dp_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::I32_8]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.sse41.dpps")
-        },
-        "_dp_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::I32_8]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.sse41.dppd")
-        },
-        "_max_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse41.pmaxsb")
+        "_mm256_max_epu32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
+            output: &::U32x8,
+            definition: Named("llvm.x86.avx2.pmaxu.d")
         },
-        "_max_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse41.pmaxuw")
+        "_mm256_min_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.pmins.b")
         },
-        "_max_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.sse41.pmaxsd")
+        "_mm256_min_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.pminu.b")
         },
-        "_max_epu32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
-            output: &::U32x4,
-            definition: Named("llvm.x86.sse41.pmaxud")
+        "_mm256_min_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pmins.w")
         },
-        "_min_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse41.pminsb")
+        "_mm256_min_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.pminu.w")
         },
-        "_min_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse41.pminuw")
+        "_mm256_min_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.pmins.d")
         },
-        "_min_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.sse41.pminsd")
+        "_mm256_min_epu32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
+            output: &::U32x8,
+            definition: Named("llvm.x86.avx2.pminu.d")
         },
-        "_min_epu32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
-            output: &::U32x4,
-            definition: Named("llvm.x86.sse41.pminud")
+        "_mm256_movemask_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x32]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.avx2.pmovmskb")
         },
-        "_minpos_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::U16x8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse41.phminposuw")
+        "_mm256_mpsadbw_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x32, &::U8x32, &::I32_8]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.mpsadbw")
         },
-        "_mpsadbw_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x16, &::U8x16, &::I32_8]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse41.mpsadbw")
+        "_mm256_mul_epi64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I64x4,
+            definition: Named("llvm.x86.avx2.pmulq.dq")
         },
-        "_mul_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::I64x2,
-            definition: Named("llvm.x86.sse41.pmuldq")
+        "_mm256_mul_epu64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
+            output: &::U64x4,
+            definition: Named("llvm.x86.avx2.pmulq.dq")
         },
-        "_packus_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
-            output: &::U16x8,
-            definition: Named("llvm.x86.sse41.packusdw")
+        "_mm256_mulhi_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pmulhw.w")
         },
-        "_testc_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse41.ptestc")
+        "_mm256_mulhi_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.pmulhw.w")
         },
-        "_testnzc_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse41.ptestnzc")
+        "_mm256_mulhrs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.pmul.hr.sw")
         },
-        "_testz_si128" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse41.ptestz")
+        "_mm256_packs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.packsswb")
         },
-        "_cmpestra" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestria128")
+        "_mm256_packus_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.packuswb")
         },
-        "_cmpestrc" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestric128")
+        "_mm256_packs_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.packssdw")
         },
-        "_cmpestri" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestri128")
+        "_mm256_packus_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.packusdw")
         },
-        "_cmpestrm" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse42.pcmpestrm128")
+        "_mm256_permutevar8x32_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.permd")
         },
-        "_cmpestro" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestrio128")
+        "_mm256_permutevar8x32_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::I32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.avx2.permps")
         },
-        "_cmpestrs" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestris128")
+        "_mm256_sad_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.psad.bw")
         },
-        "_cmpestrz" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpestriz128")
+        "_mm256_shuffle_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.pshuf.b")
         },
-        "_cmpistra" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistria128")
+        "_mm256_sign_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.psign.b")
         },
-        "_cmpistrc" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistric128")
+        "_mm256_sign_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.psign.w")
         },
-        "_cmpistri" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistri128")
+        "_mm256_sign_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
+            output: &::I32x8,
+            definition: Named("llvm.x86.avx2.psign.d")
         },
-        "_cmpistrm" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I8x16,
-            definition: Named("llvm.x86.sse42.pcmpistrm128")
+        "_mm256_subs_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
+            output: &::I8x32,
+            definition: Named("llvm.x86.avx2.psubs.b")
         },
-        "_cmpistro" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistrio128")
+        "_mm256_subs_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
+            output: &::U8x32,
+            definition: Named("llvm.x86.avx2.psubus.b")
         },
-        "_cmpistrs" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistris128")
+        "_mm256_subs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
+            output: &::I16x16,
+            definition: Named("llvm.x86.avx2.psubs.w")
         },
-        "_cmpistrz" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.sse42.pcmpistriz128")
+        "_mm256_subs_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
+            output: &::U16x16,
+            definition: Named("llvm.x86.avx2.psubus.w")
         },
-        "256_addsub_ps" => Intrinsic {
+        "_mm256_addsub_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.addsub.ps.256")
         },
-        "256_addsub_pd" => Intrinsic {
+        "_mm256_addsub_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.addsub.pd.256")
         },
-        "256_blendv_ps" => Intrinsic {
+        "_mm256_blendv_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.blendv.ps.256")
         },
-        "256_blendv_pd" => Intrinsic {
+        "_mm256_blendv_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.blendv.pd.256")
         },
-        "256_broadcast_ps" => Intrinsic {
+        "_mm256_broadcast_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [{ static PTR: Type = Type::Pointer(&::I8, None, true); &PTR }]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.vbroadcastf128.ps.256")
         },
-        "256_broadcast_pd" => Intrinsic {
+        "_mm256_broadcast_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [{ static PTR: Type = Type::Pointer(&::I8, None, true); &PTR }]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.vbroadcastf128.pd.256")
         },
-        "256_cmp_ps" => Intrinsic {
+        "_mm256_cmp_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::I8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.cmp.ps.256")
         },
-        "256_cmp_pd" => Intrinsic {
+        "_mm256_cmp_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::I8]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.cmp.pd.256")
         },
-        "256_cvtepi32_pd" => Intrinsic {
+        "_mm256_cvtepi32_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::I32x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.cvtdq2.pd.256")
         },
-        "256_cvtepi32_ps" => Intrinsic {
+        "_mm256_cvtepi32_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::I32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.cvtdq2.ps.256")
         },
-        "256_cvtpd_epi32" => Intrinsic {
+        "_mm256_cvtpd_epi32" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F64x4]; &INPUTS },
             output: &::I32x4,
             definition: Named("llvm.x86.avx.cvt.pd2dq.256")
         },
-        "256_cvtpd_ps" => Intrinsic {
+        "_mm256_cvtpd_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F64x4]; &INPUTS },
             output: &::F32x4,
             definition: Named("llvm.x86.avx.cvt.pd2.ps.256")
         },
-        "256_cvtps_epi32" => Intrinsic {
+        "_mm256_cvtps_epi32" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::I32x8,
             definition: Named("llvm.x86.avx.cvt.ps2dq.256")
         },
-        "256_cvtps_pd" => Intrinsic {
+        "_mm256_cvtps_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.cvt.ps2.pd.256")
         },
-        "256_cvttpd_epi32" => Intrinsic {
+        "_mm256_cvttpd_epi32" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F64x4]; &INPUTS },
             output: &::I32x4,
             definition: Named("llvm.x86.avx.cvtt.pd2dq.256")
         },
-        "256_cvttps_epi32" => Intrinsic {
+        "_mm256_cvttps_epi32" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::I32x8,
             definition: Named("llvm.x86.avx.cvtt.ps2dq.256")
         },
-        "256_dp_ps" => Intrinsic {
+        "_mm256_dp_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::I32_8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.dp.ps.256")
         },
-        "256_hadd_ps" => Intrinsic {
+        "_mm256_hadd_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.hadd.ps.256")
         },
-        "256_hadd_pd" => Intrinsic {
+        "_mm256_hadd_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.hadd.pd.256")
         },
-        "256_hsub_ps" => Intrinsic {
+        "_mm256_hsub_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.hsub.ps.256")
         },
-        "256_hsub_pd" => Intrinsic {
+        "_mm256_hsub_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.hsub.pd.256")
         },
-        "256_max_ps" => Intrinsic {
+        "_mm256_max_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.max.ps.256")
         },
-        "256_max_pd" => Intrinsic {
+        "_mm256_max_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.max.pd.256")
         },
-        "_maskload_ps" => Intrinsic {
+        "_mm_maskload_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x4_F32]; &INPUTS },
             output: &::F32x4,
             definition: Named("llvm.x86.avx.maskload.ps")
         },
-        "_maskload_pd" => Intrinsic {
+        "_mm_maskload_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x2_F64]; &INPUTS },
             output: &::F64x2,
             definition: Named("llvm.x86.avx.maskload.pd")
         },
-        "256_maskload_ps" => Intrinsic {
+        "_mm256_maskload_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x8_F32]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.maskload.ps.256")
         },
-        "256_maskload_pd" => Intrinsic {
+        "_mm256_maskload_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x4_F64]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.maskload.pd.256")
         },
-        "_maskstore_ps" => Intrinsic {
+        "_mm_maskstore_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), false); &PTR }, &::I32x4_F32, &::F32x4]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.maskstore.ps")
         },
-        "_maskstore_pd" => Intrinsic {
+        "_mm_maskstore_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::I8), false); &PTR }, &::I64x2_F64, &::F64x2]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.maskstore.pd")
         },
-        "256_maskstore_ps" => Intrinsic {
+        "_mm256_maskstore_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), false); &PTR }, &::I32x8_F32, &::F32x8]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.maskstore.ps.256")
         },
-        "256_maskstore_pd" => Intrinsic {
+        "_mm256_maskstore_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::I8), false); &PTR }, &::I64x4_F64, &::F64x4]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.maskstore.pd.256")
         },
-        "256_min_ps" => Intrinsic {
+        "_mm256_min_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.min.ps.256")
         },
-        "256_min_pd" => Intrinsic {
+        "_mm256_min_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.min.pd.256")
         },
-        "256_movemask_ps" => Intrinsic {
+        "_mm256_movemask_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.movmsk.ps.256")
         },
-        "256_movemask_pd" => Intrinsic {
+        "_mm256_movemask_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.movmsk.pd.256")
         },
-        "_permutevar_ps" => Intrinsic {
+        "_mm_permutevar_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::I32x4]; &INPUTS },
             output: &::F32x4,
             definition: Named("llvm.x86.avx.vpermilvar.ps")
         },
-        "_permutevar_pd" => Intrinsic {
+        "_mm_permutevar_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::I64x2]; &INPUTS },
             output: &::F64x2,
             definition: Named("llvm.x86.avx.vpermilvar.pd")
         },
-        "256_permutevar_ps" => Intrinsic {
+        "_mm256_permutevar_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::I32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.vpermilvar.ps.256")
         },
-        "256_permutevar_pd" => Intrinsic {
+        "_mm256_permutevar_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::I64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.x86.avx.vpermilvar.pd.256")
         },
-        "256_rcp_ps" => Intrinsic {
+        "_mm256_rcp_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.rcp.ps.256")
         },
-        "256_rsqrt_ps" => Intrinsic {
+        "_mm256_rsqrt_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.x86.avx.rsqrt.ps.256")
         },
-        "256_storeu_ps" => Intrinsic {
+        "_mm256_storeu_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F32x8, Some(&::U8), false); &PTR }, &::F32x8]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.storeu.ps.256")
         },
-        "256_storeu_pd" => Intrinsic {
+        "_mm256_storeu_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F64x4, Some(&::U8), false); &PTR }, &::F64x4]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.storeu.ps.256")
         },
-        "256_storeu_si256" => Intrinsic {
+        "_mm256_storeu_si256" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::U8x32, Some(&::U8), false); &PTR }, &::U8x32]; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.storeu.dq.256")
         },
-        "256_sqrt_ps" => Intrinsic {
+        "_mm256_sqrt_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F32x8]; &INPUTS },
             output: &::F32x8,
             definition: Named("llvm.sqrt.v8f32")
         },
-        "256_sqrt_pd" => Intrinsic {
+        "_mm256_sqrt_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 1] = [&::F64x4]; &INPUTS },
             output: &::F64x4,
             definition: Named("llvm.sqrt.v4f64")
         },
-        "_testc_ps" => Intrinsic {
+        "_mm_testc_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestc.ps")
         },
-        "256_testc_ps" => Intrinsic {
+        "_mm256_testc_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestc.ps.256")
         },
-        "_testc_pd" => Intrinsic {
+        "_mm_testc_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestc.pd")
         },
-        "256_testc_pd" => Intrinsic {
+        "_mm256_testc_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestc.pd.256")
         },
-        "256_testc_si256" => Intrinsic {
+        "_mm256_testc_si256" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::U64x4, &::U64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.ptestc.256")
         },
-        "_testnzc_ps" => Intrinsic {
+        "_mm_testnzc_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestnzc.ps")
         },
-        "256_testnzc_ps" => Intrinsic {
+        "_mm256_testnzc_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestnzc.ps.256")
         },
-        "_testnzc_pd" => Intrinsic {
+        "_mm_testnzc_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestnzc.pd")
         },
-        "256_testnzc_pd" => Intrinsic {
+        "_mm256_testnzc_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestnzc.pd.256")
         },
-        "256_testnzc_si256" => Intrinsic {
+        "_mm256_testnzc_si256" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::U64x4, &::U64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.ptestnzc.256")
         },
-        "_testz_ps" => Intrinsic {
+        "_mm_testz_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestz.ps")
         },
-        "256_testz_ps" => Intrinsic {
+        "_mm256_testz_ps" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::F32x8]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestz.ps.256")
         },
-        "_testz_pd" => Intrinsic {
+        "_mm_testz_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestz.pd")
         },
-        "256_testz_pd" => Intrinsic {
+        "_mm256_testz_pd" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::F64x4, &::F64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.vtestz.pd.256")
         },
-        "256_testz_si256" => Intrinsic {
+        "_mm256_testz_si256" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 2] = [&::U64x4, &::U64x4]; &INPUTS },
             output: &::I32,
             definition: Named("llvm.x86.avx.ptestz.256")
         },
-        "256_zeroall" => Intrinsic {
+        "_mm256_zeroall" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.vzeroall")
         },
-        "256_zeroupper" => Intrinsic {
+        "_mm256_zeroupper" => Intrinsic {
             inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
             output: &::VOID,
             definition: Named("llvm.x86.avx.vzeroupper")
         },
-        "256_abs_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.pabs.b")
+        "_bmi2_bzhi_32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32, &::U32]; &INPUTS },
+            output: &::U32,
+            definition: Named("llvm.x86.bmi.bzhi.32")
+        },
+        "_bmi2_bzhi_64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64, &::U64]; &INPUTS },
+            output: &::U64,
+            definition: Named("llvm.x86.bmi.bzhi.64")
+        },
+        "_bmi2_pdep_32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32, &::U32]; &INPUTS },
+            output: &::U32,
+            definition: Named("llvm.x86.bmi.pdep.32")
+        },
+        "_bmi2_pdep_64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64, &::U64]; &INPUTS },
+            output: &::U64,
+            definition: Named("llvm.x86.bmi.pdep.64")
+        },
+        "_bmi2_pext_32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32, &::U32]; &INPUTS },
+            output: &::U32,
+            definition: Named("llvm.x86.bmi.pext.32")
+        },
+        "_bmi2_pext_64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64, &::U64]; &INPUTS },
+            output: &::U64,
+            definition: Named("llvm.x86.bmi.pext.64")
+        },
+        "_bmi_bextr_32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32, &::U32]; &INPUTS },
+            output: &::U32,
+            definition: Named("llvm.x86.bmi.bextr.32")
+        },
+        "_bmi_bextr_64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64, &::U64]; &INPUTS },
+            output: &::U64,
+            definition: Named("llvm.x86.bmi.bextr.64")
+        },
+        "_mm_fmadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfmadd.ps")
         },
-        "256_abs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pabs.w")
+        "_mm_fmadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfmadd.pd")
         },
-        "256_abs_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.pabs.d")
+        "_mm256_fmadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfmadd.ps.256")
         },
-        "256_adds_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.padds.b")
+        "_mm256_fmadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfmadd.pd.256")
         },
-        "256_adds_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.paddus.b")
+        "_mm_fmaddsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfmaddsub.ps")
         },
-        "256_adds_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.padds.w")
+        "_mm_fmaddsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfmaddsub.pd")
         },
-        "256_adds_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.paddus.w")
+        "_mm256_fmaddsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfmaddsub.ps.256")
         },
-        "256_avg_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.pavg.b")
+        "_mm256_fmaddsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfmaddsub.pd.256")
         },
-        "256_avg_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.pavg.w")
+        "_mm_fmsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfmsub.ps")
         },
-        "256_hadd_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.phadd.w")
+        "_mm_fmsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfmsub.pd")
         },
-        "256_hadd_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.phadd.d")
+        "_mm256_fmsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfmsub.ps.256")
         },
-        "256_hadds_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.phadd.sw")
+        "_mm256_fmsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfmsub.pd.256")
+        },
+        "_mm_fmsubadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfmsubadd.ps")
+        },
+        "_mm_fmsubadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfmsubadd.pd")
+        },
+        "_mm256_fmsubadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfmsubadd.ps.256")
+        },
+        "_mm256_fmsubadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfmsubadd.pd.256")
+        },
+        "_mm_fnmadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfnmadd.ps")
+        },
+        "_mm_fnmadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfnmadd.pd")
+        },
+        "_mm256_fnmadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfnmadd.ps.256")
+        },
+        "_mm256_fnmadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfnmadd.pd.256")
+        },
+        "_mm_fnmsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.fma.vfnmsub.ps")
+        },
+        "_mm_fnmsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.fma.vfnmsub.pd")
+        },
+        "_mm256_fnmsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
+            output: &::F32x8,
+            definition: Named("llvm.x86.fma.vfnmsub.ps.256")
+        },
+        "_mm256_fnmsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
+            output: &::F64x4,
+            definition: Named("llvm.x86.fma.vfnmsub.pd.256")
+        },
+        "_mm_adds_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse2.padds.b")
+        },
+        "_mm_adds_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.paddus.b")
+        },
+        "_mm_adds_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.padds.w")
+        },
+        "_mm_adds_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse2.paddus.w")
+        },
+        "_mm_avg_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.pavg.b")
+        },
+        "_mm_avg_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse2.pavg.w")
+        },
+        "_mm_lfence" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.lfence")
+        },
+        "_mm_madd_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.sse2.pmadd.wd")
         },
-        "256_hsub_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.phsub.w")
+        "_mm_maskmoveu_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x16, &::U8x16, { static PTR: Type = Type::Pointer(&::U8, None, false); &PTR }]; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.maskmov.dqu")
         },
-        "256_hsub_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.phsub.d")
+        "_mm_max_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.pmaxs.w")
         },
-        "256_hsubs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.phsub.sw")
+        "_mm_max_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.pmaxu.b")
         },
-        "256_madd_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.pmadd.wd")
+        "_mm_max_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse2.max.pd")
         },
-        "256_maddubs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pmadd.ub.sw")
+        "_mm_mfence" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.fence")
         },
-        "_mask_i32gather_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I32x4, &::I32x4, &::I32_8]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.avx2.gather.d.d")
+        "_mm_min_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.pmins.w")
         },
-        "_mask_i32gather_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x4, &::I32x4_F32, &::I32_8]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.avx2.gather.d.ps")
+        "_mm_min_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.pminu.b")
         },
-        "256_mask_i32gather_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x8, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I32x8, &::I32x8, &::I32_8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.gather.d.d.256")
+        "_mm_min_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse2.min.pd")
         },
-        "256_mask_i32gather_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x8, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I32x8, &::I32x8_F32, &::I32_8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.avx2.gather.d.ps.256")
+        "_mm_movemask_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F64x2]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse2.movmsk.pd")
         },
-        "_mask_i32gather_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x2, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x2, &::I32_8]; &INPUTS },
-            output: &::I64x2,
-            definition: Named("llvm.x86.avx2.gather.d.q")
+        "_mm_movemask_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x16]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse2.pmovmskb.128")
         },
-        "_mask_i32gather_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x2, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x2_F64, &::I32_8]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.avx2.gather.d.pd")
+        "_mm_mul_epu32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
+            output: &::U64x2,
+            definition: Named("llvm.x86.sse2.pmulu.dq")
         },
-        "256_mask_i32gather_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x4, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x4, &::I32_8]; &INPUTS },
-            output: &::I64x4,
-            definition: Named("llvm.x86.avx2.gather.d.q.256")
+        "_mm_mulhi_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.pmulh.w")
         },
-        "256_mask_i32gather_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x4, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I32x4, &::I64x4_F64, &::I32_8]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.avx2.gather.d.pd.256")
+        "_mm_mulhi_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse2.pmulhu.w")
         },
-        "_mask_i64gather_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I64x2, &::I32x4, &::I32_8]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.avx2.gather.q.d")
+        "_mm_packs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse2.packsswb.128")
         },
-        "_mask_i64gather_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I64x2, &::I32x4_F32, &::I32_8]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.avx2.gather.q.ps")
+        "_mm_packs_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.packssdw.128")
         },
-        "256_mask_i64gather_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I32x4, { static PTR: Type = Type::Pointer(&::I32, Some(&::I8), true); &PTR }, &::I64x4, &::I32x4, &::I32_8]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.avx2.gather.q.d")
+        "_mm_packus_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.packuswb.128")
         },
-        "256_mask_i64gather_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F32x4, { static PTR: Type = Type::Pointer(&::F32, Some(&::I8), true); &PTR }, &::I64x4, &::I32x4_F32, &::I32_8]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.avx2.gather.q.ps")
+        "_mm_sad_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U64x2,
+            definition: Named("llvm.x86.sse2.psad.bw")
         },
-        "_mask_i64gather_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x2, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I64x2, &::I64x2, &::I32_8]; &INPUTS },
-            output: &::I64x2,
-            definition: Named("llvm.x86.avx2.gather.q.q")
+        "_mm_sfence" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 0] = []; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.sfence")
         },
-        "_mask_i64gather_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x2, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x2, &::I64x2_F64, &::I32_8]; &INPUTS },
+        "_mm_sqrt_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F64x2]; &INPUTS },
             output: &::F64x2,
-            definition: Named("llvm.x86.avx2.gather.q.pd")
+            definition: Named("llvm.sqrt.v2f64")
         },
-        "256_mask_i64gather_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::I64x4, { static PTR: Type = Type::Pointer(&::I64, Some(&::I8), true); &PTR }, &::I64x4, &::I64x4, &::I32_8]; &INPUTS },
-            output: &::I64x4,
-            definition: Named("llvm.x86.avx2.gather.q.q.256")
+        "_mm_storeu_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F64, Some(&::U8), false); &PTR }, &::F64x2]; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.storeu.pd")
         },
-        "256_mask_i64gather_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 5] = [&::F64x4, { static PTR: Type = Type::Pointer(&::F64, Some(&::I8), true); &PTR }, &::I64x4, &::I64x4_F64, &::I32_8]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.avx2.gather.q.pd.256")
+        "_mm_storeu_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::U8x16, Some(&::U8), false); &PTR }, &::U8x16]; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse2.storeu.dq")
         },
-        "_maskload_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I32x4, Some(&::I8), true); &PTR }, &::I32x4]; &INPUTS },
-            output: &::I32x4,
-            definition: Named("llvm.x86.avx2.maskload.d")
+        "_mm_subs_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse2.psubs.b")
         },
-        "_maskload_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I64x2, Some(&::I8), true); &PTR }, &::I64x2]; &INPUTS },
-            output: &::I64x2,
-            definition: Named("llvm.x86.avx2.maskload.q")
+        "_mm_subs_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse2.psubus.b")
         },
-        "256_maskload_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I32x8, Some(&::I8), true); &PTR }, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.maskload.d.256")
+        "_mm_subs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.sse2.psubs.w")
         },
-        "256_maskload_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::I64x4, Some(&::I8), true); &PTR }, &::I64x4]; &INPUTS },
-            output: &::I64x4,
-            definition: Named("llvm.x86.avx2.maskload.q.256")
+        "_mm_subs_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse2.psubus.w")
         },
-        "_maskstore_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I32, Some(&::I8), false); &PTR }, &::I32x4, &::I32x4]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.avx2.maskstore.d")
+        "_mm_addsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse3.addsub.ps")
         },
-        "_maskstore_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I64, Some(&::I8), false); &PTR }, &::I64x2, &::I64x2]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.avx2.maskstore.q")
+        "_mm_addsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse3.addsub.pd")
         },
-        "256_maskstore_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I32, Some(&::I8), false); &PTR }, &::I32x8, &::I32x8]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.avx2.maskstore.d.256")
+        "_mm_hadd_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse3.hadd.ps")
         },
-        "256_maskstore_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [{ static PTR: Type = Type::Pointer(&::I64, Some(&::I8), false); &PTR }, &::I64x4, &::I64x4]; &INPUTS },
-            output: &::VOID,
-            definition: Named("llvm.x86.avx2.maskstore.q.256")
+        "_mm_hadd_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse3.hadd.pd")
         },
-        "256_max_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.pmaxs.b")
+        "_mm_hsub_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse3.hsub.ps")
         },
-        "256_max_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.pmaxu.b")
+        "_mm_hsub_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F64x2, &::F64x2]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse3.hsub.pd")
         },
-        "256_max_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pmaxs.w")
+        "_mm_lddqu_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [{ static PTR: Type = Type::Pointer(&::U8x16, Some(&::I8), true); &PTR }]; &INPUTS },
+            output: &::U8x16,
+            definition: Named("llvm.x86.sse3.ldu.dq")
         },
-        "256_max_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.pmaxu.w")
+        "_mm_dp_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::I32_8]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse41.dpps")
         },
-        "256_max_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.pmaxs.d")
+        "_mm_dp_pd" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::I32_8]; &INPUTS },
+            output: &::F64x2,
+            definition: Named("llvm.x86.sse41.dppd")
         },
-        "256_max_epu32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
-            output: &::U32x8,
-            definition: Named("llvm.x86.avx2.pmaxu.d")
+        "_mm_max_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse41.pmaxsb")
         },
-        "256_min_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.pmins.b")
+        "_mm_max_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse41.pmaxuw")
         },
-        "256_min_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.pminu.b")
+        "_mm_max_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.sse41.pmaxsd")
         },
-        "256_min_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pmins.w")
+        "_mm_max_epu32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
+            output: &::U32x4,
+            definition: Named("llvm.x86.sse41.pmaxud")
         },
-        "256_min_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.pminu.w")
+        "_mm_min_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse41.pminsb")
         },
-        "256_min_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.pmins.d")
+        "_mm_min_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse41.pminuw")
         },
-        "256_min_epu32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
-            output: &::U32x8,
-            definition: Named("llvm.x86.avx2.pminu.d")
+        "_mm_min_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.sse41.pminsd")
         },
-        "256_movemask_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x32]; &INPUTS },
-            output: &::I32,
-            definition: Named("llvm.x86.avx2.pmovmskb")
+        "_mm_min_epu32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
+            output: &::U32x4,
+            definition: Named("llvm.x86.sse41.pminud")
         },
-        "256_mpsadbw_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x32, &::U8x32, &::I32_8]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.mpsadbw")
+        "_mm_minpos_epu16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::U16x8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse41.phminposuw")
         },
-        "256_mul_epi64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I64x4,
-            definition: Named("llvm.x86.avx2.pmulq.dq")
+        "_mm_mpsadbw_epu8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::U8x16, &::U8x16, &::I32_8]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse41.mpsadbw")
         },
-        "256_mul_epu64" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U32x8, &::U32x8]; &INPUTS },
-            output: &::U64x4,
-            definition: Named("llvm.x86.avx2.pmulq.dq")
+        "_mm_mul_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I64x2,
+            definition: Named("llvm.x86.sse41.pmuldq")
         },
-        "256_mulhi_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pmulhw.w")
+        "_mm_packus_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::U16x8,
+            definition: Named("llvm.x86.sse41.packusdw")
         },
-        "256_mulhi_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.pmulhw.w")
+        "_mm_testc_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse41.ptestc")
         },
-        "256_mulhrs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.pmul.hr.sw")
+        "_mm_testnzc_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse41.ptestnzc")
         },
-        "256_packs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.packsswb")
+        "_mm_testz_si128" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64x2, &::U64x2]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse41.ptestz")
         },
-        "256_packus_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.packuswb")
+        "_mm_cmpestra" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestria128")
         },
-        "256_packs_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.packssdw")
+        "_mm_cmpestrc" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestric128")
         },
-        "256_packus_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.packusdw")
+        "_mm_cmpestri" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestri128")
         },
-        "256_permutevar8x32_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.permd")
+        "_mm_cmpestrm" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse42.pcmpestrm128")
         },
-        "256_permutevar8x32_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x8, &::I32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.avx2.permps")
+        "_mm_cmpestro" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestrio128")
         },
-        "256_sad_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.psad.bw")
+        "_mm_cmpestrs" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestris128")
         },
-        "256_shuffle_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.pshuf.b")
+        "_mm_cmpestrz" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 5] = [&::I8x16, &::I32, &::I8x16, &::I32, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpestriz128")
         },
-        "256_sign_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.psign.b")
+        "_mm_cmpistra" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistria128")
         },
-        "256_sign_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.psign.w")
+        "_mm_cmpistrc" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistric128")
         },
-        "256_sign_epi32" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x8, &::I32x8]; &INPUTS },
-            output: &::I32x8,
-            definition: Named("llvm.x86.avx2.psign.d")
+        "_mm_cmpistri" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistri128")
         },
-        "256_subs_epi8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x32, &::I8x32]; &INPUTS },
-            output: &::I8x32,
-            definition: Named("llvm.x86.avx2.psubs.b")
+        "_mm_cmpistrm" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.sse42.pcmpistrm128")
         },
-        "256_subs_epu8" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x32, &::U8x32]; &INPUTS },
-            output: &::U8x32,
-            definition: Named("llvm.x86.avx2.psubus.b")
+        "_mm_cmpistro" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistrio128")
         },
-        "256_subs_epi16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x16, &::I16x16]; &INPUTS },
-            output: &::I16x16,
-            definition: Named("llvm.x86.avx2.psubs.w")
+        "_mm_cmpistrs" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistris128")
         },
-        "256_subs_epu16" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 2] = [&::U16x16, &::U16x16]; &INPUTS },
-            output: &::U16x16,
-            definition: Named("llvm.x86.avx2.psubus.w")
+        "_mm_cmpistrz" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 3] = [&::I8x16, &::I8x16, &::I32_8]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse42.pcmpistriz128")
         },
-        "_fmadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfmadd.ps")
+        "_mm_movemask_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
+            output: &::I32,
+            definition: Named("llvm.x86.sse.movmsk.ps")
         },
-        "_fmadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfmadd.pd")
+        "_mm_max_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse.max.ps")
         },
-        "256_fmadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfmadd.ps.256")
+        "_mm_min_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse.min.ps")
         },
-        "256_fmadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfmadd.pd.256")
+        "_mm_rsqrt_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.x86.sse.rsqrt.ps")
         },
-        "_fmaddsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
+        "_mm_rcp_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
             output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfmaddsub.ps")
+            definition: Named("llvm.x86.sse.rcp.ps")
         },
-        "_fmaddsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfmaddsub.pd")
+        "_mm_sqrt_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::F32x4]; &INPUTS },
+            output: &::F32x4,
+            definition: Named("llvm.sqrt.v4f32")
         },
-        "256_fmaddsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfmaddsub.ps.256")
+        "_mm_storeu_ps" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [{ static PTR: Type = Type::Pointer(&::F32, Some(&::I8), false); &PTR }, &::F32x4]; &INPUTS },
+            output: &::VOID,
+            definition: Named("llvm.x86.sse.storeu.ps")
         },
-        "256_fmaddsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfmaddsub.pd.256")
+        "_mm_abs_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.ssse3.pabs.b.128")
         },
-        "_fmsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfmsub.ps")
+        "_mm_abs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.pabs.w.128")
         },
-        "_fmsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfmsub.pd")
+        "_mm_abs_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 1] = [&::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.ssse3.pabs.d.128")
         },
-        "256_fmsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfmsub.ps.256")
+        "_mm_hadd_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.phadd.w.128")
         },
-        "256_fmsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfmsub.pd.256")
+        "_mm_hadd_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.ssse3.phadd.d.128")
         },
-        "_fmsubadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfmsubadd.ps")
+        "_mm_hadds_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.phadd.sw.128")
         },
-        "_fmsubadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfmsubadd.pd")
+        "_mm_hsub_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.phsub.w.128")
         },
-        "256_fmsubadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfmsubadd.ps.256")
+        "_mm_hsub_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.ssse3.phsub.d.128")
         },
-        "256_fmsubadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfmsubadd.pd.256")
+        "_mm_hsubs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.phsub.sw.128")
         },
-        "_fnmadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfnmadd.ps")
+        "_mm_maddubs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::I8x16]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.pmadd.ub.sw.128")
         },
-        "_fnmadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfnmadd.pd")
+        "_mm_mulhrs_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.pmul.hr.sw.128")
         },
-        "256_fnmadd_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfnmadd.ps.256")
+        "_mm_shuffle_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.ssse3.pshuf.b.128")
         },
-        "256_fnmadd_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfnmadd.pd.256")
+        "_mm_sign_epi8" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
+            output: &::I8x16,
+            definition: Named("llvm.x86.ssse3.psign.b.128")
         },
-        "_fnmsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x4, &::F32x4, &::F32x4]; &INPUTS },
-            output: &::F32x4,
-            definition: Named("llvm.x86.fma.vfnmsub.ps")
+        "_mm_sign_epi16" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
+            output: &::I16x8,
+            definition: Named("llvm.x86.ssse3.psign.w.128")
         },
-        "_fnmsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x2, &::F64x2, &::F64x2]; &INPUTS },
-            output: &::F64x2,
-            definition: Named("llvm.x86.fma.vfnmsub.pd")
+        "_mm_sign_epi32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
+            output: &::I32x4,
+            definition: Named("llvm.x86.ssse3.psign.d.128")
         },
-        "256_fnmsub_ps" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F32x8, &::F32x8, &::F32x8]; &INPUTS },
-            output: &::F32x8,
-            definition: Named("llvm.x86.fma.vfnmsub.ps.256")
+        "_tbm_bextri_u32" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U32, &::U32]; &INPUTS },
+            output: &::U32,
+            definition: Named("llvm.x86.tbm.bextri.u32")
         },
-        "256_fnmsub_pd" => Intrinsic {
-            inputs: { static INPUTS: [&'static Type; 3] = [&::F64x4, &::F64x4, &::F64x4]; &INPUTS },
-            output: &::F64x4,
-            definition: Named("llvm.x86.fma.vfnmsub.pd.256")
+        "_tbm_bextri_u64" => Intrinsic {
+            inputs: { static INPUTS: [&'static Type; 2] = [&::U64, &::U64]; &INPUTS },
+            output: &::U64,
+            definition: Named("llvm.x86.tbm.bextri.u64")
         },
         _ => return None,
     })
index ed400af66855a66145924a9cf66ac240e542e37b..66b0d663424aa829a95c673de86b76e27b63ae8e 100644 (file)
@@ -1167,18 +1167,6 @@ pub fn arenas() -> ResolverArenas<'a> {
 
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
-        // Currently, we ignore the name resolution data structures for
-        // the purposes of dependency tracking. Instead we will run name
-        // resolution and include its output in the hash of each item,
-        // much like we do for macro expansion. In other words, the hash
-        // reflects not just its contents but the results of name
-        // resolution on those contents. Hopefully we'll push this back at
-        // some point.
-        let _ignore = self.session.dep_graph.in_ignore();
-
-        self.build_reduced_graph(krate);
-        resolve_imports::resolve_imports(self);
-
         self.current_module = self.graph_root;
         visit::walk_crate(self, krate);
 
index cb308f91204046fae6b06b7a73eafbce7e7e1a8e..16a59fbb800024afcd24c43de94a8b15307da684 100644 (file)
 
 use std::cell::{Cell, RefCell};
 
+impl<'a> Resolver<'a> {
+    pub fn resolve_imports(&mut self) {
+        ImportResolver { resolver: self }.resolve_imports();
+    }
+}
+
 /// Contains data for specific types of import directives.
 #[derive(Clone, Debug)]
 pub enum ImportDirectiveSubclass {
@@ -722,8 +728,3 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
         GlobImport { .. } => "*".to_string(),
     }
 }
-
-pub fn resolve_imports(resolver: &mut Resolver) {
-    let mut import_resolver = ImportResolver { resolver: resolver };
-    import_resolver.resolve_imports();
-}
index 8eaf398778380be7724bc42cd60dc8d5c60c5e54..0580c51d9a17a745db2140e59ef8b3885624849c 100644 (file)
@@ -299,12 +299,10 @@ pub fn get_method_data(&self, id: ast::NodeId,
                             let mut result = String::from("<");
                             result.push_str(&rustc::hir::print::ty_to_string(&ty));
 
-                            match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) {
-                                Some(def_id) => {
-                                    result.push_str(" as ");
-                                    result.push_str(&self.tcx.item_path_str(def_id));
-                                }
-                                None => {}
+                            if let Some(def_id) = self.tcx
+                                    .trait_of_item(self.tcx.map.local_def_id(id)) {
+                                result.push_str(" as ");
+                                result.push_str(&self.tcx.item_path_str(def_id));
                             }
                             result.push_str(">");
                             result
index 15beba0d9a6eeb639bb88bf82513df3e586bec83..3ef6e29a6f83894da32612e3ba11b5fa4fcd780a 100644 (file)
@@ -1706,17 +1706,13 @@ fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             //
             // In such cases, the more general path is unsafe, because
             // it assumes it is matching against a valid value.
-            match simple_name(pat) {
-                Some(name) => {
-                    let var_scope = cleanup::var_scope(tcx, local.id);
-                    return mk_binding_alloca(
-                        bcx, pat.id, name, var_scope, (),
-                        "_match::store_local",
-                        |(), bcx, Datum { val: v, .. }| expr::trans_into(bcx, &init_expr,
-                                                                         expr::SaveIn(v)));
-                }
-
-                None => {}
+            if let Some(name) = simple_name(pat) {
+                let var_scope = cleanup::var_scope(tcx, local.id);
+                return mk_binding_alloca(
+                    bcx, pat.id, name, var_scope, (),
+                    "_match::store_local",
+                    |(), bcx, Datum { val: v, .. }| expr::trans_into(bcx, &init_expr,
+                                                                     expr::SaveIn(v)));
             }
 
             // General path.
index a4792ea328f08b64e13a25ca8ab82d07ef1fabef..23c4258caf7bd9c5ca873ba44d9c4ac28880f2d0 100644 (file)
@@ -191,9 +191,8 @@ pub fn represent_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                 t: Ty<'tcx>)
                                 -> Rc<Repr<'tcx>> {
     debug!("Representing: {}", t);
-    match cx.adt_reprs().borrow().get(&t) {
-        Some(repr) => return repr.clone(),
-        None => {}
+    if let Some(repr) = cx.adt_reprs().borrow().get(&t) {
+        return repr.clone();
     }
 
     let repr = Rc::new(represent_type_uncached(cx, t));
index 0ca59cfd7571b8e846712f90e8433a689fae6b0b..744712b22b060ef3cafafef22dc282fb8329daa2 100644 (file)
@@ -136,14 +136,17 @@ pub fn build_link_meta<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     return r;
 }
 
-pub fn get_linker(sess: &Session) -> (String, Command) {
+// The third parameter is for an extra path to add to PATH for MSVC
+// cross linkers for host toolchain DLL dependencies
+pub fn get_linker(sess: &Session) -> (String, Command, Option<PathBuf>) {
     if let Some(ref linker) = sess.opts.cg.linker {
-        (linker.clone(), Command::new(linker))
+        (linker.clone(), Command::new(linker), None)
     } else if sess.target.target.options.is_like_msvc {
-        ("link.exe".to_string(), msvc::link_exe_cmd(sess))
+        let (cmd, host) = msvc::link_exe_cmd(sess);
+        ("link.exe".to_string(), cmd, host)
     } else {
         (sess.target.target.options.linker.clone(),
-         Command::new(&sess.target.target.options.linker))
+         Command::new(&sess.target.target.options.linker), None)
     }
 }
 
@@ -153,7 +156,7 @@ pub fn get_ar_prog(sess: &Session) -> String {
     })
 }
 
-fn command_path(sess: &Session) -> OsString {
+fn command_path(sess: &Session, extra: Option<PathBuf>) -> OsString {
     // The compiler's sysroot often has some bundled tools, so add it to the
     // PATH for the child.
     let mut new_path = sess.host_filesearch(PathKind::All)
@@ -161,9 +164,7 @@ fn command_path(sess: &Session) -> OsString {
     if let Some(path) = env::var_os("PATH") {
         new_path.extend(env::split_paths(&path));
     }
-    if sess.target.target.options.is_like_msvc {
-        new_path.extend(msvc::host_dll_path());
-    }
+    new_path.extend(extra);
     env::join_paths(new_path).unwrap()
 }
 
@@ -379,7 +380,7 @@ fn archive_config<'a>(sess: &'a Session,
         src: input.map(|p| p.to_path_buf()),
         lib_search_paths: archive_search_paths(sess),
         ar_prog: get_ar_prog(sess),
-        command_path: command_path(sess),
+        command_path: command_path(sess, None),
     }
 }
 
@@ -616,8 +617,8 @@ fn link_natively(sess: &Session,
     info!("preparing {:?} from {:?} to {:?}", crate_type, objects, out_filename);
 
     // The invocations of cc share some flags across platforms
-    let (pname, mut cmd) = get_linker(sess);
-    cmd.env("PATH", command_path(sess));
+    let (pname, mut cmd, extra) = get_linker(sess);
+    cmd.env("PATH", command_path(sess, extra));
 
     let root = sess.target_filesearch(PathKind::Native).get_lib_path();
     cmd.args(&sess.target.target.options.pre_link_args);
@@ -682,10 +683,15 @@ fn escape_string(s: &[u8]) -> String {
             info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
         },
         Err(e) => {
-            // Trying to diagnose https://github.com/rust-lang/rust/issues/33844
             sess.struct_err(&format!("could not exec the linker `{}`: {}", pname, e))
                 .note(&format!("{:?}", &cmd))
                 .emit();
+            if sess.target.target.options.is_like_msvc && e.kind() == io::ErrorKind::NotFound {
+                sess.note_without_error("the msvc targets depend on the msvc linker \
+                    but `link.exe` was not found");
+                sess.note_without_error("please ensure that VS 2013 or VS 2015 was installed \
+                    with the Visual C++ option");
+            }
             sess.abort_if_errors();
         }
     }
diff --git a/src/librustc_trans/back/msvc/arch.rs b/src/librustc_trans/back/msvc/arch.rs
new file mode 100644 (file)
index 0000000..c10312a
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2016 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.
+
+#![allow(non_camel_case_types, non_snake_case)]
+
+use libc::c_void;
+use std::mem;
+
+type DWORD = u32;
+type WORD = u16;
+type LPVOID = *mut c_void;
+type DWORD_PTR = usize;
+
+const PROCESSOR_ARCHITECTURE_INTEL: WORD = 0;
+const PROCESSOR_ARCHITECTURE_AMD64: WORD = 9;
+
+#[repr(C)]
+struct SYSTEM_INFO {
+    wProcessorArchitecture: WORD,
+    _wReserved: WORD,
+    _dwPageSize: DWORD,
+    _lpMinimumApplicationAddress: LPVOID,
+    _lpMaximumApplicationAddress: LPVOID,
+    _dwActiveProcessorMask: DWORD_PTR,
+    _dwNumberOfProcessors: DWORD,
+    _dwProcessorType: DWORD,
+    _dwAllocationGranularity: DWORD,
+    _wProcessorLevel: WORD,
+    _wProcessorRevision: WORD,
+}
+
+extern "system" {
+    fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
+}
+
+pub enum Arch {
+    X86,
+    Amd64,
+}
+
+pub fn host_arch() -> Option<Arch> {
+    let mut info = unsafe { mem::zeroed() };
+    unsafe { GetNativeSystemInfo(&mut info) };
+    match info.wProcessorArchitecture {
+        PROCESSOR_ARCHITECTURE_INTEL => Some(Arch::X86),
+        PROCESSOR_ARCHITECTURE_AMD64 => Some(Arch::Amd64),
+        _ => None,
+    }
+}
index 0112da57cc0a6bed711e7ee16618b85b9dc1b406..16aef6ee8ca3543047ba07c85d867f9eae1de881 100644 (file)
 //! paths/files is based on Microsoft's logic in their vcvars bat files, but
 //! comments can also be found below leading through the various code paths.
 
+// A simple macro to make this option mess easier to read
+macro_rules! otry {
+    ($expr:expr) => (match $expr {
+        Some(val) => val,
+        None => return None,
+    })
+}
+
 #[cfg(windows)]
 mod registry;
+#[cfg(windows)]
+mod arch;
 
 #[cfg(windows)]
 mod platform {
@@ -42,111 +52,134 @@ mod platform {
     use std::path::{Path, PathBuf};
     use std::process::Command;
     use session::Session;
-    use super::registry::{LOCAL_MACHINE};
+    use super::arch::{host_arch, Arch};
+    use super::registry::LOCAL_MACHINE;
 
-    // Cross toolchains depend on dlls from the host toolchain
-    // We can't just add it to the Command's PATH in `link_exe_cmd` because it
-    // is later overridden so we publicly expose it here instead
-    pub fn host_dll_path() -> Option<PathBuf> {
-        get_vc_dir().and_then(|(_, vcdir)| {
-            host_dll_subdir().map(|sub| {
-                vcdir.join("bin").join(sub)
+    // First we need to figure out whether the environment is already correctly
+    // configured by vcvars. We do this by looking at the environment variable
+    // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
+    // otherwise. If it is defined, then we find `link.exe` in `PATH and trust
+    // that everything else is configured correctly.
+    //
+    // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where
+    // it claimed it should be), then we resort to finding everything
+    // ourselves. First we find where the latest version of MSVC is installed
+    // and what version it is. Then based on the version we find the
+    // appropriate SDKs.
+    //
+    // If despite our best efforts we are still unable to find MSVC then we
+    // just blindly call `link.exe` and hope for the best.
+    //
+    // This code only supports VC 11 through 15. For versions older than that
+    // the user will need to manually execute the appropriate vcvars bat file
+    // and it should hopefully work.
+    //
+    // The second member of the tuple we return is the directory for the host
+    // linker toolchain, which is necessary when using the cross linkers.
+    pub fn link_exe_cmd(sess: &Session) -> (Command, Option<PathBuf>) {
+        let arch = &sess.target.target.arch;
+        env::var_os("VCINSTALLDIR").and_then(|_| {
+            debug!("Detected that vcvars was already run.");
+            let path = otry!(env::var_os("PATH"));
+            // Mingw has its own link which is not the link we want so we
+            // look for `cl.exe` too as a precaution.
+            env::split_paths(&path).find(|path| {
+                path.join("cl.exe").is_file()
+                    && path.join("link.exe").is_file()
+            }).map(|path| {
+                (Command::new(path.join("link.exe")), None)
             })
+        }).or_else(|| {
+            None.or_else(|| {
+                find_msvc_latest(arch, "15.0")
+            }).or_else(|| {
+                find_msvc_latest(arch, "14.0")
+            }).or_else(|| {
+                find_msvc_12(arch)
+            }).or_else(|| {
+                find_msvc_11(arch)
+            }).map(|(cmd, path)| (cmd, Some(path)))
+        }).unwrap_or_else(|| {
+            debug!("Failed to locate linker.");
+            (Command::new("link.exe"), None)
         })
     }
 
-    pub fn link_exe_cmd(sess: &Session) -> Command {
-        let arch = &sess.target.target.arch;
-        let (binsub, libsub, vclibsub) =
-            match (bin_subdir(arch), lib_subdir(arch), vc_lib_subdir(arch)) {
-            (Some(x), Some(y), Some(z)) => (x, y, z),
-            _ => return Command::new("link.exe"),
-        };
+    // For MSVC 14 or newer we need to find the Universal CRT as well as either
+    // the Windows 10 SDK or Windows 8.1 SDK.
+    fn find_msvc_latest(arch: &str, ver: &str) -> Option<(Command, PathBuf)> {
+        let vcdir = otry!(get_vc_dir(ver));
+        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
+        let sub = otry!(lib_subdir(arch));
+        let ucrt = otry!(get_ucrt_dir());
+        debug!("Found Universal CRT {:?}", ucrt);
+        add_lib(&mut cmd, &ucrt.join("ucrt").join(sub));
+        if let Some(dir) = get_sdk10_dir() {
+            debug!("Found Win10 SDK {:?}", dir);
+            add_lib(&mut cmd, &dir.join("um").join(sub));
+        } else if let Some(dir) = get_sdk81_dir() {
+            debug!("Found Win8.1 SDK {:?}", dir);
+            add_lib(&mut cmd, &dir.join("um").join(sub));
+        } else {
+            return None
+        }
+        Some((cmd, host))
+    }
 
-        // First we need to figure out whether the environment is already correctly
-        // configured by vcvars. We do this by looking at the environment variable
-        // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
-        // otherwise. If it is defined, then we derive the path to `link.exe` from
-        // that and trust that everything else is configured correctly.
-        //
-        // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where it
-        // claimed it should be), then we resort to finding everything ourselves.
-        // First we find where the latest version of MSVC is installed and what
-        // version it is. Then based on the version we find the appropriate SDKs.
-        //
-        // For MSVC 14 (VS 2015) we look for the Win10 SDK and failing that we look
-        // for the Win8.1 SDK. We also look for the Universal CRT.
-        //
-        // For MSVC 12 (VS 2013) we look for the Win8.1 SDK.
-        //
-        // For MSVC 11 (VS 2012) we look for the Win8 SDK.
-        //
-        // For all other versions the user has to execute the appropriate vcvars bat
-        // file themselves to configure the environment.
-        //
-        // If despite our best efforts we are still unable to find MSVC then we just
-        // blindly call `link.exe` and hope for the best.
-        return env::var_os("VCINSTALLDIR").and_then(|dir| {
-            debug!("Environment already configured by user. Assuming it works.");
-            let mut p = PathBuf::from(dir);
-            p.push("bin");
-            p.push(binsub);
-            p.push("link.exe");
-            if !p.is_file() { return None }
-            Some(Command::new(p))
-        }).or_else(|| {
-            get_vc_dir().and_then(|(ver, vcdir)| {
-                debug!("Found VC installation directory {:?}", vcdir);
-                let linker = vcdir.clone().join("bin").join(binsub).join("link.exe");
-                if !linker.is_file() { return None }
-                let mut cmd = Command::new(linker);
-                add_lib(&mut cmd, &vcdir.join("lib").join(vclibsub));
-                if ver == "14.0" {
-                    if let Some(dir) = get_ucrt_dir() {
-                        debug!("Found Universal CRT {:?}", dir);
-                        add_lib(&mut cmd, &dir.join("ucrt").join(libsub));
-                    }
-                    if let Some(dir) = get_sdk10_dir() {
-                        debug!("Found Win10 SDK {:?}", dir);
-                        add_lib(&mut cmd, &dir.join("um").join(libsub));
-                    } else if let Some(dir) = get_sdk81_dir() {
-                        debug!("Found Win8.1 SDK {:?}", dir);
-                        add_lib(&mut cmd, &dir.join("um").join(libsub));
-                    }
-                } else if ver == "12.0" {
-                    if let Some(dir) = get_sdk81_dir() {
-                        debug!("Found Win8.1 SDK {:?}", dir);
-                        add_lib(&mut cmd, &dir.join("um").join(libsub));
-                    }
-                } else { // ver == "11.0"
-                    if let Some(dir) = get_sdk8_dir() {
-                        debug!("Found Win8 SDK {:?}", dir);
-                        add_lib(&mut cmd, &dir.join("um").join(libsub));
-                    }
-                }
-                Some(cmd)
-            })
-        }).unwrap_or_else(|| {
-            debug!("Failed to locate linker.");
-            Command::new("link.exe")
-        });
+    // For MSVC 12 we need to find the Windows 8.1 SDK.
+    fn find_msvc_12(arch: &str) -> Option<(Command, PathBuf)> {
+        let vcdir = otry!(get_vc_dir("12.0"));
+        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
+        let sub = otry!(lib_subdir(arch));
+        let sdk81 = otry!(get_sdk81_dir());
+        debug!("Found Win8.1 SDK {:?}", sdk81);
+        add_lib(&mut cmd, &sdk81.join("um").join(sub));
+        Some((cmd, host))
+    }
+
+    // For MSVC 11 we need to find the Windows 8 SDK.
+    fn find_msvc_11(arch: &str) -> Option<(Command, PathBuf)> {
+        let vcdir = otry!(get_vc_dir("11.0"));
+        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
+        let sub = otry!(lib_subdir(arch));
+        let sdk8 = otry!(get_sdk8_dir());
+        debug!("Found Win8 SDK {:?}", sdk8);
+        add_lib(&mut cmd, &sdk8.join("um").join(sub));
+        Some((cmd, host))
     }
-    // A convenience function to make the above code simpler
+
+    // A convenience function to append library paths.
     fn add_lib(cmd: &mut Command, lib: &Path) {
         let mut arg: OsString = "/LIBPATH:".into();
         arg.push(lib);
         cmd.arg(arg);
     }
 
-    // To find MSVC we look in a specific registry key for the newest of the
-    // three versions that we support.
-    fn get_vc_dir() -> Option<(&'static str, PathBuf)> {
-        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref())
-        .ok().and_then(|key| {
-            ["14.0", "12.0", "11.0"].iter().filter_map(|ver| {
-                key.query_str(ver).ok().map(|p| (*ver, p.into()))
-            }).next()
-        })
+    // Given a possible MSVC installation directory, we look for the linker and
+    // then add the MSVC library path.
+    fn get_linker(path: &Path, arch: &str) -> Option<(Command, PathBuf)> {
+        debug!("Looking for linker in {:?}", path);
+        bin_subdir(arch).into_iter().map(|(sub, host)| {
+            (path.join("bin").join(sub).join("link.exe"),
+             path.join("bin").join(host))
+        }).filter(|&(ref path, _)| {
+            path.is_file()
+        }).map(|(path, host)| {
+            (Command::new(path), host)
+        }).filter_map(|(mut cmd, host)| {
+            let sub = otry!(vc_lib_subdir(arch));
+            add_lib(&mut cmd, &path.join("lib").join(sub));
+            Some((cmd, host))
+        }).next()
+    }
+
+    // To find MSVC we look in a specific registry key for the version we are
+    // trying to find.
+    fn get_vc_dir(ver: &str) -> Option<PathBuf> {
+        let key = otry!(LOCAL_MACHINE
+            .open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref()).ok());
+        let path = otry!(key.query_str(ver).ok());
+        Some(path.into())
     }
 
     // To find the Universal CRT we look in a specific registry key for where
@@ -154,46 +187,42 @@ fn get_vc_dir() -> Option<(&'static str, PathBuf)> {
     // find the newest version. While this sort of sorting isn't ideal,  it is
     // what vcvars does so that's good enough for us.
     fn get_ucrt_dir() -> Option<PathBuf> {
-        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref())
-        .ok().and_then(|key| {
-            key.query_str("KitsRoot10").ok()
-        }).and_then(|root| {
-            fs::read_dir(Path::new(&root).join("Lib")).ok()
-        }).and_then(|readdir| {
-            let mut dirs: Vec<_> = readdir.filter_map(|dir| {
-                dir.ok()
-            }).map(|dir| {
-                dir.path()
-            }).filter(|dir| {
-                dir.components().last().and_then(|c| {
-                    c.as_os_str().to_str()
-                }).map(|c| c.starts_with("10.")).unwrap_or(false)
-            }).collect();
-            dirs.sort();
-            dirs.pop()
-        })
+        let key = otry!(LOCAL_MACHINE
+            .open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref()).ok());
+        let root = otry!(key.query_str("KitsRoot10").ok());
+        let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
+        readdir.filter_map(|dir| {
+            dir.ok()
+        }).map(|dir| {
+            dir.path()
+        }).filter(|dir| {
+            dir.components().last().and_then(|c| {
+                c.as_os_str().to_str()
+            }).map(|c| {
+                c.starts_with("10.") && dir.join("ucrt").is_dir()
+            }).unwrap_or(false)
+        }).max()
     }
 
     // Vcvars finds the correct version of the Windows 10 SDK by looking
-    // for the include um/Windows.h because sometimes a given version will
+    // for the include `um\Windows.h` because sometimes a given version will
     // only have UCRT bits without the rest of the SDK. Since we only care about
-    // libraries and not includes, we just look for the folder `um` in the lib
-    // section. Like we do for the Universal CRT, we sort the possibilities
+    // libraries and not includes, we instead look for `um\x64\kernel32.lib`.
+    // Since the 32-bit and 64-bit libraries are always installed together we
+    // only need to bother checking x64, making this code a tiny bit simpler.
+    // Like we do for the Universal CRT, we sort the possibilities
     // asciibetically to find the newest one as that is what vcvars does.
     fn get_sdk10_dir() -> Option<PathBuf> {
-        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref())
-        .ok().and_then(|key| {
-            key.query_str("InstallationFolder").ok()
-        }).and_then(|root| {
-            fs::read_dir(Path::new(&root).join("lib")).ok()
-        }).and_then(|readdir| {
-            let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
-                .map(|dir| dir.path()).collect();
-            dirs.sort();
-            dirs.into_iter().rev().filter(|dir| {
-                dir.join("um").is_dir()
-            }).next()
-        })
+        let key = otry!(LOCAL_MACHINE
+            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref()).ok());
+        let root = otry!(key.query_str("InstallationFolder").ok());
+        let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
+        let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
+            .map(|dir| dir.path()).collect();
+        dirs.sort();
+        dirs.into_iter().rev().filter(|dir| {
+            dir.join("um").join("x64").join("kernel32.lib").is_file()
+        }).next()
     }
 
     // Interestingly there are several subdirectories, `win7` `win8` and
@@ -201,21 +230,17 @@ fn get_sdk10_dir() -> Option<PathBuf> {
     // applies to us. Note that if we were targetting kernel mode drivers
     // instead of user mode applications, we would care.
     fn get_sdk81_dir() -> Option<PathBuf> {
-        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref())
-        .ok().and_then(|key| {
-            key.query_str("InstallationFolder").ok()
-        }).map(|root| {
-            Path::new(&root).join("lib").join("winv6.3")
-        })
+        let key = otry!(LOCAL_MACHINE
+            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref()).ok());
+        let root = otry!(key.query_str("InstallationFolder").ok());
+        Some(Path::new(&root).join("lib").join("winv6.3"))
     }
 
     fn get_sdk8_dir() -> Option<PathBuf> {
-        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref())
-        .ok().and_then(|key| {
-            key.query_str("InstallationFolder").ok()
-        }).map(|root| {
-            Path::new(&root).join("lib").join("win8")
-        })
+        let key = otry!(LOCAL_MACHINE
+            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref()).ok());
+        let root = otry!(key.query_str("InstallationFolder").ok());
+        Some(Path::new(&root).join("lib").join("win8"))
     }
 
     // When choosing the linker toolchain to use, we have to choose the one
@@ -223,31 +248,27 @@ fn get_sdk8_dir() -> Option<PathBuf> {
     // where someone on 32-bit Windows is trying to cross compile to 64-bit and
     // it tries to invoke the native 64-bit linker which won't work.
     //
-    // FIXME - This currently functions based on the host architecture of rustc
-    // itself but it should instead detect the bitness of the OS itself.
+    // For the return value of this function, the first member of the tuple is
+    // the folder of the linker we will be invoking, while the second member
+    // is the folder of the host toolchain for that linker which is essential
+    // when using a cross linker. We return a Vec since on x64 there are often
+    // two linkers that can target the architecture we desire. The 64-bit host
+    // linker is preferred, and hence first, due to 64-bit allowing it more
+    // address space to work with and potentially being faster.
     //
     // FIXME - Figure out what happens when the host architecture is arm.
-    //
-    // FIXME - Some versions of MSVC may not come with all these toolchains.
-    // Consider returning an array of toolchains and trying them one at a time
-    // until the linker is found.
-    fn bin_subdir(arch: &str) -> Option<&'static str> {
-        if cfg!(target_arch = "x86_64") {
-            match arch {
-                "x86" => Some("amd64_x86"),
-                "x86_64" => Some("amd64"),
-                "arm" => Some("amd64_arm"),
-                _ => None,
-            }
-        } else if cfg!(target_arch = "x86") {
-            match arch {
-                "x86" => Some(""),
-                "x86_64" => Some("x86_amd64"),
-                "arm" => Some("x86_arm"),
-                _ => None,
-            }
-        } else { None }
+    fn bin_subdir(arch: &str) -> Vec<(&'static str, &'static str)> {
+        match (arch, host_arch()) {
+            ("x86", Some(Arch::X86)) => vec![("", "")],
+            ("x86", Some(Arch::Amd64)) => vec![("amd64_x86", "amd64"), ("", "")],
+            ("x86_64", Some(Arch::X86)) => vec![("x86_amd64", "")],
+            ("x86_64", Some(Arch::Amd64)) => vec![("amd64", "amd64"), ("x86_amd64", "")],
+            ("arm", Some(Arch::X86)) => vec![("x86_arm", "")],
+            ("arm", Some(Arch::Amd64)) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
+            _ => vec![],
+        }
     }
+
     fn lib_subdir(arch: &str) -> Option<&'static str> {
         match arch {
             "x86" => Some("x86"),
@@ -256,6 +277,7 @@ fn lib_subdir(arch: &str) -> Option<&'static str> {
             _ => None,
         }
     }
+
     // MSVC's x86 libraries are not in a subfolder
     fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
         match arch {
@@ -265,11 +287,6 @@ fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
             _ => None,
         }
     }
-    fn host_dll_subdir() -> Option<&'static str> {
-        if cfg!(target_arch = "x86_64") { Some("amd64") }
-        else if cfg!(target_arch = "x86") { Some("") }
-        else { None }
-    }
 }
 
 // If we're not on Windows, then there's no registry to search through and MSVC
@@ -279,9 +296,9 @@ mod platform {
     use std::path::PathBuf;
     use std::process::Command;
     use session::Session;
-    pub fn link_exe_cmd(_sess: &Session) -> Command {
-        Command::new("link.exe")
+    pub fn link_exe_cmd(_sess: &Session) -> (Command, Option<PathBuf>) {
+        (Command::new("link.exe"), None)
     }
-    pub fn host_dll_path() -> Option<PathBuf> { None }
 }
+
 pub use self::platform::*;
index d644fcca3bad869022a5b9aaaa5c1ca6bb4cf12a..ec20381d1890d1f55f5d6e543104503ac4542ae5 100644 (file)
@@ -616,11 +616,19 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
         }
     }
 
-    llvm::LLVMDisposeModule(llmod);
-    llvm::LLVMContextDispose(llcx);
     llvm::LLVMRustDisposeTargetMachine(tm);
 }
 
+
+pub fn cleanup_llvm(trans: &CrateTranslation) {
+    for module in trans.modules.iter() {
+        unsafe {
+            llvm::LLVMDisposeModule(module.llmod);
+            llvm::LLVMContextDispose(module.llcx);
+        }
+    }
+}
+
 pub fn run_passes(sess: &Session,
                   trans: &CrateTranslation,
                   output_types: &HashMap<OutputType, Option<PathBuf>>,
@@ -970,7 +978,7 @@ fn run_work_multithreaded(sess: &Session,
 }
 
 pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
-    let (pname, mut cmd) = get_linker(sess);
+    let (pname, mut cmd, _) = get_linker(sess);
 
     cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object))
                            .arg(&outputs.temp_path(OutputType::Assembly));
index 2998c834aca7a870d4f62011b3c1d13dee6cb4e0..7a572fdadc3d795bdac78a20a3bb3ea80449ed96 100644 (file)
@@ -136,11 +136,8 @@ pub struct _InsnCtxt {
 impl Drop for _InsnCtxt {
     fn drop(&mut self) {
         TASK_LOCAL_INSN_KEY.with(|slot| {
-            match slot.borrow_mut().as_mut() {
-                Some(ctx) => {
-                    ctx.pop();
-                }
-                None => {}
+            if let Some(ctx) = slot.borrow_mut().as_mut() {
+                ctx.pop();
             }
         })
     }
index 4e12d3d5d82310120897b93bd06d89a99300f65f..5596ab0d819e0a3470f7b6a2e360a0c72de87fa2 100644 (file)
@@ -138,18 +138,15 @@ pub fn addr_of(ccx: &CrateContext,
                align: machine::llalign,
                kind: &str)
                -> ValueRef {
-    match ccx.const_globals().borrow().get(&cv) {
-        Some(&gv) => {
-            unsafe {
-                // Upgrade the alignment in cases where the same constant is used with different
-                // alignment requirements
-                if align > llvm::LLVMGetAlignment(gv) {
-                    llvm::LLVMSetAlignment(gv, align);
-                }
+    if let Some(&gv) = ccx.const_globals().borrow().get(&cv) {
+        unsafe {
+            // Upgrade the alignment in cases where the same constant is used with different
+            // alignment requirements
+            if align > llvm::LLVMGetAlignment(gv) {
+                llvm::LLVMSetAlignment(gv, align);
             }
-            return gv;
         }
-        None => {}
+        return gv;
     }
     let gv = addr_of_mut(ccx, cv, align, kind);
     unsafe {
index f7f065a3562ed2bb8223a1741af97490884abd47..d36878b03322a30fbe24c4c98c66bdaed168a242 100644 (file)
 
 register_long_diagnostics! {
 
+E0510: r##"
+`return_address` was used in an invalid context. Erroneous code example:
+
+```ignore
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+unsafe fn by_value() -> i32 {
+    let _ = return_address();
+    // error: invalid use of `return_address` intrinsic: function does
+    //        not use out pointer
+    0
+}
+```
+
+Return values may be stored in a return register(s) or written into a so-called
+out pointer. In case the returned value is too big (this is
+target-ABI-dependent and generally not portable or future proof) to fit into
+the return register(s), the compiler will return the value by writing it into
+space allocated in the caller's stack frame. Example:
+
+```
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+unsafe fn by_pointer() -> String {
+    let _ = return_address();
+    String::new() // ok!
+}
+```
+"##,
+
 E0511: r##"
 Invalid monomorphization of an intrinsic function was used. Erroneous code
 example:
index a721361fce0e3aecbbd152edb8fd663507383df3..bd24647edf00b4b0f349c7e60f90bbab479a2dbe 100644 (file)
@@ -617,6 +617,18 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
 
         },
 
+
+        (_, "return_address") => {
+            if !fcx.fn_ty.ret.is_indirect() {
+                span_err!(tcx.sess, span, E0510,
+                          "invalid use of `return_address` intrinsic: function \
+                           does not use out pointer");
+                C_null(Type::i8p(ccx))
+            } else {
+                PointerCast(bcx, llvm::get_param(fcx.llfn, 0), Type::i8p(ccx))
+            }
+        }
+
         (_, "discriminant_value") => {
             let val_ty = substs.types.get(FnSpace, 0);
             match val_ty.sty {
index c369858556d3a454c823b2862d636b6226afdcdd..9cb5d8b6ad62a2e43781bb64b3b7806f5fabe425 100644 (file)
@@ -28,7 +28,6 @@
 #![feature(const_fn)]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
-#![feature(iter_arith)]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
index 28bcd8a633c1c96fa792da00036a55ac8f24d953..c3f2c4f2c8bfe5bf333550dbadc1ff6687690620 100644 (file)
@@ -572,11 +572,8 @@ pub fn trans_scalar_checked_binop(&mut self,
         // will only succeed if both operands are constant.
         // This is necessary to determine when an overflow Assert
         // will always panic at runtime, and produce a warning.
-        match const_scalar_checked_binop(bcx.tcx(), op, lhs, rhs, input_ty) {
-            Some((val, of)) => {
-                return OperandValue::Pair(val, C_bool(bcx.ccx(), of));
-            }
-            None => {}
+        if let Some((val, of)) = const_scalar_checked_binop(bcx.tcx(), op, lhs, rhs, input_ty) {
+            return OperandValue::Pair(val, C_bool(bcx.ccx(), of));
         }
 
         let (val, of) = match op {
index fa00ea1e7801bb4a7cf31a2b30fba1fc867077b9..ab859b88a85972d55200ba32260199974fa94422 100644 (file)
@@ -169,8 +169,7 @@ pub struct Instance<'tcx> {
 
 impl<'tcx> fmt::Display for Instance<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[],
-                             |tcx| Some(tcx.lookup_item_type(self.def).generics))
+        ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[], |_| None)
     }
 }
 
index 5a3268e9e447b25a9165c02eec623c5f6164cedd..0fb08ec9855de006bebaa15071f41af6dc453d43 100644 (file)
@@ -275,6 +275,8 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
             "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" =>
                 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
 
+            "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)),
+
             "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
 
             "discriminant_value" => (1, vec![
index 373fc83fa7444c1c8cf1f0f5b5e545dbe6939f4e..6a1baf13b273d4f2bda0c4f4c3d4cf1b688ca38c 100644 (file)
@@ -864,9 +864,8 @@ fn assemble_where_clause_candidates(&mut self,
     // THE ACTUAL SEARCH
 
     fn pick(mut self) -> PickResult<'tcx> {
-        match self.pick_core() {
-            Some(r) => return r,
-            None => {}
+        if let Some(r) = self.pick_core() {
+            return r;
         }
 
         let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
@@ -929,9 +928,8 @@ fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>>
             return None;
         }
 
-        match self.pick_by_value_method(step) {
-            Some(result) => return Some(result),
-            None => {}
+        if let Some(result) = self.pick_by_value_method(step) {
+            return Some(result);
         }
 
         self.pick_autorefd_method(step)
@@ -1003,12 +1001,10 @@ fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
         let mut possibly_unsatisfied_predicates = Vec::new();
 
         debug!("searching inherent candidates");
-        match self.consider_candidates(self_ty, &self.inherent_candidates,
-                                       &mut possibly_unsatisfied_predicates) {
-            None => {}
-            Some(pick) => {
-                return Some(pick);
-            }
+        if let Some(pick) = self.consider_candidates(self_ty,
+                                                     &self.inherent_candidates,
+                                                     &mut possibly_unsatisfied_predicates) {
+            return Some(pick);
         }
 
         debug!("searching extension candidates");
index 83b5ab71cc2246f5285041e5c1a2005bbba719a7..3bc90f05d2536c2f41ebcef9a45dcfc4bc2a5a29 100644 (file)
@@ -1157,6 +1157,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         let rty = ccx.tcx.node_id_to_type(id);
         let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), e.id);
         let declty = fcx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
+        fcx.require_type_is_sized(declty, e.span, traits::ConstSized);
         fcx.check_const_with_ty(sp, e, declty);
     });
 }
index 7f5f3ae120b7a0cad09a8bd9ca6dac5cb1629180..9786132dc537b53c57c0a4b47abde6fe863536ac 100644 (file)
@@ -334,13 +334,8 @@ fn visit_method_map_entry(&self,
         };
 
         //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE
-        match new_method {
-            Some(method) => {
-                self.tcx().tables.borrow_mut().method_map.insert(
-                    method_call,
-                    method);
-            }
-            None => {}
+        if let Some(method) = new_method {
+            self.tcx().tables.borrow_mut().method_map.insert(method_call, method);
         }
     }
 
index ade7806e71d12fab312019cc21ad2e7d843216e6..198e9afd5e12c77f1604d753ba612ba8414ad38c 100644 (file)
@@ -174,12 +174,9 @@ fn check_implementation(&self, item: &Item) {
     }
 
     fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
-        match self.inherent_impls.borrow().get(&base_def_id) {
-            Some(implementation_list) => {
-                implementation_list.borrow_mut().push(impl_def_id);
-                return;
-            }
-            None => {}
+        if let Some(implementation_list) = self.inherent_impls.borrow().get(&base_def_id) {
+            implementation_list.borrow_mut().push(impl_def_id);
+            return;
         }
 
         self.inherent_impls.borrow_mut().insert(
index 7ccff7ad3d87c06da57c00a6d79561a5b6e2e17e..84452589dfda389a9bc7e708c55dc16f9f497e9f 100644 (file)
@@ -76,7 +76,6 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(iter_arith)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
@@ -313,14 +312,13 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
 fn check_for_entry_fn(ccx: &CrateCtxt) {
     let tcx = ccx.tcx;
     let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
-    match *tcx.sess.entry_fn.borrow() {
-        Some((id, sp)) => match tcx.sess.entry_type.get() {
+    if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
+        match tcx.sess.entry_type.get() {
             Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
             Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
             Some(config::EntryNone) => {}
             None => bug!("entry function without a type")
-        },
-        None => {}
+        }
     }
 }
 
index 8ffbd6be41878a56fe329fd273248b2d9e3c00c1..8894b9732fe89250f32f7ead6c3ab0de0cf60b4d 100644 (file)
@@ -432,7 +432,6 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
     ret.push(clean::Item {
         inner: clean::ImplItem(clean::Impl {
             unsafety: hir::Unsafety::Normal, // FIXME: this should be decoded
-            derived: clean::detect_derived(&attrs),
             provided_trait_methods: provided,
             trait_: trait_,
             for_: for_,
index bc3d9d83399f8340ab6b2a4dcb2cf720ea22915c..7827459baa87f310818813f69320e9982cbd0859 100644 (file)
@@ -2242,14 +2242,9 @@ pub struct Impl {
     pub trait_: Option<Type>,
     pub for_: Type,
     pub items: Vec<Item>,
-    pub derived: bool,
     pub polarity: Option<ImplPolarity>,
 }
 
-fn detect_derived<M: AttrMetaMethods>(attrs: &[M]) -> bool {
-    attr::contains_name(attrs, "automatically_derived")
-}
-
 impl Clean<Vec<Item>> for doctree::Impl {
     fn clean(&self, cx: &DocContext) -> Vec<Item> {
         let mut ret = Vec::new();
@@ -2286,7 +2281,6 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
                 trait_: trait_,
                 for_: self.for_.clean(cx),
                 items: items,
-                derived: detect_derived(&self.attrs),
                 polarity: Some(self.polarity.clean(cx)),
             }),
         });
index f4da8167ea28640fe4f9c8b64a5f9ee9303d267e..85ea94e02e8d794014a13263b2d9db970337abe6 100644 (file)
@@ -149,9 +149,9 @@ pub fn run_core(search_paths: SearchPaths,
     let name = link::find_crate_name(Some(&sess), &krate.attrs, &input);
 
     let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = {
-        let make_glob_map = resolve::MakeGlobMap::No;
-        driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None, make_glob_map)
-            .expect("phase_2_configure_and_expand aborted in rustdoc!")
+        driver::phase_2_configure_and_expand(
+            &sess, &cstore, krate, &name, None, resolve::MakeGlobMap::No, |_| Ok(()),
+        ).expect("phase_2_configure_and_expand aborted in rustdoc!")
     };
 
     let arenas = ty::CtxtArenas::new();
index 760e84622cfe5d880f3a0375c397b26ab0b3eb20..77c4a0f8174a3296d00a2a94a480d912375cead7 100644 (file)
@@ -131,9 +131,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     write!(f, ":&nbsp;{}", TyParamBounds(&tp.bounds))?;
                 }
 
-                match tp.default {
-                    Some(ref ty) => { write!(f, "&nbsp;=&nbsp;{}", ty)?; },
-                    None => {}
+                if let Some(ref ty) = tp.default {
+                    write!(f, "&nbsp;=&nbsp;{}", ty)?;
                 };
             }
         }
@@ -401,15 +400,12 @@ fn primitive_link(f: &mut fmt::Formatter,
                 }
                 (_, render::Unknown) => None,
             };
-            match loc {
-                Some(root) => {
-                    write!(f, "<a class='primitive' href='{}{}/primitive.{}.html'>",
-                           root,
-                           path.0.first().unwrap(),
-                           prim.to_url_str())?;
-                    needs_termination = true;
-                }
-                None => {}
+            if let Some(root) = loc {
+                write!(f, "<a class='primitive' href='{}{}/primitive.{}.html'>",
+                       root,
+                       path.0.first().unwrap(),
+                       prim.to_url_str())?;
+                needs_termination = true;
             }
         }
         None => {}
index 2e2f99897733dc3947b9323217f3227867357b87..84e98a6739193e9b917135c3b218e00cb15bd08f 100644 (file)
@@ -352,9 +352,8 @@ fn write_header(class: Option<&str>,
                 out: &mut Write)
                 -> io::Result<()> {
     write!(out, "<pre ")?;
-    match id {
-        Some(id) => write!(out, "id='{}' ", id)?,
-        None => {}
+    if let Some(id) = id {
+        write!(out, "id='{}' ", id)?;
     }
     write!(out, "class='rust {}'>\n", class.unwrap_or(""))
 }
index 35be593b3bd817006b6b2034c2da2f999f6ce820..6ab2bcc768590f16a5285188725d06f0c147039d 100644 (file)
@@ -399,7 +399,6 @@ fn init_ids() -> HashMap<String, usize> {
      "methods",
      "deref-methods",
      "implementations",
-     "derived_implementations"
      ].into_iter().map(|id| (String::from(*id), 1)).collect()
 }
 
@@ -590,19 +589,16 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     // Attach all orphan methods to the type's definition if the type
     // has since been learned.
     for &(did, ref item) in orphan_methods {
-        match paths.get(&did) {
-            Some(&(ref fqp, _)) => {
-                search_index.push(IndexItem {
-                    ty: shortty(item),
-                    name: item.name.clone().unwrap(),
-                    path: fqp[..fqp.len() - 1].join("::"),
-                    desc: Escape(&shorter(item.doc_value())).to_string(),
-                    parent: Some(did),
-                    parent_idx: None,
-                    search_type: get_index_search_type(&item),
-                });
-            },
-            None => {}
+        if let Some(&(ref fqp, _)) = paths.get(&did) {
+            search_index.push(IndexItem {
+                ty: shortty(item),
+                name: item.name.clone().unwrap(),
+                path: fqp[..fqp.len() - 1].join("::"),
+                desc: Escape(&shorter(item.doc_value())).to_string(),
+                parent: Some(did),
+                parent_idx: None,
+                search_type: get_index_search_type(&item),
+            });
         }
     }
 
@@ -2095,15 +2091,12 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
         <h2 id='implementors'>Implementors</h2>
         <ul class='item-list' id='implementors-list'>
     ")?;
-    match cache.implementors.get(&it.def_id) {
-        Some(implementors) => {
-            for i in implementors {
-                write!(w, "<li><code>")?;
-                fmt_impl_for_trait_page(&i.impl_, w)?;
-                writeln!(w, "</code></li>")?;
-            }
+    if let Some(implementors) = cache.implementors.get(&it.def_id) {
+        for i in implementors {
+            write!(w, "<li><code>")?;
+            fmt_impl_for_trait_page(&i.impl_, w)?;
+            writeln!(w, "</code></li>")?;
         }
-        None => {}
     }
     write!(w, "</ul>")?;
     write!(w, r#"<script type="text/javascript" async
@@ -2528,25 +2521,11 @@ fn render_assoc_items(w: &mut fmt::Formatter,
         }
         write!(w, "<h2 id='implementations'>Trait \
                    Implementations</h2>")?;
-        let (derived, manual): (Vec<_>, Vec<&Impl>) = traits.iter().partition(|i| {
-            i.inner_impl().derived
-        });
-        for i in &manual {
+        for i in &traits {
             let did = i.trait_did().unwrap();
             let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
             render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
         }
-        if !derived.is_empty() {
-            write!(w, "<h3 id='derived_implementations'>\
-                           Derived Implementations \
-                       </h3>")?;
-            for i in &derived {
-                let did = i.trait_did().unwrap();
-                let assoc_link = AssocItemLink::GotoSource(did,
-                                                           &i.inner_impl().provided_trait_methods);
-                render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
-            }
-        }
     }
     Ok(())
 }
index 95d02d6ce4bee33135aae9a295aaf593965bbd6d..e3bc8037d13b67b0395baeb7560bb6b964a8c283 100644 (file)
@@ -95,9 +95,9 @@ pub fn run(input: &str,
     cfg.extend(config::parse_cfgspecs(cfgs.clone()));
     let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
     let driver::ExpansionResult { defs, mut hir_forest, .. } = {
-        let make_glob_map = MakeGlobMap::No;
-        phase_2_configure_and_expand(&sess, &cstore, krate, "rustdoc-test", None, make_glob_map)
-            .expect("phase_2_configure_and_expand aborted in rustdoc!")
+        phase_2_configure_and_expand(
+            &sess, &cstore, krate, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(())
+        ).expect("phase_2_configure_and_expand aborted in rustdoc!")
     };
 
     let dep_graph = DepGraph::new(false);
index 90b2c6116038c4024c764499ee0107631dc00772..6c4b6c4506b814fd7d19b5575841b6703ef54f52 100644 (file)
@@ -1764,9 +1764,8 @@ fn parse(&mut self) -> JsonEvent {
                     return self.parse_array(first);
                 }
                 ParseArrayComma => {
-                    match self.parse_array_comma_or_end() {
-                        Some(evt) => { return evt; }
-                        None => {}
+                    if let Some(evt) = self.parse_array_comma_or_end() {
+                        return evt;
                     }
                 }
                 ParseObject(first) => {
@@ -2583,9 +2582,8 @@ impl<'a, T: Encodable> fmt::Display for AsPrettyJson<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut shim = FormatShim { inner: f };
         let mut encoder = PrettyEncoder::new(&mut shim);
-        match self.indent {
-            Some(n) => encoder.set_indent(n),
-            None => {}
+        if let Some(n) = self.indent {
+            encoder.set_indent(n);
         }
         match self.inner.encode(&mut encoder) {
             Ok(_) => Ok(()),
index 536f168e4010843216c6bc07044ae6a57c78e1e4..60d7e01d98814a99dc61c725a6fd97c09713c7e2 100644 (file)
@@ -14,7 +14,7 @@
 use borrow::Borrow;
 use cmp::max;
 use fmt::{self, Debug};
-use hash::{Hash, SipHasher, BuildHasher};
+use hash::{Hash, Hasher, BuildHasher, SipHasher13};
 use iter::FromIterator;
 use mem::{self, replace};
 use ops::{Deref, Index};
@@ -1711,10 +1711,30 @@ pub fn new() -> RandomState {
 
 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
 impl BuildHasher for RandomState {
-    type Hasher = SipHasher;
+    type Hasher = DefaultHasher;
     #[inline]
-    fn build_hasher(&self) -> SipHasher {
-        SipHasher::new_with_keys(self.k0, self.k1)
+    fn build_hasher(&self) -> DefaultHasher {
+        DefaultHasher(SipHasher13::new_with_keys(self.k0, self.k1))
+    }
+}
+
+/// The default `Hasher` used by `RandomState`.
+///
+/// The internal algorithm is not specified, and so it and its hashes should
+/// not be relied upon over releases.
+#[unstable(feature = "hashmap_default_hasher", issue = "0")]
+pub struct DefaultHasher(SipHasher13);
+
+#[unstable(feature = "hashmap_default_hasher", issue = "0")]
+impl Hasher for DefaultHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.0.write(msg)
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.0.finish()
     }
 }
 
index 135ea8a5e7cb40412c310d8a922df41ba085cd33..a396c7be09ad16db2effaf51845b45085bd80d47 100644 (file)
 #![feature(reflect_marker)]
 #![feature(rustc_attrs)]
 #![feature(shared)]
+#![feature(sip_hash_13)]
 #![feature(slice_bytes)]
 #![feature(slice_concat_ext)]
 #![feature(slice_patterns)]
index d510339f1c5b492d29941a9cbfe10bc7e4e926d5..b93ca8277e636bb7b3b8ff1ed30cd84db1a20ef1 100644 (file)
@@ -344,6 +344,9 @@ fn hash<H: hash::Hasher>(&self, s: &mut H) {
 /// some other type (e.g. a string) just for it to be converted back to
 /// `SocketAddr` in constructor methods is pointless.
 ///
+/// Addresses returned by the operating system that are not IP addresses are
+/// silently ignored.
+///
 /// Some examples:
 ///
 /// ```no_run
@@ -448,12 +451,7 @@ fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
 
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = lookup_host(s)?;
-    let v: Vec<_> = ips.map(|a| {
-        a.map(|mut a| {
-            a.set_port(p);
-            a
-        })
-    }).collect()?;
+    let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
     Ok(v.into_iter())
 }
 
index 45070460282710f84e0de8fcd37e179c573f8421..ac13b23ebee50256b70f780917b182f77ffce26b 100644 (file)
@@ -98,8 +98,8 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
                                               addresses",
            issue = "27705")]
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
 }
 
 /// Resolve the host specified by `host` as a number of `SocketAddr` instances.
@@ -107,6 +107,9 @@ fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
 /// This method may perform a DNS query to resolve `host` and may also inspect
 /// system configuration to resolve the specified hostname.
 ///
+/// The returned iterator will skip over any unknown addresses returned by the
+/// operating system.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -116,7 +119,7 @@ fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
 ///
 /// # fn foo() -> std::io::Result<()> {
 /// for host in try!(net::lookup_host("rust-lang.org")) {
-///     println!("found address: {}", try!(host));
+///     println!("found address: {}", host);
 /// }
 /// # Ok(())
 /// # }
index 17d412411c0481fe47813bfca8f0270cdfdaf707..7a676c041ad89084e72b2ea5325923f0e0fabf4b 100644 (file)
@@ -110,6 +110,7 @@ pub unsafe fn coshf(n: c_float) -> c_float {
         }
 
         #[inline]
+        #[allow(deprecated)]
         pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float {
             let (a, b) = f64::frexp(x as f64);
             *value = b as c_int;
@@ -117,6 +118,7 @@ pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float {
         }
 
         #[inline]
+        #[allow(deprecated)]
         pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float {
             f64::ldexp(x as f64, n as isize) as c_float
         }
@@ -265,7 +267,11 @@ pub fn classify(self) -> FpCategory { num::Float::classify(self) }
     /// [floating-point]: ../reference.html#machine-types
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
+    #[allow(deprecated)]
     pub fn integer_decode(self) -> (u64, i16, i8) {
         num::Float::integer_decode(self)
     }
@@ -718,6 +724,9 @@ pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn ldexp(x: f32, exp: isize) -> f32 {
         unsafe { cmath::ldexpf(x, exp as c_int) }
@@ -747,6 +756,9 @@ pub fn ldexp(x: f32, exp: isize) -> f32 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn frexp(self) -> (f32, isize) {
         unsafe {
@@ -773,6 +785,9 @@ pub fn frexp(self) -> (f32, isize) {
     #[unstable(feature = "float_extras",
                reason = "unsure about its place in the world",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn next_after(self, other: f32) -> f32 {
         unsafe { cmath::nextafterf(self, other) }
@@ -1384,6 +1399,7 @@ fn test_classify() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_integer_decode() {
         assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
         assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
@@ -1711,6 +1727,7 @@ fn test_to_radians() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_ldexp() {
         let f1 = 2.0f32.powi(-123);
         let f2 = 2.0f32.powi(-111);
@@ -1731,6 +1748,7 @@ fn test_ldexp() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_frexp() {
         let f1 = 2.0f32.powi(-123);
         let f2 = 2.0f32.powi(-111);
@@ -1750,6 +1768,7 @@ fn test_frexp() {
     }
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    #[allow(deprecated)]
     fn test_frexp_nowin() {
         let inf: f32 = f32::INFINITY;
         let neg_inf: f32 = f32::NEG_INFINITY;
index 70b7706535ca17784f4ebf81f95aac4b93110b5d..67a1c302483d20644bdd157def4bed445c47e6fa 100644 (file)
@@ -209,7 +209,11 @@ pub fn classify(self) -> FpCategory { num::Float::classify(self) }
     /// [floating-point]: ../reference.html#machine-types
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
+    #[allow(deprecated)]
     pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
 
     /// Returns the largest integer less than or equal to a number.
@@ -613,6 +617,9 @@ pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn ldexp(x: f64, exp: isize) -> f64 {
         unsafe { cmath::ldexp(x, exp as c_int) }
@@ -640,6 +647,9 @@ pub fn ldexp(x: f64, exp: isize) -> f64 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn frexp(self) -> (f64, isize) {
         unsafe {
@@ -664,6 +674,9 @@ pub fn frexp(self) -> (f64, isize) {
     #[unstable(feature = "float_extras",
                reason = "unsure about its place in the world",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn next_after(self, other: f64) -> f64 {
         unsafe { cmath::nextafter(self, other) }
@@ -1277,6 +1290,7 @@ fn test_classify() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_integer_decode() {
         assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
         assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
@@ -1604,6 +1618,7 @@ fn test_to_radians() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_ldexp() {
         let f1 = 2.0f64.powi(-123);
         let f2 = 2.0f64.powi(-111);
@@ -1624,6 +1639,7 @@ fn test_ldexp() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_frexp() {
         let f1 = 2.0f64.powi(-123);
         let f2 = 2.0f64.powi(-111);
@@ -1643,6 +1659,7 @@ fn test_frexp() {
     }
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    #[allow(deprecated)]
     fn test_frexp_nowin() {
         let inf: f64 = INFINITY;
         let neg_inf: f64 = NEG_INFINITY;
index d33df05acf2248fcea578cdc2672176aff1089dd..20804d62dfab663401f07293496b3c4d1066973d 100644 (file)
@@ -17,6 +17,7 @@
 #![allow(missing_docs)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 pub use core::num::{Zero, One};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError};
@@ -46,7 +47,6 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod tests {
-    use super::*;
     use u8;
     use u16;
     use u32;
@@ -198,15 +198,14 @@ fn $test_name() {
 
     #[test]
     fn test_pow() {
-        fn naive_pow<T: Mul<Output=T> + One + Copy>(base: T, exp: usize) -> T {
-            let one: T = T::one();
+        fn naive_pow<T: Mul<Output=T> + Copy>(one: T, base: T, exp: usize) -> T {
             (0..exp).fold(one, |acc, _| acc * base)
         }
         macro_rules! assert_pow {
             (($num:expr, $exp:expr) => $expected:expr) => {{
                 let result = $num.pow($exp);
                 assert_eq!(result, $expected);
-                assert_eq!(result, naive_pow($num, $exp));
+                assert_eq!(result, naive_pow(1, $num, $exp));
             }}
         }
         assert_pow!((3u32,     0 ) => 1);
index c103ff7f4b025345a260fd586f01eb01829b643e..ad4cdef615847719d2f63ff078b8f36346a302e9 100644 (file)
@@ -1057,7 +1057,6 @@ pub fn push<P: AsRef<Path>>(&mut self, path: P) {
         self._push(path.as_ref())
     }
 
-    #[allow(deprecated)]
     fn _push(&mut self, path: &Path) {
         // in general, a separator is needed if the rightmost byte is not a separator
         let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
@@ -1443,8 +1442,7 @@ pub fn to_path_buf(&self) -> PathBuf {
     /// `is_absolute` and `has_root` are equivalent.
     ///
     /// * On Windows, a path is absolute if it has a prefix and starts with the
-    /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not. In
-    /// other words, `path.is_absolute() == path.prefix().is_some() && path.has_root()`.
+    /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not.
     ///
     /// # Examples
     ///
index 54b9b466c42240b7f8dab99bb962af50f4e1e553..274e495d70eb620b3f0d4e5f2ea91ee618825dfb 100644 (file)
@@ -119,14 +119,22 @@ pub struct LookupHost {
 }
 
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> {
-        unsafe {
-            if self.cur.is_null() { return None }
-            let ret = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr),
-                                       (*self.cur).ai_addrlen as usize);
-            self.cur = (*self.cur).ai_next as *mut c::addrinfo;
-            Some(ret)
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        loop {
+            unsafe {
+                let cur = match self.cur.as_ref() {
+                    None => return None,
+                    Some(c) => c,
+                };
+                self.cur = cur.ai_next;
+                match sockaddr_to_addr(mem::transmute(cur.ai_addr),
+                                       cur.ai_addrlen as usize)
+                {
+                    Ok(addr) => return Some(addr),
+                    Err(_) => continue,
+                }
+            }
         }
     }
 }
index 12a877f7478204feb105c8ee78b51c11b4499efb..f0fd42fc99b806eadba0b261ddefe2ca61872980 100644 (file)
@@ -12,8 +12,6 @@
 
 use io::{self, ErrorKind};
 use libc;
-use num::One;
-use ops::Neg;
 
 #[cfg(target_os = "android")]   pub use os::android as platform;
 #[cfg(target_os = "bitrig")]    pub use os::bitrig as platform;
@@ -123,9 +121,23 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
     }
 }
 
-pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
-    let one: T = T::one();
-    if t == -one {
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
+pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() {
         Err(io::Error::last_os_error())
     } else {
         Ok(t)
@@ -133,7 +145,8 @@ pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
 }
 
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
+    where T: IsMinusOne,
+          F: FnMut() -> T
 {
     loop {
         match cvt(f()) {
index 6dd4f4c3e750e8b2df17d3e5941c9f97bce901f7..12219c1e9d42bf750717bdb1c8f16b169c17d1e7 100644 (file)
@@ -14,7 +14,6 @@
 
 use ffi::{OsStr, OsString};
 use io::{self, ErrorKind};
-use num::Zero;
 use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use time::Duration;
@@ -178,8 +177,22 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
     }
 }
 
-fn cvt<I: PartialEq + Zero>(i: I) -> io::Result<I> {
-    if i == I::zero() {
+trait IsZero {
+    fn is_zero(&self) -> bool;
+}
+
+macro_rules! impl_is_zero {
+    ($($t:ident)*) => ($(impl IsZero for $t {
+        fn is_zero(&self) -> bool {
+            *self == 0
+        }
+    })*)
+}
+
+impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+fn cvt<I: IsZero>(i: I) -> io::Result<I> {
+    if i.is_zero() {
         Err(io::Error::last_os_error())
     } else {
         Ok(i)
index b05dcf42a3324636d3a5a8ae1acb3a9a6e5c8789..71e164f012f1f7c4dfe9cba2ef212660414da296 100644 (file)
@@ -17,8 +17,6 @@
 use libc::{c_int, c_void, c_ulong};
 use mem;
 use net::{SocketAddr, Shutdown};
-use num::One;
-use ops::Neg;
 use ptr;
 use sync::Once;
 use sys::c;
@@ -60,11 +58,26 @@ fn last_error() -> io::Error {
     io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
 }
 
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
 /// and if so, returns the last error from the Windows socket interface. This
 /// function must be called before another call to the socket API is made.
-pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
-    if t == -T::one() {
+pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() {
         Err(last_error())
     } else {
         Ok(t)
@@ -82,7 +95,8 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 
 /// Just to provide the same interface as sys/unix/net.rs
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
+    where T: IsMinusOne,
+          F: FnMut() -> T
 {
     cvt(f())
 }
index 3c88fb8f6703b6796655bdd20020943a2a118bee..e01bd2a93aacdfcb9b806a0af3e5960fdff47d12 100644 (file)
     static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
 }
 
+enum AttrError {
+    MultipleItem(InternedString),
+    UnknownMetaItem(InternedString),
+    MissingSince,
+    MissingFeature,
+    MultipleStabilityLevels,
+}
+
+fn handle_errors(diag: &Handler, span: Span, error: AttrError) {
+    match error {
+        AttrError::MultipleItem(item) => span_err!(diag, span, E0538,
+                                                   "multiple '{}' items", item),
+        AttrError::UnknownMetaItem(item) => span_err!(diag, span, E0541,
+                                                      "unknown meta item '{}'", item),
+        AttrError::MissingSince => span_err!(diag, span, E0542, "missing 'since'"),
+        AttrError::MissingFeature => span_err!(diag, span, E0546, "missing 'feature'"),
+        AttrError::MultipleStabilityLevels => span_err!(diag, span, E0544,
+                                                        "multiple stability levels"),
+    }
+}
+
 pub fn mark_used(attr: &Attribute) {
     let AttrId(id) = attr.node.id;
     USED_ATTRS.with(|slot| {
@@ -303,10 +324,10 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Inte
             if let s@Some(_) = attr.value_str() {
                 s
             } else {
-                diag.struct_span_err(attr.span,
-                                     "export_name attribute has invalid format")
-                    .help("use #[export_name=\"*\"]")
-                    .emit();
+                struct_span_err!(diag, attr.span, E0533,
+                                 "export_name attribute has invalid format")
+                                .help("use #[export_name=\"*\"]")
+                                .emit();
                 None
             }
         } else {
@@ -339,14 +360,16 @@ pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> In
             MetaItemKind::List(ref n, ref items) if n == "inline" => {
                 mark_used(attr);
                 if items.len() != 1 {
-                    diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
+                    diagnostic.map(|d|{ span_err!(d, attr.span, E0534, "expected one argument"); });
                     InlineAttr::None
                 } else if contains_name(&items[..], "always") {
                     InlineAttr::Always
                 } else if contains_name(&items[..], "never") {
                     InlineAttr::Never
                 } else {
-                    diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
+                    diagnostic.map(|d| {
+                        span_err!(d, (*items[0]).span, E0535, "invalid argument");
+                    });
                     InlineAttr::None
                 }
             }
@@ -374,13 +397,13 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
             mis.iter().all(|mi| cfg_matches(cfgs, &mi, sess, features)),
         ast::MetaItemKind::List(ref pred, ref mis) if &pred[..] == "not" => {
             if mis.len() != 1 {
-                sess.span_diagnostic.span_err(cfg.span, "expected 1 cfg-pattern");
+                span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
                 return false;
             }
             !cfg_matches(cfgs, &mis[0], sess, features)
         }
         ast::MetaItemKind::List(ref pred, _) => {
-            sess.span_diagnostic.span_err(cfg.span, &format!("invalid predicate `{}`", pred));
+            span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", pred);
             false
         },
         ast::MetaItemKind::Word(_) | ast::MetaItemKind::NameValue(..) => {
@@ -446,15 +469,14 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
         if let Some(metas) = attr.meta_item_list() {
             let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
                 if item.is_some() {
-                    diagnostic.span_err(meta.span, &format!("multiple '{}' items",
-                                                             meta.name()));
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
                     return false
                 }
                 if let Some(v) = meta.value_str() {
                     *item = Some(v);
                     true
                 } else {
-                    diagnostic.span_err(meta.span, "incorrect meta item");
+                    span_err!(diagnostic, meta.span, E0539, "incorrect meta item");
                     false
                 }
             };
@@ -462,7 +484,8 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
             match tag {
                 "rustc_deprecated" => {
                     if rustc_depr.is_some() {
-                        diagnostic.span_err(item_sp, "multiple rustc_deprecated attributes");
+                        span_err!(diagnostic, item_sp, E0540,
+                                  "multiple rustc_deprecated attributes");
                         break
                     }
 
@@ -473,8 +496,8 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             "since" => if !get(meta, &mut since) { continue 'outer },
                             "reason" => if !get(meta, &mut reason) { continue 'outer },
                             _ => {
-                                diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
-                                                                        meta.name()));
+                                handle_errors(diagnostic, meta.span,
+                                              AttrError::UnknownMetaItem(meta.name()));
                                 continue 'outer
                             }
                         }
@@ -488,18 +511,18 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             })
                         }
                         (None, _) => {
-                            diagnostic.span_err(attr.span(), "missing 'since'");
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
                             continue
                         }
                         _ => {
-                            diagnostic.span_err(attr.span(), "missing 'reason'");
+                            span_err!(diagnostic, attr.span(), E0543, "missing 'reason'");
                             continue
                         }
                     }
                 }
                 "unstable" => {
                     if stab.is_some() {
-                        diagnostic.span_err(item_sp, "multiple stability levels");
+                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
                         break
                     }
 
@@ -512,8 +535,8 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             "reason" => if !get(meta, &mut reason) { continue 'outer },
                             "issue" => if !get(meta, &mut issue) { continue 'outer },
                             _ => {
-                                diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
-                                                                        meta.name()));
+                                handle_errors(diagnostic, meta.span,
+                                              AttrError::UnknownMetaItem(meta.name()));
                                 continue 'outer
                             }
                         }
@@ -528,7 +551,8 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                         if let Ok(issue) = issue.parse() {
                                             issue
                                         } else {
-                                            diagnostic.span_err(attr.span(), "incorrect 'issue'");
+                                            span_err!(diagnostic, attr.span(), E0545,
+                                                      "incorrect 'issue'");
                                             continue
                                         }
                                     }
@@ -538,18 +562,18 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             })
                         }
                         (None, _, _) => {
-                            diagnostic.span_err(attr.span(), "missing 'feature'");
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
                             continue
                         }
                         _ => {
-                            diagnostic.span_err(attr.span(), "missing 'issue'");
+                            span_err!(diagnostic, attr.span(), E0547, "missing 'issue'");
                             continue
                         }
                     }
                 }
                 "stable" => {
                     if stab.is_some() {
-                        diagnostic.span_err(item_sp, "multiple stability levels");
+                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
                         break
                     }
 
@@ -560,8 +584,8 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             "feature" => if !get(meta, &mut feature) { continue 'outer },
                             "since" => if !get(meta, &mut since) { continue 'outer },
                             _ => {
-                                diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
-                                                                        meta.name()));
+                                handle_errors(diagnostic, meta.span,
+                                              AttrError::UnknownMetaItem(meta.name()));
                                 continue 'outer
                             }
                         }
@@ -578,11 +602,11 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                             })
                         }
                         (None, _) => {
-                            diagnostic.span_err(attr.span(), "missing 'feature'");
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
                             continue
                         }
                         _ => {
-                            diagnostic.span_err(attr.span(), "missing 'since'");
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
                             continue
                         }
                     }
@@ -590,7 +614,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                 _ => unreachable!()
             }
         } else {
-            diagnostic.span_err(attr.span(), "incorrect stability attribute type");
+            span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
             continue
         }
     }
@@ -603,8 +627,9 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
             }
             stab.rustc_depr = Some(rustc_depr);
         } else {
-            diagnostic.span_err(item_sp, "rustc_deprecated attribute must be paired with \
-                                          either stable or unstable attribute");
+            span_err!(diagnostic, item_sp, E0549,
+                      "rustc_deprecated attribute must be paired with \
+                       either stable or unstable attribute");
         }
     }
 
@@ -627,22 +652,21 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
         mark_used(attr);
 
         if depr.is_some() {
-            diagnostic.span_err(item_sp, "multiple deprecated attributes");
+            span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
             break
         }
 
         depr = if let Some(metas) = attr.meta_item_list() {
             let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
                 if item.is_some() {
-                    diagnostic.span_err(meta.span, &format!("multiple '{}' items",
-                                                             meta.name()));
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
                     return false
                 }
                 if let Some(v) = meta.value_str() {
                     *item = Some(v);
                     true
                 } else {
-                    diagnostic.span_err(meta.span, "incorrect meta item");
+                    span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
                     false
                 }
             };
@@ -654,8 +678,8 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
                     "since" => if !get(meta, &mut since) { continue 'outer },
                     "note" => if !get(meta, &mut note) { continue 'outer },
                     _ => {
-                        diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
-                                                                meta.name()));
+                        handle_errors(diagnostic, meta.span,
+                                      AttrError::UnknownMetaItem(meta.name()));
                         continue 'outer
                     }
                 }
@@ -689,7 +713,7 @@ pub fn require_unique_names(diagnostic: &Handler, metas: &[P<MetaItem>]) {
 
         if !set.insert(name.clone()) {
             panic!(diagnostic.span_fatal(meta.span,
-                                  &format!("duplicate meta item `{}`", name)));
+                                         &format!("duplicate meta item `{}`", name)));
         }
     }
 }
@@ -718,8 +742,8 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                                 Some(ity) => Some(ReprInt(item.span, ity)),
                                 None => {
                                     // Not a word we recognize
-                                    diagnostic.span_err(item.span,
-                                                        "unrecognized representation hint");
+                                    span_err!(diagnostic, item.span, E0552,
+                                              "unrecognized representation hint");
                                     None
                                 }
                             }
@@ -731,7 +755,8 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                         }
                     }
                     // Not a word:
-                    _ => diagnostic.span_err(item.span, "unrecognized enum representation hint")
+                    _ => span_err!(diagnostic, item.span, E0553,
+                                   "unrecognized enum representation hint"),
                 }
             }
         }
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
new file mode 100644 (file)
index 0000000..eb30657
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2014 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.
+
+#![allow(non_snake_case)]
+
+// Error messages for EXXXX errors.
+// Each message should start and end with a new line, and be wrapped to 80 characters.
+// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
+register_long_diagnostics! {
+
+E0533: r##"
+```compile_fail,E0533
+#[export_name]
+pub fn something() {}
+
+fn main() {}
+```
+"##,
+
+}
+
+register_diagnostics! {
+    E0534, // expected one argument
+    E0535, // invalid argument
+    E0536, // expected 1 cfg-pattern
+    E0537, // invalid predicate
+    E0538, // multiple [same] items
+    E0539, // incorrect meta item
+    E0540, // multiple rustc_deprecated attributes
+    E0541, // unknown meta item
+    E0542, // missing 'since'
+    E0543, // missing 'reason'
+    E0544, // multiple stability levels
+    E0545, // incorrect 'issue'
+    E0546, // missing 'feature'
+    E0547, // missing 'issue'
+    E0548, // incorrect stability attribute type
+    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
+    E0550, // multiple deprecated attributes
+    E0551, // incorrect meta item
+    E0552, // unrecognized representation hint
+    E0553, // unrecognized enum representation hint
+    E0554, // #[feature] may not be used on the [] release channel
+    E0555, // malformed feature attribute, expected #![feature(...)]
+    E0556, // malformed feature, expected just one word
+    E0557, // feature has been removed
+}
index ca38ef068d05f4c610f7480e9f5444392af7afbd..92670cd9def9015cc14d76809f3ba0f93e560046 100644 (file)
@@ -944,9 +944,8 @@ fn find_escape_frame(&mut self) -> &mut MapChainFrame {
 
     pub fn find(&self, k: Name) -> Option<Rc<SyntaxExtension>> {
         for frame in self.chain.iter().rev() {
-            match frame.map.get(&k) {
-                Some(v) => return Some(v.clone()),
-                None => {}
+            if let Some(v) = frame.map.get(&k) {
+                return Some(v.clone());
             }
         }
         None
index 58328eb4246756607aa037cf4d35a8731a929224..40944a9a1c2d360bf13c78a9b1a45d742f2fb998 100644 (file)
@@ -225,12 +225,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
         } else { /* repeat */
             *r.repeat_idx.last_mut().unwrap() += 1;
             r.stack.last_mut().unwrap().idx = 0;
-            match r.stack.last().unwrap().sep.clone() {
-                Some(tk) => {
-                    r.cur_tok = tk; /* repeat same span, I guess */
-                    return ret_val;
-                }
-                None => {}
+            if let Some(tk) = r.stack.last().unwrap().sep.clone() {
+                r.cur_tok = tk; // repeat same span, I guess
+                return ret_val;
             }
         }
     }
index d6476fdb2f0159fbb001f51daf2cd500912c0af4..27485ee65fcc037640e5309d2534d583e47e91da 100644 (file)
@@ -1103,17 +1103,16 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F
 
         match attr.meta_item_list() {
             None => {
-                span_handler.span_err(attr.span, "malformed feature attribute, \
-                                                  expected #![feature(...)]");
+                span_err!(span_handler, attr.span, E0555,
+                          "malformed feature attribute, expected #![feature(...)]");
             }
             Some(list) => {
                 for mi in list {
                     let name = match mi.node {
                         ast::MetaItemKind::Word(ref word) => (*word).clone(),
                         _ => {
-                            span_handler.span_err(mi.span,
-                                                  "malformed feature, expected just \
-                                                   one word");
+                            span_err!(span_handler, mi.span, E0556,
+                                      "malformed feature, expected just one word");
                             continue
                         }
                     };
@@ -1123,7 +1122,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F
                     }
                     else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter()
                         .find(|& &(n, _, _)| name == n) {
-                        span_handler.span_err(mi.span, "feature has been removed");
+                        span_err!(span_handler, mi.span, E0557, "feature has been removed");
                     }
                     else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
                         .find(|& &(n, _, _)| name == n) {
@@ -1179,9 +1178,9 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
         for attr in &krate.attrs {
             if attr.check_name("feature") {
                 let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
-                let ref msg = format!("#[feature] may not be used on the {} release channel",
-                                      release_channel);
-                span_handler.span_err(attr.span, msg);
+                span_err!(span_handler, attr.span, E0554,
+                          "#[feature] may not be used on the {} release channel",
+                          release_channel);
             }
         }
     }
index 652cf68db07592b7f3d66fb9ebf660d67c02127f..8febf1c49ec2badeb618ed632b4c661168da73d4 100644 (file)
@@ -33,6 +33,7 @@
 #![feature(str_escape)]
 #![feature(unicode)]
 #![feature(question_mark)]
+#![feature(rustc_diagnostic_macros)]
 
 extern crate serialize;
 extern crate term;
@@ -66,6 +67,18 @@ macro_rules! panictry {
     })
 }
 
+#[macro_use]
+pub mod diagnostics {
+    #[macro_use]
+    pub mod macros;
+    pub mod plugin;
+    pub mod metadata;
+}
+
+// NB: This module needs to be declared first so diagnostics are
+// registered before they are used.
+pub mod diagnostic_list;
+
 pub mod util {
     pub mod interner;
     pub mod lev_distance;
@@ -80,12 +93,6 @@ pub mod util {
     pub use self::thin_vec::ThinVec;
 }
 
-pub mod diagnostics {
-    pub mod macros;
-    pub mod plugin;
-    pub mod metadata;
-}
-
 pub mod json;
 
 pub mod syntax {
@@ -130,3 +137,5 @@ pub mod tt {
         pub mod macro_rules;
     }
 }
+
+// __build_diagnostic_array! { libsyntax, DIAGNOSTICS }
index f6e94b7caeabe617ceb2e17a3e5f34512c4410e8..15344cef1dbcf438d157614df5bfd39064462152 100644 (file)
@@ -160,12 +160,9 @@ pub fn parse_meta_item(&mut self) -> PResult<'a, P<ast::MetaItem>> {
             _ => None,
         };
 
-        match nt_meta {
-            Some(meta) => {
-                self.bump();
-                return Ok(meta);
-            }
-            None => {}
+        if let Some(meta) = nt_meta {
+            self.bump();
+            return Ok(meta);
         }
 
         let lo = self.span.lo;
index 809f4daa3616d7a481dace362d62e59499668db0..77b5c10899a3da8cc158c1003161b44a200d78bf 100644 (file)
@@ -470,15 +470,12 @@ fn scan_optional_raw_name(&mut self) -> Option<ast::Name> {
     /// PRECONDITION: self.curr is not whitespace
     /// Eats any kind of comment.
     fn scan_comment(&mut self) -> Option<TokenAndSpan> {
-        match self.curr {
-            Some(c) => {
-                if c.is_whitespace() {
-                    self.span_diagnostic.span_err(syntax_pos::mk_sp(self.last_pos, self.last_pos),
-                                                  "called consume_any_line_comment, but there \
-                                                   was whitespace");
-                }
+        if let Some(c) = self.curr {
+            if c.is_whitespace() {
+                self.span_diagnostic.span_err(syntax_pos::mk_sp(self.last_pos, self.last_pos),
+                                              "called consume_any_line_comment, but there \
+                                               was whitespace");
             }
-            None => {}
         }
 
         if self.curr_is('/') {
index 20a54228d016cdb222a1975dc219332586227349..6fa95afd9fb2223c9dec5dc1565cb68a40db4e7f 100644 (file)
@@ -2752,9 +2752,8 @@ fn parse_kleene_op<'a>(parser: &mut Parser<'a>) ->
             }
         };
 
-        match parse_kleene_op(self)? {
-            Some(kleene_op) => return Ok((None, kleene_op)),
-            None => {}
+        if let Some(kleene_op) = parse_kleene_op(self)? {
+            return Ok((None, kleene_op));
         }
 
         let separator = self.bump_and_get();
@@ -5691,15 +5690,12 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             }
             _ => None
         };
-        match nt_item {
-            Some(mut item) => {
-                self.bump();
-                let mut attrs = attrs;
-                mem::swap(&mut item.attrs, &mut attrs);
-                item.attrs.extend(attrs);
-                return Ok(Some(P(item)));
-            }
-            None => {}
+        if let Some(mut item) = nt_item {
+            self.bump();
+            let mut attrs = attrs;
+            mem::swap(&mut item.attrs, &mut attrs);
+            item.attrs.extend(attrs);
+            return Ok(Some(P(item)));
         }
 
         let lo = self.span.lo;
index b56cec72a956e0555a8b0d5a710c0378c8e72690..ce30c3de7595867490b94ec77281f91d2e1a51fe 100644 (file)
@@ -1264,13 +1264,10 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                     _ => {}
                 }
 
-                match *opt_trait {
-                    Some(ref t) => {
-                        try!(self.print_trait_ref(t));
-                        try!(space(&mut self.s));
-                        try!(self.word_space("for"));
-                    }
-                    None => {}
+                if let Some(ref t) = *opt_trait {
+                    try!(self.print_trait_ref(t));
+                    try!(space(&mut self.s));
+                    try!(self.word_space("for"));
                 }
 
                 try!(self.print_type(&ty));
@@ -1338,7 +1335,7 @@ fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::
                 if comma {
                     try!(self.word_space(","))
                 }
-                try!(self.print_lifetime_def(lifetime_def));
+                try!(self.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds));
                 comma = true;
             }
             try!(word(&mut self.s, ">"));
@@ -1470,11 +1467,8 @@ pub fn print_tt(&mut self, tt: &tokenstream::TokenTree) -> io::Result<()> {
                     try!(self.print_tt(tt_elt));
                 }
                 try!(word(&mut self.s, ")"));
-                match seq.separator {
-                    Some(ref tk) => {
-                        try!(word(&mut self.s, &token_to_string(tk)));
-                    }
-                    None => {},
+                if let Some(ref tk) = seq.separator {
+                    try!(word(&mut self.s, &token_to_string(tk)));
                 }
                 match seq.op {
                     tokenstream::KleeneOp::ZeroOrMore => word(&mut self.s, "*"),
@@ -2749,16 +2743,20 @@ pub fn print_lifetime(&mut self,
         self.print_name(lifetime.name)
     }
 
-    pub fn print_lifetime_def(&mut self,
-                              lifetime: &ast::LifetimeDef)
-                              -> io::Result<()>
+    pub fn print_lifetime_bounds(&mut self,
+                                 lifetime: &ast::Lifetime,
+                                 bounds: &[ast::Lifetime])
+                                 -> io::Result<()>
     {
-        try!(self.print_lifetime(&lifetime.lifetime));
-        let mut sep = ":";
-        for v in &lifetime.bounds {
-            try!(word(&mut self.s, sep));
-            try!(self.print_lifetime(v));
-            sep = "+";
+        try!(self.print_lifetime(lifetime));
+        if !bounds.is_empty() {
+            try!(word(&mut self.s, ": "));
+            for (i, bound) in bounds.iter().enumerate() {
+                if i != 0 {
+                    try!(word(&mut self.s, " + "));
+                }
+                try!(self.print_lifetime(bound));
+            }
         }
         Ok(())
     }
@@ -2781,8 +2779,8 @@ pub fn print_generics(&mut self,
 
         try!(self.commasep(Inconsistent, &ints[..], |s, &idx| {
             if idx < generics.lifetimes.len() {
-                let lifetime = &generics.lifetimes[idx];
-                s.print_lifetime_def(lifetime)
+                let lifetime_def = &generics.lifetimes[idx];
+                s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
             } else {
                 let idx = idx - generics.lifetimes.len();
                 let param = &generics.ty_params[idx];
@@ -2833,16 +2831,7 @@ pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
                 ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
                                                                                ref bounds,
                                                                                ..}) => {
-                    try!(self.print_lifetime(lifetime));
-                    try!(word(&mut self.s, ":"));
-
-                    for (i, bound) in bounds.iter().enumerate() {
-                        try!(self.print_lifetime(bound));
-
-                        if i != 0 {
-                            try!(word(&mut self.s, ":"));
-                        }
-                    }
+                    try!(self.print_lifetime_bounds(lifetime, bounds));
                 }
                 ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
                     try!(self.print_path(path, false, 0));
index e01f4ed1f9bd233a932762ebf3cd110078703805..f33898109cc57e3110aa40a13b1ac7cfeaefe1da 100644 (file)
@@ -360,13 +360,10 @@ impl<'a, 'b> visit::Visitor for Visitor<'a, 'b> {
         fn visit_ty(&mut self, ty: &ast::Ty) {
             match ty.node {
                 ast::TyKind::Path(_, ref path) if !path.global => {
-                    match path.segments.first() {
-                        Some(segment) => {
-                            if self.ty_param_names.contains(&segment.identifier.name) {
-                                self.types.push(P(ty.clone()));
-                            }
+                    if let Some(segment) = path.segments.first() {
+                        if self.ty_param_names.contains(&segment.identifier.name) {
+                            self.types.push(P(ty.clone()));
                         }
-                        None => {}
                     }
                 }
                 _ => {}
index 546f8eaa692863d8280f9cba0c8a1a35aff2e965..c6c4b6135c681e1eec0e83b0e05b8679cd006bb4 100644 (file)
@@ -88,12 +88,9 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
         }
     };
 
-    match exprs.next() {
-        None => {}
-        Some(_) => {
-            cx.span_err(sp, "env! takes 1 or 2 arguments");
-            return DummyResult::expr(sp);
-        }
+    if let Some(_) = exprs.next() {
+        cx.span_err(sp, "env! takes 1 or 2 arguments");
+        return DummyResult::expr(sp);
     }
 
     let e = match env::var(&var[..]) {
index f311f16f11b0efbebd7c59390f75102f537c171b..dc572e652c6713de2597706a78dc074e3014f00d 100644 (file)
@@ -126,16 +126,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
 
             panictry!(p.expect(&token::Eq));
             let e = panictry!(p.parse_expr());
-            match names.get(name) {
-                None => {}
-                Some(prev) => {
-                    ecx.struct_span_err(e.span,
-                                        &format!("duplicate argument named `{}`",
-                                                 name))
-                       .span_note(prev.span, "previously here")
-                       .emit();
-                    continue
-                }
+            if let Some(prev) = names.get(name) {
+                ecx.struct_span_err(e.span,
+                                    &format!("duplicate argument named `{}`",
+                                             name))
+                    .span_note(prev.span, "previously here")
+                    .emit();
+                continue;
             }
             order.push(name.to_string());
             names.insert(name.to_string(), e);
@@ -665,13 +662,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
             Some(piece) => {
                 if !parser.errors.is_empty() { break }
                 cx.verify_piece(&piece);
-                match cx.trans_piece(&piece) {
-                    Some(piece) => {
-                        let s = cx.trans_literal_string();
-                        cx.str_pieces.push(s);
-                        cx.pieces.push(piece);
-                    }
-                    None => {}
+                if let Some(piece) = cx.trans_piece(&piece) {
+                    let s = cx.trans_literal_string();
+                    cx.str_pieces.push(s);
+                    cx.pieces.push(piece);
                 }
             }
             None => break
index 88be3ade83922b399abb116253c386c8dcc58d1b..c90c93e75acd87f930f76db4dc0fb43691a72132 100644 (file)
@@ -747,12 +747,9 @@ fn len_if_padded(t: &TestDescAndFn) -> usize {
             PadOnRight => t.desc.name.as_slice().len(),
         }
     }
-    match tests.iter().max_by_key(|t| len_if_padded(*t)) {
-        Some(t) => {
-            let n = t.desc.name.as_slice();
-            st.max_name_len = n.len();
-        }
-        None => {}
+    if let Some(t) = tests.iter().max_by_key(|t| len_if_padded(*t)) {
+        let n = t.desc.name.as_slice();
+        st.max_name_len = n.len();
     }
     run_tests(opts, tests, |x| callback(&x, &mut st))?;
     return st.write_run_finish();
index 9c6ed991df8a6b0d6b9e948abcb7ff7d2f42661b..c9d1eb39f0a3de464f6028d192e6ad4737ceb1e0 100644 (file)
@@ -213,6 +213,7 @@ dependencies = [
  "rustc_back 0.0.0",
  "rustc_bitflags 0.0.0",
  "rustc_const_math 0.0.0",
+ "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_llvm 0.0.0",
  "serialize 0.0.0",
index 0b420158488229de571db0d9458c2c96f4526cec..f74855a0849b15ac8698d4fad29c5a1b75c50963 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
diff --git a/src/test/compile-fail/const-unsized.rs b/src/test/compile-fail/const-unsized.rs
new file mode 100644 (file)
index 0000000..72a5c5f
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2016 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.
+
+use std::fmt::Debug;
+
+const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
+//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE does not have a constant size known at compile-time
+//~| NOTE constant expressions must have a statically known size
+
+const CONST_FOO: str = *"foo";
+//~^ ERROR `str: std::marker::Sized` is not satisfied
+//~| NOTE does not have a constant size known at compile-time
+//~| NOTE constant expressions must have a statically known size
+
+static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
+//~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE does not have a constant size known at compile-time
+//~| NOTE constant expressions must have a statically known size
+
+static STATIC_BAR: str = *"bar";
+//~^ ERROR `str: std::marker::Sized` is not satisfied
+//~| NOTE does not have a constant size known at compile-time
+//~| NOTE constant expressions must have a statically known size
+
+fn main() {
+    println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
+}
diff --git a/src/test/compile-fail/intrinsic-return-address.rs b/src/test/compile-fail/intrinsic-return-address.rs
new file mode 100644 (file)
index 0000000..9060568
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 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.
+
+#![allow(warnings)]
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+unsafe fn f() { let _ = return_address(); }
+//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
+
+unsafe fn g() -> isize { let _ = return_address(); 0 }
+//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
+
+fn main() {}
index cbeac77479811fc8d37096d842f4df40473ae24f..b9382520cf9d3166c3ba6461973d4aeff5a4884d 100644 (file)
@@ -11,6 +11,8 @@
 fn main() {
     static foo: Fn() -> u32 = || -> u32 {
         //~^ ERROR: mismatched types
+        //~| ERROR: `std::ops::Fn() -> u32 + 'static: std::marker::Sized` is not satisfied
+
         0
     };
 }
index 5b0dd256b4c41788670d51f2c66f4fddc3d30a4e..c00be91a2d74daf067a0d99abb6251d0652239c9 100644 (file)
@@ -17,9 +17,8 @@ pub fn main() {
 
     // Bool => does not implement iterator.
     for i in false..true {}
-    //~^ ERROR `bool: std::num::One` is not satisfied
-    //~^^ ERROR `bool: std::iter::Step` is not satisfied
-    //~^^^ ERROR `for<'a> &'a bool: std::ops::Add` is not satisfied
+    //~^ ERROR `bool: std::iter::Step` is not satisfied
+    //~^^ ERROR `for<'a> &'a bool: std::ops::Add` is not satisfied
 
     // Unsized type.
     let arr: &[_] = &[1, 2, 3];
index 8c7c0c275db8ec74c14afe841756b8c386606489..d35f2cbb584c767958051215f4ad1dc1e962ed9b 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod bogus_attribute_types_1 {
-    #[stable(feature = "a", since = "a", reason)] //~ ERROR unknown meta item 'reason'
+    #[stable(feature = "a", since = "a", reason)] //~ ERROR unknown meta item 'reason' [E0541]
     fn f1() { }
 
-    #[stable(feature = "a", since)] //~ ERROR incorrect meta item
+    #[stable(feature = "a", since)] //~ ERROR incorrect meta item [E0539]
     fn f2() { }
 
-    #[stable(feature, since = "a")] //~ ERROR incorrect meta item
+    #[stable(feature, since = "a")] //~ ERROR incorrect meta item [E0539]
     fn f3() { }
 
-    #[stable(feature = "a", since(b))] //~ ERROR incorrect meta item
+    #[stable(feature = "a", since(b))] //~ ERROR incorrect meta item [E0539]
     fn f5() { }
 
-    #[stable(feature(b), since = "a")] //~ ERROR incorrect meta item
+    #[stable(feature(b), since = "a")] //~ ERROR incorrect meta item [E0539]
     fn f6() { }
 }
 
 mod bogus_attribute_types_2 {
-    #[unstable] //~ ERROR incorrect stability attribute type
+    #[unstable] //~ ERROR incorrect stability attribute type [E0548]
     fn f1() { }
 
-    #[unstable = "a"] //~ ERROR incorrect stability attribute type
+    #[unstable = "a"] //~ ERROR incorrect stability attribute type [E0548]
     fn f2() { }
 
-    #[stable] //~ ERROR incorrect stability attribute type
+    #[stable] //~ ERROR incorrect stability attribute type [E0548]
     fn f3() { }
 
-    #[stable = "a"] //~ ERROR incorrect stability attribute type
+    #[stable = "a"] //~ ERROR incorrect stability attribute type [E0548]
     fn f4() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated] //~ ERROR incorrect stability attribute type
+    #[rustc_deprecated] //~ ERROR incorrect stability attribute type [E0548]
     fn f5() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated = "a"] //~ ERROR incorrect stability attribute type
+    #[rustc_deprecated = "a"] //~ ERROR incorrect stability attribute type [E0548]
     fn f6() { }
 }
 
 mod missing_feature_names {
-    #[unstable(issue = "0")] //~ ERROR missing 'feature'
+    #[unstable(issue = "0")] //~ ERROR missing 'feature' [E0546]
     fn f1() { }
 
-    #[unstable(feature = "a")] //~ ERROR missing 'issue'
+    #[unstable(feature = "a")] //~ ERROR missing 'issue' [E0547]
     fn f2() { }
 
-    #[stable(since = "a")] //~ ERROR missing 'feature'
+    #[stable(since = "a")] //~ ERROR missing 'feature' [E0546]
     fn f3() { }
 }
 
 mod missing_version {
-    #[stable(feature = "a")] //~ ERROR missing 'since'
+    #[stable(feature = "a")] //~ ERROR missing 'since' [E0542]
     fn f1() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated(reason = "a")] //~ ERROR missing 'since'
+    #[rustc_deprecated(reason = "a")] //~ ERROR missing 'since' [E0542]
     fn f2() { }
 }
 
 #[unstable(feature = "a", issue = "0")]
-#[stable(feature = "a", since = "b")]
-fn multiple1() { } //~ ERROR multiple stability levels
+#[stable(feature = "a", since = "b")] //~ ERROR multiple stability levels [E0544]
+fn multiple1() { }
 
 #[unstable(feature = "a", issue = "0")]
-#[unstable(feature = "a", issue = "0")]
-fn multiple2() { } //~ ERROR multiple stability levels
+#[unstable(feature = "a", issue = "0")] //~ ERROR multiple stability levels [E0544]
+fn multiple2() { }
 
 #[stable(feature = "a", since = "b")]
-#[stable(feature = "a", since = "b")]
-fn multiple3() { } //~ ERROR multiple stability levels
+#[stable(feature = "a", since = "b")] //~ ERROR multiple stability levels [E0544]
+fn multiple3() { }
 
 #[stable(feature = "a", since = "b")]
 #[rustc_deprecated(since = "b", reason = "text")]
 #[rustc_deprecated(since = "b", reason = "text")]
-fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes
+fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes [E0540]
 //~^ ERROR Invalid stability or deprecation version found
 
 #[rustc_deprecated(since = "a", reason = "text")]
-fn deprecated_without_unstable_or_stable() { } //~ ERROR rustc_deprecated attribute must be paired
+fn deprecated_without_unstable_or_stable() { }
+//~^ ERROR rustc_deprecated attribute must be paired with either stable or unstable attribute
 
 fn main() { }
index eb92bcf065d3f582150d8683af12cb422d41a45a..1638caaa9233740e63a0a19586448ccfcc447516 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index 7c9e0d3a92c98517406dc658fcbd0a0c333ff6d8..99523ca699f0ead6f703b37835dc1916505f8cd1 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index 1e6a7232904a8b344260e157bd76d8df8bfd2aab..dcf4859792d280912295e2c0c7a1f6afafb3d7ad 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index 73c35ee6f82ca6b89438d63f89f54ab5ec9c888d..7e51ca456b21a4607bf75e4a92fbe92802200094 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index b8908e2cbd1e506d549f99cd051d2be27828c863..54ca87d84c1ec371df5a16b03efbd17ddfcb51e0 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index 291e441aa5e2dc800ac24203324fa64cc03e7667..ea90faaf610888bdb402fd2b9298f873e541508b 100644 (file)
@@ -17,7 +17,7 @@
 
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
-//~| NOTE: perhaps this crate needs to be recompiled
+//~| NOTE: perhaps that crate needs to be recompiled
 //~| NOTE: crate `a` path #1:
 //~| NOTE: crate `b` path #1:
 
index ed816a93c52d230ec59382fd76bf9059cba8c2a1..c0a5a0a17eb2655c8d0d9bcd87b102cb7515a6e7 100644 (file)
@@ -22,7 +22,7 @@
 
 extern crate uta;
 extern crate utb; //~ ERROR: found possibly newer version of crate `uta` which `utb` depends
-//~| NOTE: perhaps this crate needs to be recompiled?
+//~| NOTE: perhaps that crate needs to be recompiled?
 //~| NOTE: crate `uta` path #1:
 //~| NOTE: crate `utb` path #1:
 
diff --git a/src/test/debuginfo/pretty-huge-vec.rs b/src/test/debuginfo/pretty-huge-vec.rs
new file mode 100644 (file)
index 0000000..bb53852
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2013-2016 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.
+
+// ignore-windows failing on win32 bot
+// ignore-freebsd: gdb package too new
+// ignore-android: FIXME(#10381)
+// compile-flags:-g
+// min-gdb-version 7.7
+// min-lldb-version: 310
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command: run
+
+// gdb-command: print vec
+// gdb-check:$1 = Vec<u8>(len: 1000000000, cap: 1000000000) = {[...]...}
+
+// gdb-command: print slice
+// gdb-check:$2 = &[u8](len: 1000000000) = {[...]...}
+
+
+#![allow(unused_variables)]
+
+fn main() {
+
+    // Vec
+    let mut vec: Vec<u8> = Vec::with_capacity(1_000_000_000);
+    unsafe{ vec.set_len(1_000_000_000) }
+    let slice = &vec[..];
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/debuginfo/pretty-uninitialized-vec.rs b/src/test/debuginfo/pretty-uninitialized-vec.rs
new file mode 100644 (file)
index 0000000..7516965
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2013-2016 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.
+
+// ignore-windows failing on win32 bot
+// ignore-freebsd: gdb package too new
+// ignore-android: FIXME(#10381)
+// compile-flags:-g
+// min-gdb-version 7.7
+// min-lldb-version: 310
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command: run
+
+// gdb-command: print vec
+// gdb-check:$1 = Vec<i32>(len: [...], cap: [...])[...]
+
+
+#![allow(unused_variables)]
+
+fn main() {
+
+    let vec;
+    zzz(); // #break
+    vec = vec![0];
+
+}
+
+fn zzz() { () }
index 0d396c885eb85f2efbad184cc3e3ee9846702d04..cdb5bc4ecfb6ec371976059ad75cc9d7c85ac047 100644 (file)
 // gdb-command:print *((int64_t[2]*)('vec_slices::MUT_VECT_SLICE'.data_ptr))
 // gdb-check:$15 = {64, 65}
 
+//gdb-command:print mut_slice.length
+//gdb-check:$16 = 5
+//gdb-command:print *((int64_t[5]*)(mut_slice.data_ptr))
+//gdb-check:$17 = {1, 2, 3, 4, 5}
+
 
 // === LLDB TESTS ==================================================================================
 
@@ -106,6 +111,8 @@ fn main() {
         MUT_VECT_SLICE = VECT_SLICE;
     }
 
+    let mut_slice: &mut [i64] = &mut [1, 2, 3, 4, 5];
+
     zzz(); // #break
 }
 
diff --git a/src/test/pretty/lifetime.rs b/src/test/pretty/lifetime.rs
new file mode 100644 (file)
index 0000000..2cc7153
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2016 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.
+
+// pp-exact
+
+fn f1<'a, 'b, 'c>(_x: &'a u32, _y: &'b u32, _z: &'c u32) where 'c: 'a + 'b { }
+
+fn main() { }
index cca7707509f0c7f335d3581aa99345e5403df8d7..388064a8be8546cd0078ef0abf0899b00d1c733d 100644 (file)
@@ -10,6 +10,6 @@
 
 // pp-exact
 
-fn f<'a, 'b, T>(t: T) -> isize where T: 'a, 'a:'b, T: Eq { 0 }
+fn f<'a, 'b, T>(t: T) -> isize where T: 'a, 'a: 'b, T: Eq { 0 }
 
 fn main() { }
index a94b2a85c7754046716f305773b3f514a7df9aa0..21e1463b6ef955efdf9929e42acf2f4944c7deaa 100644 (file)
@@ -241,8 +241,9 @@ fn compile_program(input: &str, sysroot: PathBuf)
         let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
 
         let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = {
-            driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None, MakeGlobMap::No)
-                .expect("phase_2 returned `None`")
+            driver::phase_2_configure_and_expand(
+                &sess, &cstore, krate, &id, None, MakeGlobMap::No, |_| Ok(()),
+            ).expect("phase_2 returned `None`")
         };
 
         let arenas = ty::CtxtArenas::new();
diff --git a/src/test/run-make/llvm-phase/Makefile b/src/test/run-make/llvm-phase/Makefile
new file mode 100644 (file)
index 0000000..6a8e172
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) test.rs
+       $(call RUN,test $(RUSTC))
diff --git a/src/test/run-make/llvm-phase/test.rs b/src/test/run-make/llvm-phase/test.rs
new file mode 100644 (file)
index 0000000..402b5ed
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright 2016 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.
+
+#![feature(plugin, rustc_private, box_syntax)]
+
+extern crate rustc;
+extern crate rustc_driver;
+extern crate rustc_llvm;
+#[macro_use] extern crate syntax;
+extern crate getopts;
+
+use rustc_driver::{CompilerCalls, Compilation};
+use rustc_driver::driver::CompileController;
+use rustc::session::Session;
+use syntax::codemap::FileLoader;
+use std::io;
+use std::path::{PathBuf, Path};
+
+struct JitLoader;
+
+impl FileLoader for JitLoader {
+    fn file_exists(&self, _: &Path) -> bool { true }
+    fn abs_path(&self, _: &Path) -> Option<PathBuf> { None }
+    fn read_file(&self, _: &Path) -> io::Result<String> {
+        Ok(r#"
+#[no_mangle]
+pub fn test_add(a: i32, b: i32) -> i32 { a + b }
+"#.to_string())
+    }
+}
+
+#[derive(Copy, Clone)]
+struct JitCalls;
+
+impl<'a> CompilerCalls<'a> for JitCalls {
+    fn build_controller(&mut self,
+                        _: &Session,
+                        _: &getopts::Matches)
+                        -> CompileController<'a> {
+        let mut cc = CompileController::basic();
+        cc.after_llvm.stop = Compilation::Stop;
+        cc.after_llvm.run_callback_on_error = true;
+        cc.after_llvm.callback = Box::new(|state| {
+            state.session.abort_if_errors();
+            let trans = state.trans.unwrap();
+            assert_eq!(trans.modules.len(), 1);
+            let rs_llmod = trans.modules[0].llmod;
+            unsafe { rustc_llvm::LLVMDumpModule(rs_llmod) };
+        });
+        cc
+    }
+}
+
+fn main() {
+    use rustc_driver;
+
+    let mut path = match std::env::args().nth(2) {
+        Some(path) => PathBuf::from(&path),
+        None => panic!("missing rustc path")
+    };
+
+    // Remove two segments from rustc path to get sysroot.
+    path.pop();
+    path.pop();
+
+    let args: Vec<String> =
+        format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap())
+        .split(' ').map(|s| s.to_string()).collect();
+
+    let (result, _) = rustc_driver::run_compiler_with_file_loader(
+        &args, &mut JitCalls, box JitLoader);
+    if let Err(n) = result {
+        panic!("Error {}", n);
+    }
+}
index edf8e9df465dc23e825d18a1bee7bade996eb494..0da4af34ef03d9ae30dd28a9200174f47f21ee55 100644 (file)
@@ -28,7 +28,7 @@ all:
        # Ensure crateC fails to compile since A1 is "missing" and A2/A3 hashes do not match
        $(RUSTC) -L $(A2) -L $(A3) crateC.rs >$(LOG) 2>&1 || true
        grep "error: found possibly newer version of crate \`crateA\` which \`crateB\` depends on" $(LOG)
-       grep "note: perhaps this crate needs to be recompiled?" $(LOG)
+       grep "note: perhaps that crate needs to be recompiled?" $(LOG)
        grep "note: crate \`crateA\` path #1:" $(LOG)
        grep "note: crate \`crateA\` path #2:" $(LOG)
        grep "note: crate \`crateB\` path #1:" $(LOG)
diff --git a/src/test/run-pass/intrinsic-return-address.rs b/src/test/run-pass/intrinsic-return-address.rs
new file mode 100644 (file)
index 0000000..63aed3f
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2012-2014 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.
+
+
+#![feature(intrinsics)]
+
+use std::ptr;
+
+struct Point {
+    x: f32,
+    y: f32,
+    z: f32,
+}
+
+extern "rust-intrinsic" {
+    fn return_address() -> *const u8;
+}
+
+fn f(result: &mut usize) -> Point {
+    unsafe {
+        *result = return_address() as usize;
+        Point {
+            x: 1.0,
+            y: 2.0,
+            z: 3.0,
+        }
+    }
+
+}
+
+fn main() {
+    let mut intrinsic_reported_address = 0;
+    let pt = f(&mut intrinsic_reported_address);
+    let actual_address = &pt as *const Point as usize;
+    assert_eq!(intrinsic_reported_address, actual_address);
+}
diff --git a/src/test/run-pass/issue-34503.rs b/src/test/run-pass/issue-34503.rs
new file mode 100644 (file)
index 0000000..e621724
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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 main() {
+    struct X;
+    trait Foo<T> {
+        fn foo(&self) where (T, Option<T>): Ord {}
+        fn bar(&self, x: &Option<T>) -> bool
+        where Option<T>: Ord { *x < *x }
+    }
+    impl Foo<X> for () {}
+    let _ = &() as &Foo<X>;
+}
index 07233a43b88e29308b81c84ad0ecba3ca52e9ee9..aaf129e7b8e4abf413e65847100a8dcf03f95ab8 100644 (file)
@@ -117,11 +117,6 @@ pub fn main() {
     assert_eq!(nonsense.next(), None);
     assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });
 
-    // conversion
-    assert_eq!(0...9, (0..10).into());
-    assert_eq!(0...0, (0..1).into());
-    assert_eq!(RangeInclusive::Empty { at: 1 }, (1..0).into());
-
     // output
     assert_eq!(format!("{:?}", 0...10), "0...10");
     assert_eq!(format!("{:?}", ...10), "...10");
index 953e060465a95f6a63dbeed742d6c4265c21c8d7..577da5c5af11d2b012eed6d4f860731c3050a452 100644 (file)
@@ -1012,8 +1012,7 @@ fn check_expected_errors(&self,
 
         // Parse the JSON output from the compiler and extract out the messages.
         let actual_errors = json::parse_output(&file_name, &proc_res.stderr, &proc_res);
-        let mut unexpected = 0;
-        let mut not_found = 0;
+        let mut unexpected = Vec::new();
         let mut found = vec![false; expected_errors.len()];
         for actual_error in &actual_errors {
             let opt_index =
@@ -1045,12 +1044,13 @@ fn check_expected_errors(&self,
                                      .map_or(String::from("message"),
                                              |k| k.to_string()),
                                      actual_error.msg));
-                        unexpected += 1;
+                        unexpected.push(actual_error.clone());
                     }
                 }
             }
         }
 
+        let mut not_found = Vec::new();
         // anything not yet found is a problem
         for (index, expected_error) in expected_errors.iter().enumerate() {
             if !found[index] {
@@ -1062,18 +1062,22 @@ fn check_expected_errors(&self,
                              .map_or("message".into(),
                                      |k| k.to_string()),
                              expected_error.msg));
-                not_found += 1;
+                not_found.push(expected_error.clone());
             }
         }
 
-        if unexpected > 0 || not_found > 0 {
+        if unexpected.len() > 0 || not_found.len() > 0 {
             self.error(
                 &format!("{} unexpected errors found, {} expected errors not found",
-                         unexpected, not_found));
+                         unexpected.len(), not_found.len()));
             print!("status: {}\ncommand: {}\n",
                    proc_res.status, proc_res.cmdline);
-            println!("actual errors (from JSON output): {:#?}\n", actual_errors);
-            println!("expected errors (from test file): {:#?}\n", expected_errors);
+            if unexpected.len() > 0 {
+                println!("unexpected errors (from JSON output): {:#?}\n", unexpected);
+            }
+            if not_found.len() > 0 {
+                println!("not found errors (from test file): {:#?}\n", not_found);
+            }
             panic!();
         }
     }
index 4b74833eaf79794ad1f5f7256a335c661cd1c5db..80c37d5597592de4e873a4876f1b274219c8e837 100644 (file)
@@ -138,22 +138,6 @@ fn check(cache: &mut Cache,
         return None;
     }
 
-    if file.ends_with("std/sys/ext/index.html") {
-        return None;
-    }
-
-    if let Some(file) = file.to_str() {
-        // FIXME(#31948)
-        if file.contains("ParseFloatError") {
-            return None;
-        }
-        // weird reexports, but this module is on its way out, so chalk it up to
-        // "rustdoc weirdness" and move on from there
-        if file.contains("scoped_tls") {
-            return None;
-        }
-    }
-
     let mut parser = UrlParser::new();
     parser.base_url(base);
 
@@ -170,12 +154,24 @@ fn check(cache: &mut Cache,
 
     // Search for anything that's the regex 'href[ ]*=[ ]*".*?"'
     with_attrs_in_source(&contents, " href", |url, i| {
+        // Ignore external URLs
+        if url.starts_with("http:") || url.starts_with("https:") ||
+           url.starts_with("javascript:") || url.starts_with("ftp:") ||
+           url.starts_with("irc:") || url.starts_with("data:") {
+            return;
+        }
         // Once we've plucked out the URL, parse it using our base url and
-        // then try to extract a file path. If either of these fail then we
-        // just keep going.
+        // then try to extract a file path.
         let (parsed_url, path) = match url_to_file_path(&parser, url) {
             Some((url, path)) => (url, PathBuf::from(path)),
-            None => return,
+            None => {
+                *errors = true;
+                println!("{}:{}: invalid link - {}",
+                         pretty_file.display(),
+                         i + 1,
+                         url);
+                return;
+            }
         };
 
         // Alright, if we've found a file name then this file had better
@@ -197,10 +193,11 @@ fn check(cache: &mut Cache,
                 Ok(res) => res,
                 Err(LoadError::IOError(err)) => panic!(format!("{}", err)),
                 Err(LoadError::BrokenRedirect(target, _)) => {
-                    print!("{}:{}: broken redirect to {}",
-                           pretty_file.display(),
-                           i + 1,
-                           target.display());
+                    *errors = true;
+                    println!("{}:{}: broken redirect to {}",
+                             pretty_file.display(),
+                             i + 1,
+                             target.display());
                     return;
                 }
                 Err(LoadError::IsRedirect) => unreachable!(),
index e0092f8e29e732b86d78369a833e9c4cb28d278d..436dc1197533638504fb8c6e808f1e8d51137b1c 100644 (file)
@@ -10,7 +10,6 @@
 
 #![deny(warnings)]
 
-#![feature(iter_arith)]
 #![feature(rustc_private)]
 #![feature(rustdoc)]
 #![feature(question_mark)]