# 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
#### 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
$ 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
```
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].
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.
+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)
==========================
;;
*-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.
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'`
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
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=
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)) \
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):
######################################################################
# The version number
-CFG_RELEASE_NUM=1.11.0
+CFG_RELEASE_NUM=1.12.0
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
# NB Make sure it starts with a dot to conform to semver pre-release
import argparse
import contextlib
+import datetime
import hashlib
import os
import shutil
import tarfile
import tempfile
+from time import time
+
def get(url, path, verbose=False):
sha_url = url + ".sha256"
try:
download(sha_path, sha_url, verbose)
+ if os.path.exists(path):
+ if verify(path, sha_path, False):
+ print("using already-download file " + path)
+ return
+ else:
+ print("ignoring already-download file " + path + " due to failed verification")
+ os.unlink(path)
download(temp_path, url, verbose)
- verify(temp_path, sha_path, verbose)
+ if not verify(temp_path, sha_path, True):
+ raise RuntimeError("failed verification")
print("moving {} to {}".format(temp_path, path))
shutil.move(temp_path, path)
finally:
found = hashlib.sha256(f.read()).hexdigest()
with open(sha_path, "r") as f:
expected, _ = f.readline().split()
- if found != expected:
- err = ("invalid checksum:\n"
+ verified = found == expected
+ if not verified and verbose:
+ print("invalid checksum:\n"
" found: {}\n"
" expected: {}".format(found, expected))
- if verbose:
- raise RuntimeError(err)
- sys.exit(err)
+ return verified
def unpack(tarball, dst, verbose=False, match=None):
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")
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"
parser.add_argument('--clean', action='store_true')
parser.add_argument('-v', '--verbose', action='store_true')
- args = [a for a in sys.argv if a != '-h']
+ args = [a for a in sys.argv if a != '-h' and a != '--help']
args, _ = parser.parse_known_args(args)
# Configure initial bootstrap
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()
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()
// 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));
}
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.
///
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
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";
}
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);
}
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));
+ }
+ }
}
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);
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));
// 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);
};
// 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() {
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");
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);
}
///
/// 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.
"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,
target.target);
}
+ AndroidCopyLibs { compiler } => {
+ check::android_copy_libs(self, &compiler, target.target);
+ }
+
+ // pseudo-steps
Dist { .. } |
- Doc { .. } | // pseudo-steps
+ Doc { .. } |
+ CheckTarget { .. } |
Check { .. } => {}
}
}
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) {
// 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"};
// 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) {
"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",
");
}
}
+
+ if target.contains("arm-linux-android") {
+ need_cmd("adb".as_ref());
+ }
}
for host in build.flags.host.iter() {
// 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 }),
(dist_mingw, DistMingw { _dummy: () }),
(dist_rustc, DistRustc { stage: u32 }),
(dist_std, DistStd { compiler: Compiler<'a> }),
+
+ // Misc targets
+ (android_copy_libs, AndroidCopyLibs { compiler: Compiler<'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)]
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),
]
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)]
}
return base
}
+
+ Source::AndroidCopyLibs { compiler } => {
+ vec![self.libtest(compiler)]
+ }
}
}
}
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
-Subproject commit a1ef94b76029780a510bc2dc9c6a791bd091ff19
+Subproject commit ac3d1cda612edccb6f1da53cbf7716e248405f3b
where F: Fn(&'a 32) -> i32 {
```
-However this presents a problem with in our case. When you specify the explict
+However this presents a problem with in our case. When you specify the explicit
lifetime on a function it binds that lifetime to the *entire* scope of the function
instead of just the invocation scope of our closure. This means that the borrow checker
will see a mutable reference in the same lifetime as our immutable reference and fail
```
This lets the Rust compiler find the minimum lifetime to invoke our closure and
-satisfy the borrow checker's rules. Our function then compiles and excutes as we
+satisfy the borrow checker's rules. Our function then compiles and executes as we
expect.
```rust
//! The `foo` module contains a lot of useful functionality blah blah blah
```
+### Crate documentation
+
+Crates can be documented by placing an inner doc comment (`//!`) at the
+beginning of the crate root, aka `lib.rs`:
+
+```rust
+//! This is documentation for the `foo` crate.
+//!
+//! The foo crate is meant to be used for bar.
+```
+
### Documentation comment style
Check out [RFC 505][rfc505] for full conventions around the style and format of
# 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.
[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])
[Cargo’s documentation][cargodoc] contains more details.
[semver]: http://semver.org
-[cargodoc]: http://doc.crates.io/crates-io.html
+[cargodoc]: http://doc.crates.io/specifying-dependencies.html
Now, without changing any of our code, let’s build our project:
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:
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
#### On ranges:
```rust
-for (i,j) in (5..10).enumerate() {
+for (i, j) in (5..10).enumerate() {
println!("i = {} and j = {}", i, j);
}
```
# Interior vs. Exterior Mutability
However, when we say something is ‘immutable’ in Rust, that doesn’t mean that
-it’s not able to be changed: we mean something has ‘exterior mutability’. Consider,
-for example, [`Arc<T>`][arc]:
+it’s not able to be changed: we are referring to its ‘exterior mutability’ that
+in this case is immutable. Consider, for example, [`Arc<T>`][arc]:
```rust
use std::sync::Arc;
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.
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!
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
foo(&v);
```
-errors with:
+will give us this error:
```text
error: cannot borrow immutable borrowed content `*v` as mutable
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
# 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
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:
```
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
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.
```
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
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.
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
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
```
-Here, `black` and `origin` are not equal, even though they contain the same
-values.
-It is almost always better to use a `struct` than a tuple struct. We
-would write `Color` and `Point` like this instead:
+Here, `black` and `origin` are not the same type, even though they contain the
+same values.
+
+The members of a tuple struct may be accessed by dot notation or destructuring
+`let`, just like regular tuples:
+
+```rust
+# struct Color(i32, i32, i32);
+# struct Point(i32, i32, i32);
+# let black = Color(0, 0, 0);
+# let origin = Point(0, 0, 0);
+let black_r = black.0;
+let Point(_, origin_y, origin_z) = origin;
+```
+
+Patterns like `Point(_, origin_y, origin_z)` are also used in
+[match expressions][match].
+
+One case when a tuple struct is very useful is when it has only one element.
+We call this the ‘newtype’ pattern, because it allows you to create a new type
+that is distinct from its contained value and also expresses its own semantic
+meaning:
+
+```rust
+struct Inches(i32);
+
+let length = Inches(10);
+
+let Inches(integer_length) = length;
+println!("length is {} inches", integer_length);
+```
+
+As above, you can extract the inner integer type through a destructuring `let`.
+In this case, the `let Inches(integer_length)` assigns `10` to `integer_length`.
+We could have used dot notation to do the same thing:
+
+```rust
+# struct Inches(i32);
+# let length = Inches(10);
+let integer_length = length.0;
+```
+
+It's always possible to use a `struct` instead of a tuple struct, and can be
+clearer. We could write `Color` and `Point` like this instead:
```rust
struct Color {
referenced with dot notation as well, a `struct` gives us actual names,
rather than positions.
-There _is_ one case when a tuple struct is very useful, though, and that is when
-it has only one element. We call this the ‘newtype’ pattern, because
-it allows you to create a new type that is distinct from its contained value
-and also expresses its own semantic meaning:
-
-```rust
-struct Inches(i32);
-
-let length = Inches(10);
-
-let Inches(integer_length) = length;
-println!("length is {} inches", integer_length);
-```
-
-As you can see here, you can extract the inner integer type through a
-destructuring `let`, as with regular tuples. In this case, the
-`let Inches(integer_length)` assigns `10` to `integer_length`.
+[match]: match.html
# Unit-like structs
You can define a `struct` with no members at all:
```rust
-struct Electron;
+struct Electron {} // use empty braces...
+struct Proton; // ...or just a semicolon
-let x = Electron;
+// whether you declared the struct with braces or not, do the same when creating one
+let x = Electron {};
+let y = Proton;
```
Such a `struct` is called ‘unit-like’ because it resembles the empty
Cargo will ignore files in subdirectories of the `tests/` directory.
Therefore shared modules in integrations tests are possible.
-For example `tests/common/mod.rs` is not seperatly compiled by cargo but can
+For example `tests/common/mod.rs` is not separately compiled by cargo but can
be imported in every test with `mod common;`
That's all there is to the `tests` directory. The `tests` module isn't needed
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
* 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`
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
import gdb
import re
+import sys
import debugger_pretty_printers_common as rustpp
+# We want a version of `range` which doesn't allocate an intermediate list,
+# specifically it should use a lazy iterator. In Python 2 this was `xrange`, but
+# if we're running with Python 3 then we need to use `range` instead.
+if sys.version_info.major >= 3:
+ xrange = range
+
#===============================================================================
# GDB Pretty Printing Module for Rust
#===============================================================================
("(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
+ for index in xrange(0, length):
+ yield (str(index), (raw_ptr + index).dereference())
class RustStringSlicePrinter:
("(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
+ for index in xrange(0, length):
+ yield (str(index), (gdb_ptr + index).dereference())
class RustStdStringPrinter:
filename = 'rustc-{}-{}.tar.gz'.format(channel, triple)
url = 'https://static.rust-lang.org/dist/{}/{}'.format(date, filename)
dst = dl_dir + '/' + filename
- if os.path.exists(dst):
- os.unlink(dst)
bootstrap.get(url, dst)
stage0_dst = triple + '/stage0'
{
- "platform": "aarch64",
- "intrinsic_prefix": "aarch64_v",
+ "platform": "aarch64_v",
+ "intrinsic_prefix": "",
"llvm_prefix": "llvm.aarch64.neon.",
"number_info": {
"signed": {
{
- "platform": "arm",
- "intrinsic_prefix": "arm_v",
+ "platform": "arm_v",
+ "intrinsic_prefix": "",
"llvm_prefix": "llvm.neon.v",
"number_info": {
"signed": {
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):
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:
def platform(self):
return self._platform
+ def intrinsic_prefix(self):
+ return self._intrinsic_prefix
+
def llvm_prefix(self):
return self._llvm_prefix
*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)
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)
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 '}'
#[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 '''\
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(),
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.avx.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.avx2.",
"intrinsics": [
{
--- /dev/null
+{
+ "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"]
+ }
+ ]
+}
--- /dev/null
+{
+ "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"]
+ }
+ ]
+}
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.fma.",
"intrinsics": [
{
{
"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" }
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.sse.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.sse2.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.sse3.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.sse41.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.sse42.",
"intrinsics": [
{
{
+ "intrinsic_prefix": "_mm",
"llvm_prefix": "llvm.x86.ssse3.",
"intrinsics": [
{
--- /dev/null
+{
+ "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"]
+ }
+ ]
+}
# 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`
/// Basic usage:
///
/// ```
- /// #![feature(binary_heap_append)]
- ///
/// use std::collections::BinaryHeap;
///
/// let v = vec![-10, 1, 2, 3, 3];
/// 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);
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;
}
}
+#[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]
/// # Examples
///
/// ```
- /// #![feature(btree_append)]
/// use std::collections::BTreeMap;
///
/// let mut a = BTreeMap::new();
/// 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 {
/// Basic usage:
///
/// ```
- /// #![feature(btree_split_off)]
/// use std::collections::BTreeMap;
///
/// let mut a = BTreeMap::new();
/// 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>
{
/// # Examples
///
/// ```
- /// #![feature(btree_append)]
/// use std::collections::BTreeSet;
///
/// let mut a = BTreeSet::new();
/// 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);
}
/// Basic usage:
///
/// ```
- /// #![feature(btree_split_off)]
/// use std::collections::BTreeMap;
///
/// let mut a = BTreeMap::new();
/// 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) }
}
#![feature(fmt_internals)]
#![feature(heap_api)]
#![feature(inclusive_range)]
-#![feature(iter_arith)]
#![feature(lang_items)]
#![feature(nonzero)]
#![feature(pattern)]
#![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)]
/// 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()
/// 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()
}
// 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(())
#[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.
// 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,
}
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;
$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 {
#[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
#[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();
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;
}
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;
}
#[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);
}
}
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=()>) {}
///
/// 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()
/// }
/// 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
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;
impl<I: Iterator> Peekable<I> {
/// Returns a reference to the next() value without advancing the iterator.
///
- /// The `peek()` method will return the value that a call to [`next()`] would
- /// return, but does not advance the iterator. Like [`next()`], if there is
- /// a value, it's wrapped in a `Some(T)`, but if the iterator is over, it
- /// will return `None`.
+ /// Like [`next()`], if there is a value, it is wrapped in a `Some(T)`.
+ /// But if the iteration is over, `None` is returned.
///
/// [`next()`]: trait.Iterator.html#tymethod.next
///
- /// Because `peek()` returns reference, and many iterators iterate over
- /// references, this leads to a possibly confusing situation where the
+ /// Because `peek()` returns a reference, and many iterators iterate over
+ /// references, there can be a possibly confusing situation where the
/// return value is a double reference. You can see this effect in the
- /// examples below, with `&&i32`.
+ /// examples below.
///
/// # Examples
///
///
/// assert_eq!(iter.next(), Some(&2));
///
- /// // we can peek() multiple times, the iterator won't advance
+ /// // The iterator does not advance even if we `peek` multiple times
/// assert_eq!(iter.peek(), Some(&&3));
/// assert_eq!(iter.peek(), Some(&&3));
///
/// assert_eq!(iter.next(), Some(&3));
///
- /// // after the iterator is finished, so is peek()
+ /// // After the iterator is finished, so is `peek()`
/// assert_eq!(iter.peek(), None);
/// assert_eq!(iter.next(), None);
/// ```
///
/// let mut iter = xs.iter().peekable();
///
- /// // there are still elements to iterate over
+ /// // There are still elements to iterate over
/// assert_eq!(iter.is_empty(), false);
///
- /// // let's consume the iterator
+ /// // Let's consume the iterator
/// iter.next();
/// iter.next();
/// iter.next();
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;
/// 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 {
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)
+ }
}
)*)
}
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)
+ }
}
)*)
}
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)
+ }
}
)*)
}
}
#[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)
{
#[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]
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) ||
}
} 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)
}
}
};
}
#[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;
#[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 {
#[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)
}
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
}
#[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;
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)
}
}
};
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),
}
}
#[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>
{
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)
}
}
};
#[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 }
#![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)]
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);
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()); }
}
};
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
// (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
}
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;
}
impl RawFloat for f32 {
+ fn zero2() -> Self {
+ 0.0
+ }
+
fn sig_bits() -> u8 {
24
}
}
fn unpack(self) -> Unpacked {
- let (sig, exp, _sig) = self.integer_decode();
+ let (sig, exp, _sig) = self.integer_decode2();
Unpacked::new(sig, exp)
}
impl RawFloat for f64 {
+ fn zero2() -> Self {
+ 0.0
+ }
+
fn sig_bits() -> u8 {
53
}
}
fn unpack(self) -> Unpacked {
- let (sig, exp, _sig) = self.integer_decode();
+ let (sig, exp, _sig) = self.integer_decode2();
Unpacked::new(sig, exp)
}
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.
use num::Float;
use num::FpCategory as Fp;
+/// The radix or base of the internal representation of `f32`.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const RADIX: u32 = 2;
+/// Number of significant digits in base 2.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MANTISSA_DIGITS: u32 = 24;
+/// Approximate number of significant digits in base 10.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const DIGITS: u32 = 6;
+/// Difference between `1.0` and the next largest representable number.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const EPSILON: f32 = 1.19209290e-07_f32;
-/// Smallest finite f32 value
+/// Smallest finite `f32` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN: f32 = -3.40282347e+38_f32;
-/// Smallest positive, normalized f32 value
+/// Smallest positive normal `f32` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32;
-/// Largest finite f32 value
+/// Largest finite `f32` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MAX: f32 = 3.40282347e+38_f32;
+/// One greater than the minimum possible normal power of 2 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN_EXP: i32 = -125;
+/// Maximum possible power of 2 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX_EXP: i32 = 128;
+/// Minimum possible normal power of 10 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN_10_EXP: i32 = -37;
+/// Maximum possible power of 10 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX_10_EXP: i32 = 38;
+/// Not a Number (NaN).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const NAN: f32 = 0.0_f32/0.0_f32;
+/// Infinity (∞).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const INFINITY: f32 = 1.0_f32/0.0_f32;
+/// Negative infinity (-∞).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
/// Basic mathematical constants.
pub mod consts {
// FIXME: replace with mathematical constants from cmath.
- /// Archimedes' constant
+ /// Archimedes' constant (Ï€)
#[stable(feature = "rust1", since = "1.0.0")]
pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
- /// pi/2.0
+ /// π/2
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
- /// pi/3.0
+ /// π/3
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
- /// pi/4.0
+ /// π/4
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
- /// pi/6.0
+ /// π/6
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
- /// pi/8.0
+ /// π/8
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
- /// 1.0/pi
+ /// 1/Ï€
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
- /// 2.0/pi
+ /// 2/Ï€
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
- /// 2.0/sqrt(pi)
+ /// 2/sqrt(Ï€)
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32;
- /// sqrt(2.0)
+ /// sqrt(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32;
- /// 1.0/sqrt(2.0)
+ /// 1/sqrt(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
- /// Euler's number
+ /// Euler's number (e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const E: f32 = 2.71828182845904523536028747135266250_f32;
- /// log2(e)
+ /// log<sub>2</sub>(e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
- /// log10(e)
+ /// log<sub>10</sub>(e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
- /// ln(2.0)
+ /// ln(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32;
- /// ln(10.0)
+ /// ln(10)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
}
/// 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.
#[inline]
fn signum(self) -> f32 {
if self.is_nan() {
- Float::nan()
+ NAN
} else {
unsafe { intrinsics::copysignf32(1.0, self) }
}
/// `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.
use num::FpCategory as Fp;
use num::Float;
+/// The radix or base of the internal representation of `f64`.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const RADIX: u32 = 2;
+/// Number of significant digits in base 2.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MANTISSA_DIGITS: u32 = 53;
+/// Approximate number of significant digits in base 10.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const DIGITS: u32 = 15;
+/// Difference between `1.0` and the next largest representable number.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
-/// Smallest finite f64 value
+/// Smallest finite `f64` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN: f64 = -1.7976931348623157e+308_f64;
-/// Smallest positive, normalized f64 value
+/// Smallest positive normal `f64` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64;
-/// Largest finite f64 value
+/// Largest finite `f64` value.
#[stable(feature = "rust1", since = "1.0.0")]
pub const MAX: f64 = 1.7976931348623157e+308_f64;
+/// One greater than the minimum possible normal power of 2 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN_EXP: i32 = -1021;
+/// Maximum possible power of 2 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX_EXP: i32 = 1024;
+/// Minimum possible normal power of 10 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN_10_EXP: i32 = -307;
+/// Maximum possible power of 10 exponent.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX_10_EXP: i32 = 308;
+/// Not a Number (NaN).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const NAN: f64 = 0.0_f64/0.0_f64;
+/// Infinity (∞).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const INFINITY: f64 = 1.0_f64/0.0_f64;
+/// Negative infinity (-∞).
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
/// Basic mathematical constants.
pub mod consts {
// FIXME: replace with mathematical constants from cmath.
- /// Archimedes' constant
+ /// Archimedes' constant (Ï€)
#[stable(feature = "rust1", since = "1.0.0")]
pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
- /// pi/2.0
+ /// π/2
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
- /// pi/3.0
+ /// π/3
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64;
- /// pi/4.0
+ /// π/4
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
- /// pi/6.0
+ /// π/6
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64;
- /// pi/8.0
+ /// π/8
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64;
- /// 1.0/pi
+ /// 1/Ï€
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
- /// 2.0/pi
+ /// 2/Ï€
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
- /// 2.0/sqrt(pi)
+ /// 2/sqrt(Ï€)
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_2_SQRT_PI: f64 = 1.12837916709551257389615890312154517_f64;
- /// sqrt(2.0)
+ /// sqrt(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const SQRT_2: f64 = 1.41421356237309504880168872420969808_f64;
- /// 1.0/sqrt(2.0)
+ /// 1/sqrt(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64;
- /// Euler's number
+ /// Euler's number (e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const E: f64 = 2.71828182845904523536028747135266250_f64;
- /// log2(e)
+ /// log<sub>2</sub>(e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64;
- /// log10(e)
+ /// log<sub>10</sub>(e)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64;
- /// ln(2.0)
+ /// ln(2)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LN_2: f64 = 0.693147180559945309417232121458176568_f64;
- /// ln(10.0)
+ /// ln(10)
#[stable(feature = "rust1", since = "1.0.0")]
pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64;
}
/// 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.
#[inline]
fn signum(self) -> f64 {
if self.is_nan() {
- Float::nan()
+ NAN
} else {
unsafe { intrinsics::copysignf64(1.0, self) }
}
/// `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.
use prelude::v1::*;
use {f32, f64};
-use num::{Float, FpCategory};
+use num::FpCategory;
+use num::dec2flt::rawfp::RawFloat;
/// Decoded unsigned finite value, such that:
///
}
/// 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;
}
/// 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,
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
macro_rules! int_module { ($T:ident, $bits:expr) => (
+/// The smallest value that can be represented by this integer type.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN: $T = $T::min_value();
+/// The largest value that can be represented by this integer type.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX: $T = $T::max_value();
) }
//! Numeric traits and functions for the built-in numeric types.
#![stable(feature = "rust1", since = "1.0.0")]
-#![allow(missing_docs)]
use char::CharExt;
use cmp::PartialOrd;
#[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;
#[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;
#[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 }
#[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 }
#[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 }
#[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 }
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(),
}
}
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(),
}
}
#[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 {
#[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;
#[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`.
#[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)
}
/// 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.
/// 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
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;
}
macro_rules! uint_module { ($T:ident, $bits:expr) => (
+/// The smallest value that can be represented by this integer type.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MIN: $T = $T::min_value();
+/// The largest value that can be represented by this integer type.
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(missing_docs)]
pub const MAX: $T = $T::max_value();
) }
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'.
/// # 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());
/// # Examples
///
/// ```
-/// #![feature(iter_arith)]
/// fn main() {
/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
/// assert_eq!(2+3+4, (2..).take(3).sum());
/// # 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());
}
}
-#[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
//! }
//!
//! 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)
//! }
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]);
});
}
-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, ],
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);
t += 1;
}
}
-
#[test] #[cfg(target_arch = "arm")]
fn test_hash_usize() {
let val = 0xdeadbeef_deadbeef_u64;
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
#![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)]
// 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 {
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
#[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);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::f64;
use core::num::flt2dec::estimator::*;
#[test]
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);
}
}
})
}
+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
// 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
// 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);
// 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
// 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);
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", ""));
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", ""));
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", ""));
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");
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");
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");
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");
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");
// 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;
}
}
}
/// 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.
ExprVec(HirVec<P<Expr>>),
/// A function call
///
- /// The first field resolves to the function itself,
+ /// The first field resolves to the function itself (usually an `ExprPath`),
/// and the second field is the list of arguments
ExprCall(P<Expr>, HirVec<P<Expr>>),
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
/// The vector of `Ty`s are the ascripted type parameters for the method
/// (within the angle brackets).
///
- /// The first element of the vector of `Expr`s is the expression that evaluates
- /// to the object on which the method is being called on (the receiver),
- /// and the remaining elements are the rest of the arguments.
+ /// The first element of the vector of `Expr`s is the expression that
+ /// evaluates to the object on which the method is being called on (the
+ /// receiver), and the remaining elements are the rest of the arguments.
///
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
/// Inline assembly (from `asm!`), with its outputs and inputs.
ExprInlineAsm(InlineAsm, Vec<P<Expr>>, Vec<P<Expr>>),
- /// A struct literal expression.
+ /// A struct or struct-like variant literal expression.
///
/// For example, `Foo {x: 1, y: 2}`, or
/// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
ExprStruct(Path, HirVec<Field>, Option<P<Expr>>),
- /// A vector literal constructed from one repeated element.
+ /// An array literal constructed from one repeated element.
///
/// For example, `[1; 5]`. The first expression is the element
/// to be repeated; the second is the number of times to repeat it.
pub position: usize,
}
+/// Hints at the original code for a `match _ { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum MatchSource {
+ /// A `match _ { .. }`
Normal,
+ /// An `if let _ = _ { .. }` (optionally with `else { .. }`)
IfLetDesugar {
contains_else_clause: bool,
},
+ /// A `while let _ = _ { .. }` (which was desugared to a
+ /// `loop { match _ { .. } }`)
WhileLetDesugar,
+ /// A desugared `for _ in _ { .. }` loop
ForLoopDesugar,
+ /// A desugared `?` operator
TryDesugar,
}
pub mutbl: Mutability,
}
-/// Represents a method's signature in a trait declaration,
-/// or in an implementation.
+/// Represents a method's signature in a trait declaration or implementation.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct MethodSig {
pub unsafety: Unsafety,
pub span: Span,
}
+/// Represents a trait method or associated constant or type
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TraitItem_ {
+ /// An associated constant with an optional value (otherwise `impl`s
+ /// must contain a value)
ConstTraitItem(P<Ty>, Option<P<Expr>>),
+ /// A method with an optional body
MethodTraitItem(MethodSig, Option<P<Block>>),
+ /// An associated type with (possibly empty) bounds and optional concrete
+ /// type
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
}
+/// Represents anything within an `impl` block
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct ImplItem {
pub id: NodeId,
pub span: Span,
}
+/// Represents different contents within `impl`s
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum ImplItemKind {
+ /// An associated constant of the given type, set to the constant result
+ /// of the expression
Const(P<Ty>, P<Expr>),
+ /// A method implementation with the given signature and body
Method(MethodSig, P<Block>),
+ /// An associated type
Type(P<Ty>),
}
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)?;
}
}
}
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);
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(enumset)]
-#![feature(iter_arith)]
#![feature(libc)]
#![feature(nonzero)]
#![feature(quote)]
// 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[..])
}
}
}
// 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| {
// 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;
}
}
// 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);
// 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;
}
}
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);
}
}
}
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);
}
}
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 {
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)
}
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)));
}
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`");
}
// 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,
// 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);
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?
false
}
}
-
// 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
/// `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 {
// 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);
}
}
#![feature(staged_api)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
-#![feature(iter_arith)]
#![feature(question_mark)]
#![feature(box_patterns)]
#![feature(box_syntax)]
use std::ops::{Index, IndexMut, Range};
use std::fmt;
use std::vec;
+use std::u32;
use rustc_serialize as serialize;
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>,
///
/// 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) => {
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",
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.
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);
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"]
+ }]);
+}
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
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(())
}
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,
}
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,
}
}
}
}
- 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>,
..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,
/// 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]
"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", || {
}
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) {
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
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();
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;
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")
});
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" }
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.
/// 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,
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
}
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)
// 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(
}
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()
}
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| {
}
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];
//! 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};
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};
}
enum PMDSource {
- Registered(Rc<cstore::crate_metadata>),
+ Registered(Rc<cstore::CrateMetadata>),
Owned(MetadataBlob),
}
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) {
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
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()),
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 => {
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) {
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();
}
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);
}
}
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,
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 {
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(|| {
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.
// 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
}
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);
- }
- }
}
}
span: i.span,
direct: true,
path_len: len,
- });
+ },
+ &mut FnvHashSet());
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
}
}
// except according to those terms.
use cstore;
+use common;
use decoder;
use encoder;
use loader;
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
pub use self::MetadataBlob::*;
+use common;
use creader;
use decoder;
use index;
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};
// 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),
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
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,
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>>,
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()
}
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);
/// 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);
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
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();
}
}
-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()) }
}
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
}
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;
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};
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
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) {
};
// 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);
}
}
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) {
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);
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 });
}
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 {
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]);
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| {
}
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());
}
}
-// 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());
// 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,
#[macro_use]
extern crate rustc;
+extern crate rustc_data_structures;
extern crate rustc_back;
extern crate rustc_llvm;
extern crate rustc_const_math;
//! 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;
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,
}
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 `{}`{}",
}
}
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 #{}: {}",
}
}
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();
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);
}
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 => {}
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> {
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 {
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())));
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(_) => {}
}
}
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,
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();
// 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,
})
/// 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);
if !msg.is_empty() {
msg = format!(". Did you mean {}?", msg);
} else {
- // we check if this a module and if so, we display a help
- // message
+ // we display a help message if this is a module
let name_path = path.segments.iter()
.map(|seg| seg.identifier.name)
.collect::<Vec<_>>();
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 {
GlobImport { .. } => "*".to_string(),
}
}
-
-pub fn resolve_imports(resolver: &mut Resolver) {
- let mut import_resolver = ImportResolver { resolver: resolver };
- import_resolver.resolve_imports();
-}
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
+use rustc::hir::map::Node;
use rustc::session::Session;
use rustc::ty::{self, TyCtxt, ImplOrTraitItem, ImplOrTraitItemContainer};
ast::ExprKind::TupField(ref sub_ex, idx) => {
self.visit_expr(&sub_ex);
- let hir_node = self.save_ctxt.tcx.map.expect_expr(sub_ex.id);
+ let hir_node = match self.save_ctxt.tcx.map.find(sub_ex.id) {
+ Some(Node::NodeExpr(expr)) => expr,
+ _ => {
+ debug!("Missing or weird node for sub-expression {} in {:?}",
+ sub_ex.id, ex);
+ return;
+ }
+ };
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
match *ty {
ty::TyStruct(def, _) => {
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
//
// 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.
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));
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)
}
}
})
}
-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)
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()
}
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),
}
}
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);
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();
}
}
--- /dev/null
+// 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,
+ }
+}
//! 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 {
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
// 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
// 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
// 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"),
_ => None,
}
}
+
// MSVC's x86 libraries are not in a subfolder
fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
match arch {
_ => 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
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::*;
}
}
- 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>>,
}
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));
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();
}
})
}
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 {
#![feature(const_fn)]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
-#![feature(iter_arith)]
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
// 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 {
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)
}
}
// 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![]);
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)
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");
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);
});
}
};
//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);
}
}
}
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(
#![feature(box_patterns)]
#![feature(box_syntax)]
-#![feature(iter_arith)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
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 => {}
+ }
}
}
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_,
pub fn is_ty_method(&self) -> bool {
ItemType::from_item(self) == ItemType::TyMethod
}
+ pub fn is_primitive(&self) -> bool {
+ ItemType::from_item(self) == ItemType::Primitive
+ }
pub fn is_stripped(&self) -> bool {
match self.inner { StrippedItem(..) => true, _ => false }
}
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();
trait_: trait_,
for_: self.for_.clean(cx),
items: items,
- derived: detect_derived(&self.attrs),
polarity: Some(self.polarity.clean(cx)),
}),
});
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();
write!(f, ": {}", TyParamBounds(&tp.bounds))?;
}
- match tp.default {
- Some(ref ty) => { write!(f, " = {}", ty)?; },
- None => {}
+ if let Some(ref ty) = tp.default {
+ write!(f, " = {}", ty)?;
};
}
}
}
(_, 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 => {}
///
/// The classifier will call into the `Writer` implementation as it finds spans
/// of text to highlight. Exactly how that text should be highlighted is up to
-/// the implemention.
+/// the implementation.
pub trait Writer {
/// Called when we start processing a span of text that should be highlighted.
/// The `Class` argument specifies how it should be highlighted.
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(""))
}
"methods",
"deref-methods",
"implementations",
- "derived_implementations"
].into_iter().map(|id| (String::from(*id), 1)).collect()
}
// 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),
+ });
}
}
*slot.borrow_mut() = cx.current.clone();
});
- let mut title = cx.current.join("::");
+ let mut title = if it.is_primitive() {
+ // No need to include the namespace for primitive types
+ String::new()
+ } else {
+ cx.current.join("::")
+ };
if pushname {
if !title.is_empty() {
title.push_str("::");
clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
_ => {}
}
- let is_primitive = match self.item.inner {
- clean::PrimitiveItem(..) => true,
- _ => false,
- };
- if !is_primitive {
+ if !self.item.is_primitive() {
let cur = &self.cx.current;
let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
for (i, component) in cur.iter().enumerate().take(amt) {
// [src] link in the downstream documentation will actually come back to
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
- if self.cx.shared.include_sources && !is_primitive {
+ if self.cx.shared.include_sources && !self.item.is_primitive() {
if let Some(l) = self.href() {
write!(fmt, "<a id='src-{}' class='srclink' \
href='{}' title='{}'>[src]</a>",
<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
}
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(())
}
let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
// the sidebar is designed to display sibling functions, modules and
- // other miscellaneous informations. since there are lots of sibling
+ // other miscellaneous information. since there are lots of sibling
// items (and that causes quadratic growth in large modules),
// we refactor common parts into a shared JavaScript file per module.
// still, we don't move everything into JS because we want to preserve
right: 5px;
}
-.methods .section-header {
- /* Override parent class attributes. */
- border-bottom: none !important;
- font-size: 1.1em !important;
- margin: 0 0 -5px;
- padding: 0;
-}
-
.section-header:hover a:after {
content: '\2002\00a7\2002';
}
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);
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) => {
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(()),
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};
#[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()
}
}
#![feature(reflect_marker)]
#![feature(rustc_attrs)]
#![feature(shared)]
+#![feature(sip_hash_13)]
#![feature(slice_bytes)]
#![feature(slice_concat_ext)]
#![feature(slice_patterns)]
text[..offset].iter().rposition(|elt| *elt == x)
}
- // test fallback implementations on all plattforms
+ // test fallback implementations on all platforms
#[test]
fn matches_one() {
assert_eq!(Some(0), memchr(b'a', b"a"));
/// 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
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())
}
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.
/// 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
///
/// # 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(())
/// # }
}
#[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;
}
#[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
}
/// [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)
}
#[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) }
#[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 {
#[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) }
}
#[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));
}
#[test]
+ #[allow(deprecated)]
fn test_ldexp() {
let f1 = 2.0f32.powi(-123);
let f2 = 2.0f32.powi(-111);
}
#[test]
+ #[allow(deprecated)]
fn test_frexp() {
let f1 = 2.0f32.powi(-123);
let f2 = 2.0f32.powi(-111);
}
#[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;
/// [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.
#[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) }
#[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 {
#[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) }
}
#[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));
}
#[test]
+ #[allow(deprecated)]
fn test_ldexp() {
let f1 = 2.0f64.powi(-123);
let f2 = 2.0f64.powi(-111);
}
#[test]
+ #[allow(deprecated)]
fn test_frexp() {
let f1 = 2.0f64.powi(-123);
let f2 = 2.0f64.powi(-111);
}
#[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+ #[allow(deprecated)]
fn test_frexp_nowin() {
let inf: f64 = INFINITY;
let neg_inf: f64 = NEG_INFINITY;
#![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};
#[cfg(test)]
mod tests {
- use super::*;
use u8;
use u16;
use u32;
#[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);
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);
/// `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
///
}
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,
+ }
+ }
}
}
}
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;
}
}
-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)
}
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()) {
use ffi::{OsStr, OsString};
use io::{self, ErrorKind};
-use num::Zero;
use os::windows::ffi::{OsStrExt, OsStringExt};
use path::PathBuf;
use time::Duration;
}
}
-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)
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;
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)
/// 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())
}
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| {
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 {
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
}
}
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(..) => {
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
}
};
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
}
"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
}
}
})
}
(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
}
"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
}
}
if let Ok(issue) = issue.parse() {
issue
} else {
- diagnostic.span_err(attr.span(), "incorrect 'issue'");
+ span_err!(diagnostic, attr.span(), E0545,
+ "incorrect 'issue'");
continue
}
}
})
}
(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
}
"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
}
}
})
}
(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
}
}
_ => unreachable!()
}
} else {
- diagnostic.span_err(attr.span(), "incorrect stability attribute type");
+ span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
continue
}
}
}
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");
}
}
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
}
};
"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
}
}
if !set.insert(name.clone()) {
panic!(diagnostic.span_fatal(meta.span,
- &format!("duplicate meta item `{}`", name)));
+ &format!("duplicate meta item `{}`", name)));
}
}
}
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
}
}
}
}
// Not a word:
- _ => diagnostic.span_err(item.span, "unrecognized enum representation hint")
+ _ => span_err!(diagnostic, item.span, E0553,
+ "unrecognized enum representation hint"),
}
}
}
if self.in_cfg(node.attrs()) { Some(node) } else { None }
}
- fn process_cfg_attrs<T: HasAttrs>(&mut self, node: T) -> T {
+ pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: T) -> T {
node.map_attrs(|attrs| {
attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
})
--- /dev/null
+// 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
+}
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
},
});
- let marked_tts = mark_tts(tts, mark);
+ let marked_tts = mark_tts(&tts, mark);
Some(expandfun.expand(fld.cx, call_site, &marked_tts))
}
}
});
- let marked_tts = mark_tts(tts, mark);
+ let marked_tts = mark_tts(&tts, mark);
Some(expander.expand(fld.cx, call_site, ident, marked_tts))
}
};
fld.cx.bt_pop();
- modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
+ let configured = modified.into_iter().flat_map(|it| {
+ it.fold_with(&mut fld.strip_unconfigured())
+ }).collect::<SmallVector<_>>();
+
+ configured.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
}
}
}
Spanned {
node: Mac_ {
path: self.fold_path(node.path),
- tts: self.fold_tts(node.tts),
+ tts: self.fold_tts(&node.tts),
},
span: self.new_span(span),
}
}
// apply a given mark to the given token trees. Used prior to expansion of a macro.
-fn mark_tts(tts: Vec<TokenTree>, m: Mrk) -> Vec<TokenTree> {
+fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None})
}
use ext::base::ExtCtxt;
use parse::{self, token, classify};
use ptr::P;
+ use std::rc::Rc;
use tokenstream::{self, TokenTree};
if self.node.style == ast::AttrStyle::Inner {
r.push(TokenTree::Token(self.span, token::Not));
}
- r.push(TokenTree::Delimited(self.span, tokenstream::Delimited {
+ r.push(TokenTree::Delimited(self.span, Rc::new(tokenstream::Delimited {
delim: token::Bracket,
open_span: self.span,
tts: self.node.value.to_tokens(cx),
close_span: self.span,
- }));
+ })));
r
}
}
impl ToTokens for () {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![TokenTree::Delimited(DUMMY_SP, tokenstream::Delimited {
+ vec![TokenTree::Delimited(DUMMY_SP, Rc::new(tokenstream::Delimited {
delim: token::Paren,
open_span: DUMMY_SP,
tts: vec![],
close_span: DUMMY_SP,
- })]
+ }))]
}
}
id_ext("tokenstream"),
id_ext("SequenceRepetition")];
let e_seq_struct = cx.expr_struct(sp, cx.path_global(sp, seq_path), fields);
+ let e_rc_new = cx.expr_call_global(sp, vec![id_ext("std"),
+ id_ext("rc"),
+ id_ext("Rc"),
+ id_ext("new")],
+ vec![e_seq_struct]);
let e_tok = cx.expr_call(sp,
mk_tt_path(cx, sp, "Sequence"),
- vec!(e_sp, e_seq_struct));
+ vec!(e_sp, e_rc_new));
let e_push =
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("tt")),
use std::cell::RefCell;
use std::collections::{HashMap};
use std::collections::hash_map::{Entry};
+use std::rc::Rc;
struct ParserAnyMacro<'a> {
parser: RefCell<Parser<'a>>,
let match_lhs_tok = MatchNt(lhs_nm, token::str_to_ident("tt"));
let match_rhs_tok = MatchNt(rhs_nm, token::str_to_ident("tt"));
let argument_gram = vec![
- TokenTree::Sequence(DUMMY_SP, tokenstream::SequenceRepetition {
+ TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: vec![
TokenTree::Token(DUMMY_SP, match_lhs_tok),
TokenTree::Token(DUMMY_SP, token::FatArrow),
separator: Some(token::Semi),
op: tokenstream::KleeneOp::OneOrMore,
num_captures: 2,
- }),
+ })),
// to phase into semicolon-termination instead of semicolon-separation
- TokenTree::Sequence(DUMMY_SP, tokenstream::SequenceRepetition {
+ TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: vec![TokenTree::Token(DUMMY_SP, token::Semi)],
separator: None,
op: tokenstream::KleeneOp::ZeroOrMore,
num_captures: 0
- }),
+ })),
];
// Parse the macro_rules! invocation (`none` is for no interpolations):
let mut r = TtReader {
sp_diag: sp_diag,
stack: vec!(TtFrame {
- forest: TokenTree::Sequence(DUMMY_SP, tokenstream::SequenceRepetition {
+ forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: src,
// doesn't matter. This merely holds the root unzipping.
separator: None, op: tokenstream::KleeneOp::ZeroOrMore, num_captures: 0
- }),
+ })),
idx: 0,
dotdotdoted: false,
sep: None,
} 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;
}
}
}
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
}
};
}
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) {
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);
}
}
}
use util::small_vector::SmallVector;
use util::move_map::MoveMap;
+use std::rc::Rc;
+
pub trait Folder : Sized {
// Any additions to this trait should happen in form
// of a call to a public `noop_*` function that only calls
noop_fold_ty_params(tps, self)
}
- fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
+ fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree {
noop_fold_tt(tt, self)
}
- fn fold_tts(&mut self, tts: Vec<TokenTree>) -> Vec<TokenTree> {
+ fn fold_tts(&mut self, tts: &[TokenTree]) -> Vec<TokenTree> {
noop_fold_tts(tts, self)
}
Spanned {
node: Mac_ {
path: fld.fold_path(node.path),
- tts: fld.fold_tts(node.tts),
+ tts: fld.fold_tts(&node.tts),
},
span: fld.new_span(span)
}
}
}
-pub fn noop_fold_tt<T: Folder>(tt: TokenTree, fld: &mut T) -> TokenTree {
- match tt {
+pub fn noop_fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree {
+ match *tt {
TokenTree::Token(span, ref tok) =>
TokenTree::Token(span, fld.fold_token(tok.clone())),
- TokenTree::Delimited(span, delimed) => TokenTree::Delimited(span, Delimited {
- delim: delimed.delim,
- open_span: delimed.open_span,
- tts: fld.fold_tts(delimed.tts),
- close_span: delimed.close_span,
- }),
- TokenTree::Sequence(span, seq) => TokenTree::Sequence(span, SequenceRepetition {
- tts: fld.fold_tts(seq.tts),
- separator: seq.separator.clone().map(|tok| fld.fold_token(tok)),
- ..seq
- }),
+ TokenTree::Delimited(span, ref delimed) => {
+ TokenTree::Delimited(span, Rc::new(
+ Delimited {
+ delim: delimed.delim,
+ open_span: delimed.open_span,
+ tts: fld.fold_tts(&delimed.tts),
+ close_span: delimed.close_span,
+ }
+ ))
+ },
+ TokenTree::Sequence(span, ref seq) =>
+ TokenTree::Sequence(span,
+ Rc::new(SequenceRepetition {
+ tts: fld.fold_tts(&seq.tts),
+ separator: seq.separator.clone().map(|tok| fld.fold_token(tok)),
+ ..**seq
+ })),
}
}
-pub fn noop_fold_tts<T: Folder>(tts: Vec<TokenTree>, fld: &mut T) -> Vec<TokenTree> {
- tts.move_map(|tt| fld.fold_tt(tt))
+pub fn noop_fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
+ tts.iter().map(|tt| fld.fold_tt(tt)).collect()
}
// apply ident folder if it's an ident, apply other folds to interpolated nodes
token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), ..*id})),
token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
- token::NtTT(tt) => token::NtTT(tt.map(|tt| fld.fold_tt(tt))),
+ token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))),
token::NtArm(arm) => token::NtArm(fld.fold_arm(arm)),
token::NtImplItem(arm) =>
token::NtImplItem(arm.map(|arm| fld.fold_impl_item(arm)
#![feature(str_escape)]
#![feature(unicode)]
#![feature(question_mark)]
+#![feature(rustc_diagnostic_macros)]
extern crate serialize;
extern crate term;
})
}
+#[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;
pub use self::thin_vec::ThinVec;
}
-pub mod diagnostics {
- pub mod macros;
- pub mod plugin;
- pub mod metadata;
-}
-
pub mod json;
pub mod syntax {
pub mod macro_rules;
}
}
+
+// __build_diagnostic_array! { libsyntax, DIAGNOSTICS }
_ => 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;
/// 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('/') {
#[cfg(test)]
mod tests {
use super::*;
+ use std::rc::Rc;
use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION};
use codemap::Spanned;
use ast::{self, PatKind};
)
if first_delimed.delim == token::Paren
&& ident.name.as_str() == "a" => {},
- _ => panic!("value 3: {:?}", *first_delimed),
+ _ => panic!("value 3: {:?}", **first_delimed),
}
let tts = &second_delimed.tts[..];
match (tts.len(), tts.get(0), tts.get(1)) {
)
if second_delimed.delim == token::Paren
&& ident.name.as_str() == "a" => {},
- _ => panic!("value 4: {:?}", *second_delimed),
+ _ => panic!("value 4: {:?}", **second_delimed),
}
},
- _ => panic!("value 2: {:?}", *macro_delimed),
+ _ => panic!("value 2: {:?}", **macro_delimed),
}
},
_ => panic!("value: {:?}",tts),
TokenTree::Token(sp(3, 4), token::Ident(str_to_ident("a"))),
TokenTree::Delimited(
sp(5, 14),
- tokenstream::Delimited {
+ Rc::new(tokenstream::Delimited {
delim: token::DelimToken::Paren,
open_span: sp(5, 6),
tts: vec![
TokenTree::Token(sp(10, 13), token::Ident(str_to_ident("i32"))),
],
close_span: sp(13, 14),
- }),
+ })),
TokenTree::Delimited(
sp(15, 21),
- tokenstream::Delimited {
+ Rc::new(tokenstream::Delimited {
delim: token::DelimToken::Brace,
open_span: sp(15, 16),
tts: vec![
TokenTree::Token(sp(18, 19), token::Semi),
],
close_span: sp(20, 21),
- })
+ }))
];
assert_eq!(tts, expected);
)?;
let (sep, repeat) = self.parse_sep_and_kleene_op()?;
let name_num = macro_parser::count_names(&seq);
- return Ok(TokenTree::Sequence(mk_sp(sp.lo, seq_span.hi), SequenceRepetition {
- tts: seq,
- separator: sep,
- op: repeat,
- num_captures: name_num
- }));
+ return Ok(TokenTree::Sequence(mk_sp(sp.lo, seq_span.hi),
+ Rc::new(SequenceRepetition {
+ tts: seq,
+ separator: sep,
+ op: repeat,
+ num_captures: name_num
+ })));
} else if self.token.is_keyword(keywords::Crate) {
self.bump();
return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar)));
}
};
- 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();
_ => {}
}
- Ok(TokenTree::Delimited(span, Delimited {
+ Ok(TokenTree::Delimited(span, Rc::new(Delimited {
delim: delim,
open_span: open_span,
tts: tts,
close_span: close_span,
- }))
+ })))
},
_ => {
// invariants: the current token is not a left-delimiter,
/// Parse a `mod <foo> { ... }` or `mod <foo>;` item
fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
+ let outer_attrs = ::config::StripUnconfigured {
+ config: &self.cfg,
+ sess: self.sess,
+ should_test: false, // irrelevant
+ features: None, // don't perform gated feature checking
+ }.process_cfg_attrs(outer_attrs.to_owned());
+
let id_span = self.span;
let id = self.parse_ident()?;
if self.check(&token::Semi) {
self.bump();
// This mod is in an external file. Let's go get it!
- let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span)?;
+ let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?;
Ok((id, m, Some(attrs)))
} else {
- self.push_mod_path(id, outer_attrs);
+ self.push_mod_path(id, &outer_attrs);
self.expect(&token::OpenDelim(token::Brace))?;
let mod_inner_lo = self.span.lo;
let attrs = self.parse_inner_attributes()?;
}
_ => 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;
_ => {}
}
- 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));
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, ">"));
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, "*"),
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(())
}
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];
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));
use parse::lexer;
use parse::token;
+use std::rc::Rc;
+
/// A delimited sequence of token trees
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
/// A single token
Token(Span, token::Token),
/// A delimited sequence of token trees
- Delimited(Span, Delimited),
+ Delimited(Span, Rc<Delimited>),
// This only makes sense in MBE macros.
/// A kleene-style repetition sequence with a span
// FIXME(eddyb) #12938 Use DST.
- Sequence(Span, SequenceRepetition),
+ Sequence(Span, Rc<SequenceRepetition>),
}
impl TokenTree {
Some(*cnt)
}).max().unwrap_or(0);
- TokenTree::Delimited(sp, Delimited {
+ TokenTree::Delimited(sp, Rc::new(Delimited {
delim: token::Bracket,
open_span: sp,
tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"))),
TokenTree::Token(sp, token::Literal(
token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
close_span: sp,
- })
+ }))
}
(&TokenTree::Delimited(_, ref delimed), _) => {
if index == 0 {
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 => {}
}
}
_ => {}
}
};
- 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[..]) {
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);
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
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();
"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",
--- /dev/null
+// 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.
+
+#[cfg_attr(all(), path = "nonexistent_file.rs")] mod foo;
+//~^ ERROR nonexistent_file.rs
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:
--- /dev/null
+// 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);
+}
fn main() {
static foo: Fn() -> u32 = || -> u32 {
//~^ ERROR: mismatched types
+ //~| ERROR: `std::ops::Fn() -> u32 + 'static: std::marker::Sized` is not satisfied
+
0
};
}
// 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];
#![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() { }
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:
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:
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:
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:
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:
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:
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:
--- /dev/null
+// 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() { () }
--- /dev/null
+// 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() { () }
// 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 ==================================================================================
MUT_VECT_SLICE = VECT_SLICE;
}
+ let mut_slice: &mut [i64] = &mut [1, 2, 3, 4, 5];
+
zzz(); // #break
}
--- /dev/null
+// 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() { }
// 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() { }
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();
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) test.rs
+ $(call RUN,test $(RUSTC))
--- /dev/null
+// 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);
+ }
+}
# 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)
..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone()
})),
Annotatable::Item(quote_item!(cx, enum Foo3 { Bar }).unwrap()),
+ Annotatable::Item(quote_item!(cx, #[cfg(any())] fn foo2() {}).unwrap()),
],
Annotatable::ImplItem(it) => vec![
quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| {
#[derive(PartialEq, Clone, Debug)]
fn foo() -> AnotherFakeTypeThatHadBetterGoAway {}
+// Check that the `#[into_multi_foo]`-generated `foo2` is configured away
+fn foo2() {}
+
trait Qux {
#[into_multi_foo]
fn bar();
--- /dev/null
+// 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>;
+}
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");
--- /dev/null
+// 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.
+
+#![crate_name = "foo"]
+
+// @has foo/primitive.u8.html '//head/title' 'u8 - Rust'
+// @!has - '//head/title' 'foo'
+#[doc(primitive = "u8")]
+/// `u8` docs
+mod u8 {}
// 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 =
.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] {
.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!();
}
}
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);
// 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
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!(),
#![deny(warnings)]
-#![feature(iter_arith)]
#![feature(rustc_private)]
#![feature(rustdoc)]
#![feature(question_mark)]