Merge pull request #28 from rust-lang/master
Sync to rust-lang/rust master
This commit is contained in:
commit
27532330e9
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -43,7 +43,7 @@
|
||||
[submodule "src/llvm-project"]
|
||||
path = src/llvm-project
|
||||
url = https://github.com/rust-lang/llvm-project.git
|
||||
branch = rustc/9.0-2019-07-12
|
||||
branch = rustc/9.0-2019-09-19
|
||||
[submodule "src/doc/embedded-book"]
|
||||
path = src/doc/embedded-book
|
||||
url = https://github.com/rust-embedded/book.git
|
||||
|
23
.mailmap
23
.mailmap
@ -117,6 +117,9 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com>
|
||||
Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com>
|
||||
Jay True <glacjay@gmail.com>
|
||||
Jeremy Letang <letang.jeremy@gmail.com>
|
||||
Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com>
|
||||
Jeremy Stucki <dev@jeremystucki.ch> <jeremy@myelin.ch>
|
||||
Jeremy Stucki <dev@jeremystucki.ch>
|
||||
Jethro Beekman <github@jbeekman.nl>
|
||||
Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
|
||||
Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>
|
||||
@ -181,12 +184,20 @@ Neil Pankey <npankey@gmail.com> <neil@wire.im>
|
||||
Nick Platt <platt.nicholas@gmail.com>
|
||||
Nicole Mazzuca <npmazzuca@gmail.com>
|
||||
Nif Ward <nif.ward@gmail.com>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> oli-obk <github6541940@oli-obk.de>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> Oliver 'ker' Schneider <rust19446194516@oli-obk.de>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam9815368754983@oli-obk.de>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github333195615777966@oli-obk.de>
|
||||
Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github6541940@oli-obk.de>
|
||||
Oliver Middleton <olliemail27@gmail.com> <ollie27@users.noreply.github.com>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git-spam-no-reply9815368754983@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git-spam9815368754983@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <github333195615777966@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <github6541940@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <rust19446194516@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git-no-reply-9879165716479413131@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git1984941651981@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <github35764891676564198441@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <github6541940@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <oli-obk@users.noreply.github.com>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <public.oliver.schneider@kit.edu>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <obk8176014uqher834@olio-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu>
|
||||
Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.com>
|
||||
Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
|
||||
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
|
||||
|
794
Cargo.lock
794
Cargo.lock
File diff suppressed because it is too large
Load Diff
@ -68,6 +68,7 @@ rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
|
||||
# here
|
||||
rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
|
||||
rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' }
|
||||
rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' }
|
||||
|
||||
[patch."https://github.com/rust-lang/rust-clippy"]
|
||||
clippy_lints = { path = "src/tools/clippy/clippy_lints" }
|
||||
|
16
README.md
16
README.md
@ -26,12 +26,13 @@ or reading the [rustc guide][rustcguidebuild].
|
||||
### Building on *nix
|
||||
1. Make sure you have installed the dependencies:
|
||||
|
||||
* `g++` 4.7 or later or `clang++` 3.x or later
|
||||
* `g++` 5.1 or later or `clang++` 3.5 or later
|
||||
* `python` 2.7 (but not 3.x)
|
||||
* GNU `make` 3.81 or later
|
||||
* `cmake` 3.4.3 or later
|
||||
* `curl`
|
||||
* `git`
|
||||
* `ssl` which comes in `libssl-dev` or `openssl-devel`
|
||||
|
||||
2. Clone the [source] with `git`:
|
||||
|
||||
@ -56,6 +57,8 @@ or reading the [rustc guide][rustcguidebuild].
|
||||
an installation (using `./x.py install`) that you set the `prefix` value
|
||||
in the `[install]` section to a directory that you have write permissions.
|
||||
|
||||
Create install directory if you are not installing in default directory
|
||||
|
||||
4. Build and install:
|
||||
|
||||
```sh
|
||||
@ -148,6 +151,17 @@ by manually calling the appropriate vcvars file before running the bootstrap.
|
||||
> python x.py build
|
||||
```
|
||||
|
||||
### Building rustc with older host toolchains
|
||||
It is still possible to build Rust with the older toolchain versions listed below, but only if the
|
||||
LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN option is set to true in the config.toml file.
|
||||
|
||||
* Clang 3.1
|
||||
* Apple Clang 3.1
|
||||
* GCC 4.8
|
||||
* Visual Studio 2015 (Update 3)
|
||||
|
||||
Toolchain versions older than what is listed above cannot be used to build rustc.
|
||||
|
||||
#### Specifying an ABI
|
||||
|
||||
Each specific ABI can also be used from either environment (for example, using
|
||||
|
114
RELEASES.md
114
RELEASES.md
@ -1,3 +1,117 @@
|
||||
Version 1.38.0 (2019-09-26)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
- [The `#[global_allocator]` attribute can now be used in submodules.][62735]
|
||||
- [The `#[deprecated]` attribute can now be used on macros.][62042]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Added pipelined compilation support to `rustc`.][62766] This will
|
||||
improve compilation times in some cases. For further information please refer
|
||||
to the [_"Evaluating pipelined rustc compilation"_][pipeline-internals] thread.
|
||||
- [Added tier 3\* support for the `aarch64-uwp-windows-msvc`, `i686-uwp-windows-gnu`,
|
||||
`i686-uwp-windows-msvc`, `x86_64-uwp-windows-gnu`, and
|
||||
`x86_64-uwp-windows-msvc` targets.][60260]
|
||||
- [Added tier 3 support for the `armv7-unknown-linux-gnueabi` and
|
||||
`armv7-unknown-linux-musleabi` targets.][63107]
|
||||
- [Added tier 3 support for the `hexagon-unknown-linux-musl` target.][62814]
|
||||
- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784]
|
||||
|
||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
||||
information on Rust's tiered platform support.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [`ascii::EscapeDefault` now implements `Clone` and `Display`.][63421]
|
||||
- [Derive macros for prelude traits (e.g. `Clone`, `Debug`, `Hash`) are now
|
||||
available at the same path as the trait.][63056] (e.g. The `Clone` derive macro
|
||||
is available at `std::clone::Clone`). This also makes all built-in macros
|
||||
available in `std`/`core` root. e.g. `std::include_bytes!`.
|
||||
- [`str::Chars` now implements `Debug`.][63000]
|
||||
- [`slice::{concat, connect, join}` now accepts `&[T]` in addition to `&T`.][62528]
|
||||
- [`*const T` and `*mut T` now implement `marker::Unpin`.][62583]
|
||||
- [`Arc<[T]>` and `Rc<[T]>` now implement `FromIterator<T>`.][61953]
|
||||
- [Added euclidean remainder and division operations (`div_euclid`,
|
||||
`rem_euclid`) to all numeric primitives.][61884] Additionally `checked`,
|
||||
`overflowing`, and `wrapping` versions are available for all
|
||||
integer primitives.
|
||||
- [`thread::AccessError` now implements `Clone`, `Copy`, `Eq`, `Error`, and
|
||||
`PartialEq`.][61491]
|
||||
- [`iter::{StepBy, Peekable, Take}` now implement `DoubleEndedIterator`.][61457]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
- [`<*const T>::cast`]
|
||||
- [`<*mut T>::cast`]
|
||||
- [`Duration::as_secs_f32`]
|
||||
- [`Duration::as_secs_f64`]
|
||||
- [`Duration::div_duration_f32`]
|
||||
- [`Duration::div_duration_f64`]
|
||||
- [`Duration::div_f32`]
|
||||
- [`Duration::div_f64`]
|
||||
- [`Duration::from_secs_f32`]
|
||||
- [`Duration::from_secs_f64`]
|
||||
- [`Duration::mul_f32`]
|
||||
- [`Duration::mul_f64`]
|
||||
- [`any::type_name`]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Added pipelined compilation support to `cargo`.][cargo/7143]
|
||||
- [You can now pass the `--features` option multiple times to enable
|
||||
multiple features.][cargo/7084]
|
||||
|
||||
Misc
|
||||
----
|
||||
- [`rustc` will now warn about some incorrect uses of
|
||||
`mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346]
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785]
|
||||
with rustc 1.39.0.
|
||||
- The [`armv7-unknown-linux-gnueabihf` platform is also known to have
|
||||
issues][62896] for certain crates such as libc.
|
||||
|
||||
[60260]: https://github.com/rust-lang/rust/pull/60260/
|
||||
[61457]: https://github.com/rust-lang/rust/pull/61457/
|
||||
[61491]: https://github.com/rust-lang/rust/pull/61491/
|
||||
[61884]: https://github.com/rust-lang/rust/pull/61884/
|
||||
[61953]: https://github.com/rust-lang/rust/pull/61953/
|
||||
[62042]: https://github.com/rust-lang/rust/pull/62042/
|
||||
[62528]: https://github.com/rust-lang/rust/pull/62528/
|
||||
[62583]: https://github.com/rust-lang/rust/pull/62583/
|
||||
[62735]: https://github.com/rust-lang/rust/pull/62735/
|
||||
[62766]: https://github.com/rust-lang/rust/pull/62766/
|
||||
[62784]: https://github.com/rust-lang/rust/pull/62784/
|
||||
[62785]: https://github.com/rust-lang/rust/issues/62785/
|
||||
[62814]: https://github.com/rust-lang/rust/pull/62814/
|
||||
[62896]: https://github.com/rust-lang/rust/issues/62896/
|
||||
[63000]: https://github.com/rust-lang/rust/pull/63000/
|
||||
[63056]: https://github.com/rust-lang/rust/pull/63056/
|
||||
[63107]: https://github.com/rust-lang/rust/pull/63107/
|
||||
[63346]: https://github.com/rust-lang/rust/pull/63346/
|
||||
[63421]: https://github.com/rust-lang/rust/pull/63421/
|
||||
[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/
|
||||
[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/
|
||||
[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
||||
[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
||||
[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32
|
||||
[`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64
|
||||
[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32
|
||||
[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64
|
||||
[`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32
|
||||
[`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64
|
||||
[`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32
|
||||
[`Duration::from_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f64
|
||||
[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32
|
||||
[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64
|
||||
[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
|
||||
[forge-platform-support]: https://forge.rust-lang.org/platform-support.html
|
||||
[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199
|
||||
|
||||
Version 1.37.0 (2019-08-15)
|
||||
==========================
|
||||
|
||||
|
@ -184,7 +184,7 @@
|
||||
# default.
|
||||
#extended = false
|
||||
|
||||
# Installs chosen set of extended tools if enables. By default builds all.
|
||||
# Installs chosen set of extended tools if enabled. By default builds all.
|
||||
# If chosen tool failed to build the installation fails.
|
||||
#tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"]
|
||||
|
||||
@ -382,11 +382,6 @@
|
||||
# This is the name of the directory in which codegen backends will get installed
|
||||
#codegen-backends-dir = "codegen-backends"
|
||||
|
||||
# Flag indicating whether `libstd` calls an imported function to handle basic IO
|
||||
# when targeting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
|
||||
# target, as without this option the test output will not be captured.
|
||||
#wasm-syscall = false
|
||||
|
||||
# Indicates whether LLD will be compiled and made available in the sysroot for
|
||||
# rustc to execute.
|
||||
#lld = false
|
||||
|
@ -44,7 +44,7 @@ cc = "1.0.35"
|
||||
libc = "0.2"
|
||||
serde = { version = "1.0.8", features = ["derive"] }
|
||||
serde_json = "1.0.2"
|
||||
toml = "0.4"
|
||||
toml = "0.5"
|
||||
lazy_static = "1.3.0"
|
||||
time = "0.1"
|
||||
petgraph = "0.4.13"
|
||||
|
@ -5,9 +5,6 @@
|
||||
//! parent directory, and otherwise documentation can be found throughout the `build`
|
||||
//! directory in each respective module.
|
||||
|
||||
// NO-RUSTC-WRAPPER
|
||||
#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
use std::env;
|
||||
|
||||
use bootstrap::{Config, Build};
|
||||
|
@ -15,9 +15,6 @@
|
||||
//! switching compilers for the bootstrap and for build scripts will probably
|
||||
//! never get replaced.
|
||||
|
||||
// NO-RUSTC-WRAPPER
|
||||
#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
@ -122,16 +119,18 @@ fn main() {
|
||||
cmd.arg(format!("-Cdebuginfo={}", debuginfo_level));
|
||||
}
|
||||
|
||||
if env::var_os("RUSTC_DENY_WARNINGS").is_some() &&
|
||||
env::var_os("RUSTC_EXTERNAL_TOOL").is_none() {
|
||||
// When extending this list, search for `NO-RUSTC-WRAPPER` and add the new lints
|
||||
// there as well, some code doesn't go through this `rustc` wrapper.
|
||||
cmd.arg("-Dwarnings");
|
||||
cmd.arg("-Drust_2018_idioms");
|
||||
cmd.arg("-Dunused_lifetimes");
|
||||
if env::var_os("RUSTC_EXTERNAL_TOOL").is_none() {
|
||||
// When extending this list, add the new lints to the RUSTFLAGS of the
|
||||
// build_bootstrap function of src/bootstrap/bootstrap.py as well as
|
||||
// some code doesn't go through this `rustc` wrapper.
|
||||
cmd.arg("-Wrust_2018_idioms");
|
||||
cmd.arg("-Wunused_lifetimes");
|
||||
if use_internal_lints(crate_name) {
|
||||
cmd.arg("-Zunstable-options");
|
||||
cmd.arg("-Drustc::internal");
|
||||
cmd.arg("-Wrustc::internal");
|
||||
}
|
||||
if env::var_os("RUSTC_DENY_WARNINGS").is_some() {
|
||||
cmd.arg("-Dwarnings");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,10 @@
|
||||
//!
|
||||
//! See comments in `src/bootstrap/rustc.rs` for more information.
|
||||
|
||||
// NO-RUSTC-WRAPPER
|
||||
#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::path::PathBuf;
|
||||
use std::ffi::OsString;
|
||||
|
||||
fn main() {
|
||||
let args = env::args_os().skip(1).collect::<Vec<_>>();
|
||||
@ -47,7 +45,9 @@ fn main() {
|
||||
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
||||
}
|
||||
if let Some(linker) = env::var_os("RUSTC_TARGET_LINKER") {
|
||||
cmd.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
|
||||
let mut arg = OsString::from("-Clinker=");
|
||||
arg.push(&linker);
|
||||
cmd.arg(arg);
|
||||
}
|
||||
|
||||
// Bootstrap's Cargo-command builder sets this variable to the current Rust version; let's pick
|
||||
|
@ -320,7 +320,7 @@ class RustBuild(object):
|
||||
def __init__(self):
|
||||
self.cargo_channel = ''
|
||||
self.date = ''
|
||||
self._download_url = 'https://static.rust-lang.org'
|
||||
self._download_url = ''
|
||||
self.rustc_channel = ''
|
||||
self.build = ''
|
||||
self.build_dir = os.path.join(os.getcwd(), "build")
|
||||
@ -523,6 +523,10 @@ class RustBuild(object):
|
||||
'value2'
|
||||
>>> rb.get_toml('key', 'c') is None
|
||||
True
|
||||
|
||||
>>> rb.config_toml = 'key1 = true'
|
||||
>>> rb.get_toml("key1")
|
||||
'true'
|
||||
"""
|
||||
|
||||
cur_section = None
|
||||
@ -571,6 +575,12 @@ class RustBuild(object):
|
||||
|
||||
>>> RustBuild.get_string(' "devel" ')
|
||||
'devel'
|
||||
>>> RustBuild.get_string(" 'devel' ")
|
||||
'devel'
|
||||
>>> RustBuild.get_string('devel') is None
|
||||
True
|
||||
>>> RustBuild.get_string(' "devel ')
|
||||
''
|
||||
"""
|
||||
start = line.find('"')
|
||||
if start != -1:
|
||||
@ -631,6 +641,9 @@ class RustBuild(object):
|
||||
target_linker = self.get_toml("linker", build_section)
|
||||
if target_linker is not None:
|
||||
env["RUSTFLAGS"] += "-C linker=" + target_linker + " "
|
||||
env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes "
|
||||
if self.get_toml("deny-warnings", "rust") != "false":
|
||||
env["RUSTFLAGS"] += "-Dwarnings "
|
||||
|
||||
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
|
||||
os.pathsep + env["PATH"]
|
||||
@ -666,7 +679,7 @@ class RustBuild(object):
|
||||
def update_submodule(self, module, checked_out, recorded_submodules):
|
||||
module_path = os.path.join(self.rust_root, module)
|
||||
|
||||
if checked_out != None:
|
||||
if checked_out is not None:
|
||||
default_encoding = sys.getdefaultencoding()
|
||||
checked_out = checked_out.communicate()[0].decode(default_encoding).strip()
|
||||
if recorded_submodules[module] == checked_out:
|
||||
@ -695,6 +708,14 @@ class RustBuild(object):
|
||||
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
|
||||
self.get_toml('submodules') == "false":
|
||||
return
|
||||
|
||||
# check the existence of 'git' command
|
||||
try:
|
||||
subprocess.check_output(['git', '--version'])
|
||||
except (subprocess.CalledProcessError, OSError):
|
||||
print("error: `git` is not found, please make sure it's installed and in the path.")
|
||||
sys.exit(1)
|
||||
|
||||
slow_submodules = self.get_toml('fast-submodules') == "false"
|
||||
start_time = time()
|
||||
if slow_submodules:
|
||||
@ -731,9 +752,19 @@ class RustBuild(object):
|
||||
self.update_submodule(module[0], module[1], recorded_submodules)
|
||||
print("Submodules updated in %.2f seconds" % (time() - start_time))
|
||||
|
||||
def set_normal_environment(self):
|
||||
"""Set download URL for normal environment"""
|
||||
if 'RUSTUP_DIST_SERVER' in os.environ:
|
||||
self._download_url = os.environ['RUSTUP_DIST_SERVER']
|
||||
else:
|
||||
self._download_url = 'https://static.rust-lang.org'
|
||||
|
||||
def set_dev_environment(self):
|
||||
"""Set download URL for development environment"""
|
||||
self._download_url = 'https://dev-static.rust-lang.org'
|
||||
if 'RUSTUP_DEV_DIST_SERVER' in os.environ:
|
||||
self._download_url = os.environ['RUSTUP_DEV_DIST_SERVER']
|
||||
else:
|
||||
self._download_url = 'https://dev-static.rust-lang.org'
|
||||
|
||||
def check_vendored_status(self):
|
||||
"""Check that vendoring is configured properly"""
|
||||
@ -809,13 +840,13 @@ def bootstrap(help_triggered):
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
|
||||
match = re.search(r'\nverbose = (\d+)', build.config_toml)
|
||||
if match is not None:
|
||||
build.verbose = max(build.verbose, int(match.group(1)))
|
||||
config_verbose = build.get_toml('verbose', 'build')
|
||||
if config_verbose is not None:
|
||||
build.verbose = max(build.verbose, int(config_verbose))
|
||||
|
||||
build.use_vendored_sources = '\nvendor = true' in build.config_toml
|
||||
build.use_vendored_sources = build.get_toml('vendor', 'build') == 'true'
|
||||
|
||||
build.use_locked_deps = '\nlocked-deps = true' in build.config_toml
|
||||
build.use_locked_deps = build.get_toml('locked-deps', 'build') == 'true'
|
||||
|
||||
build.check_vendored_status()
|
||||
|
||||
@ -826,6 +857,8 @@ def bootstrap(help_triggered):
|
||||
|
||||
if 'dev' in data:
|
||||
build.set_dev_environment()
|
||||
else:
|
||||
build.set_normal_environment()
|
||||
|
||||
build.update_submodules()
|
||||
|
||||
|
@ -337,7 +337,6 @@ impl<'a> Builder<'a> {
|
||||
match kind {
|
||||
Kind::Build => describe!(
|
||||
compile::Std,
|
||||
compile::Test,
|
||||
compile::Rustc,
|
||||
compile::CodegenBackend,
|
||||
compile::StartupObjects,
|
||||
@ -363,7 +362,6 @@ impl<'a> Builder<'a> {
|
||||
),
|
||||
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
|
||||
check::Std,
|
||||
check::Test,
|
||||
check::Rustc,
|
||||
check::CodegenBackend,
|
||||
check::Rustdoc
|
||||
@ -425,8 +423,6 @@ impl<'a> Builder<'a> {
|
||||
doc::TheBook,
|
||||
doc::Standalone,
|
||||
doc::Std,
|
||||
doc::Test,
|
||||
doc::WhitelistedRustc,
|
||||
doc::Rustc,
|
||||
doc::Rustdoc,
|
||||
doc::ErrorIndex,
|
||||
@ -801,7 +797,7 @@ impl<'a> Builder<'a> {
|
||||
}
|
||||
|
||||
match mode {
|
||||
Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
|
||||
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {},
|
||||
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
|
||||
// Build proc macros both for the host and the target
|
||||
if target != compiler.host && cmd != "check" {
|
||||
@ -852,7 +848,6 @@ impl<'a> Builder<'a> {
|
||||
// things still build right, please do!
|
||||
match mode {
|
||||
Mode::Std => metadata.push_str("std"),
|
||||
Mode::Test => metadata.push_str("test"),
|
||||
_ => {},
|
||||
}
|
||||
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
|
||||
@ -875,8 +870,7 @@ impl<'a> Builder<'a> {
|
||||
}
|
||||
|
||||
if cmd == "clippy" {
|
||||
extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
|
||||
--json-rendered=termcolor");
|
||||
extra_args.push_str("-Zforce-unstable-if-unmarked");
|
||||
}
|
||||
|
||||
if !extra_args.is_empty() {
|
||||
@ -949,9 +943,9 @@ impl<'a> Builder<'a> {
|
||||
|
||||
let debuginfo_level = match mode {
|
||||
Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
|
||||
Mode::Std | Mode::Test => self.config.rust_debuginfo_level_std,
|
||||
Mode::Std => self.config.rust_debuginfo_level_std,
|
||||
Mode::ToolBootstrap | Mode::ToolStd |
|
||||
Mode::ToolTest | Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
|
||||
Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
|
||||
};
|
||||
cargo.env("RUSTC_DEBUGINFO_LEVEL", debuginfo_level.to_string());
|
||||
|
||||
@ -1151,7 +1145,6 @@ impl<'a> Builder<'a> {
|
||||
|
||||
match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
|
||||
(Mode::Std, Some(n), _) |
|
||||
(Mode::Test, Some(n), _) |
|
||||
(_, _, Some(n)) => {
|
||||
cargo.env("RUSTC_CODEGEN_UNITS", n.to_string());
|
||||
}
|
||||
@ -1174,6 +1167,8 @@ impl<'a> Builder<'a> {
|
||||
cargo.arg("--frozen");
|
||||
}
|
||||
|
||||
cargo.env("RUSTC_INSTALL_BINDIR", &self.config.bindir);
|
||||
|
||||
self.ci_env.force_coloring_in_ci(&mut cargo);
|
||||
|
||||
cargo
|
||||
|
@ -365,27 +365,6 @@ fn dist_with_same_targets_and_hosts() {
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Test>()),
|
||||
&[
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 0 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Assemble>()),
|
||||
&[
|
||||
@ -415,7 +394,47 @@ fn build_default() {
|
||||
let b = INTERNER.intern_str("B");
|
||||
let c = INTERNER.intern_str("C");
|
||||
|
||||
assert!(!builder.cache.all::<compile::Std>().is_empty());
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Std>()),
|
||||
&[
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 0 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert!(!builder.cache.all::<compile::Assemble>().is_empty());
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Rustc>()),
|
||||
@ -450,48 +469,6 @@ fn build_default() {
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Test>()),
|
||||
&[
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 0 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -506,7 +483,47 @@ fn build_with_target_flag() {
|
||||
let b = INTERNER.intern_str("B");
|
||||
let c = INTERNER.intern_str("C");
|
||||
|
||||
assert!(!builder.cache.all::<compile::Std>().is_empty());
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Std>()),
|
||||
&[
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 0 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Assemble>()),
|
||||
&[
|
||||
@ -541,48 +558,6 @@ fn build_with_target_flag() {
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
first(builder.cache.all::<compile::Test>()),
|
||||
&[
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 0 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: a,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
compile::Test {
|
||||
compiler: Compiler { host: b, stage: 2 },
|
||||
target: c,
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||
|
||||
use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
|
||||
use crate::compile::{run_cargo, std_cargo, rustc_cargo, rustc_cargo_env,
|
||||
add_to_sysroot};
|
||||
use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
|
||||
use crate::tool::{prepare_tool_cargo, SourceType};
|
||||
@ -34,7 +34,7 @@ impl Step for Std {
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.all_krates("std")
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
@ -92,7 +92,7 @@ impl Step for Rustc {
|
||||
let compiler = builder.compiler(0, builder.config.build);
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(Test { target });
|
||||
builder.ensure(Std { target });
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
|
||||
cargo_subcommand(builder.kind));
|
||||
@ -159,47 +159,6 @@ impl Step for CodegenBackend {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Test {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(Test {
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let compiler = builder.compiler(0, builder.config.build);
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(Std { target });
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
|
||||
test_cargo(builder, &compiler, target, &mut cargo);
|
||||
|
||||
builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
|
||||
run_cargo(builder,
|
||||
&mut cargo,
|
||||
args(builder.kind),
|
||||
&libtest_stamp(builder, compiler, target),
|
||||
true);
|
||||
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
|
||||
add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustdoc {
|
||||
pub target: Interned<String>,
|
||||
@ -258,16 +217,6 @@ pub fn libstd_stamp(
|
||||
builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for libtest in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn libtest_stamp(
|
||||
builder: &Builder<'_>,
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
) -> PathBuf {
|
||||
builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for librustc in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn librustc_stamp(
|
||||
|
@ -39,7 +39,7 @@ impl Step for Std {
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.all_krates("std")
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
@ -212,11 +212,12 @@ pub fn std_cargo(builder: &Builder<'_>,
|
||||
emscripten: false,
|
||||
});
|
||||
cargo.env("LLVM_CONFIG", llvm_config);
|
||||
cargo.env("RUSTC_BUILD_SANITIZERS", "1");
|
||||
}
|
||||
|
||||
cargo.arg("--features").arg(features)
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join("src/libstd/Cargo.toml"));
|
||||
.arg(builder.src.join("src/libtest/Cargo.toml"));
|
||||
|
||||
if target.contains("musl") {
|
||||
if let Some(p) = builder.musl_root(target) {
|
||||
@ -358,129 +359,6 @@ impl Step for StartupObjects {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Test {
|
||||
pub target: Interned<String>,
|
||||
pub compiler: Compiler,
|
||||
}
|
||||
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(Test {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Builds libtest.
|
||||
///
|
||||
/// This will build libtest and supporting libraries for a particular stage of
|
||||
/// the build using the `compiler` targeting the `target` architecture. The
|
||||
/// artifacts created will also be linked into the sysroot directory.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let target = self.target;
|
||||
let compiler = self.compiler;
|
||||
|
||||
builder.ensure(Std { compiler, target });
|
||||
|
||||
if builder.config.keep_stage.contains(&compiler.stage) {
|
||||
builder.info("Warning: Using a potentially old libtest. This may not behave well.");
|
||||
builder.ensure(TestLink {
|
||||
compiler,
|
||||
target_compiler: compiler,
|
||||
target,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||
if compiler_to_use != compiler {
|
||||
builder.ensure(Test {
|
||||
compiler: compiler_to_use,
|
||||
target,
|
||||
});
|
||||
builder.info(
|
||||
&format!("Uplifting stage1 test ({} -> {})", builder.config.build, target));
|
||||
builder.ensure(TestLink {
|
||||
compiler: compiler_to_use,
|
||||
target_compiler: compiler,
|
||||
target,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Test, target, "build");
|
||||
test_cargo(builder, &compiler, target, &mut cargo);
|
||||
|
||||
builder.info(&format!("Building stage{} test artifacts ({} -> {})", compiler.stage,
|
||||
&compiler.host, target));
|
||||
run_cargo(builder,
|
||||
&mut cargo,
|
||||
vec![],
|
||||
&libtest_stamp(builder, compiler, target),
|
||||
false);
|
||||
|
||||
builder.ensure(TestLink {
|
||||
compiler: builder.compiler(compiler.stage, builder.config.build),
|
||||
target_compiler: compiler,
|
||||
target,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as `std_cargo`, but for libtest
|
||||
pub fn test_cargo(builder: &Builder<'_>,
|
||||
_compiler: &Compiler,
|
||||
_target: Interned<String>,
|
||||
cargo: &mut Command) {
|
||||
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
|
||||
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
|
||||
}
|
||||
cargo.arg("--manifest-path")
|
||||
.arg(builder.src.join("src/libtest/Cargo.toml"));
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TestLink {
|
||||
pub compiler: Compiler,
|
||||
pub target_compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for TestLink {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.never()
|
||||
}
|
||||
|
||||
/// Same as `std_link`, only for libtest
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let compiler = self.compiler;
|
||||
let target_compiler = self.target_compiler;
|
||||
let target = self.target;
|
||||
builder.info(&format!("Copying stage{} test from stage{} ({} -> {} / {})",
|
||||
target_compiler.stage,
|
||||
compiler.stage,
|
||||
&compiler.host,
|
||||
target_compiler.host,
|
||||
target));
|
||||
add_to_sysroot(
|
||||
builder,
|
||||
&builder.sysroot_libdir(target_compiler, target),
|
||||
&builder.sysroot_libdir(target_compiler, compiler.host),
|
||||
&libtest_stamp(builder, compiler, target)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustc {
|
||||
pub target: Interned<String>,
|
||||
@ -512,7 +390,7 @@ impl Step for Rustc {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(Test { compiler, target });
|
||||
builder.ensure(Std { compiler, target });
|
||||
|
||||
if builder.config.keep_stage.contains(&compiler.stage) {
|
||||
builder.info("Warning: Using a potentially old librustc. This may not behave well.");
|
||||
@ -541,7 +419,7 @@ impl Step for Rustc {
|
||||
}
|
||||
|
||||
// Ensure that build scripts and proc macros have a std / libproc_macro to link against.
|
||||
builder.ensure(Test {
|
||||
builder.ensure(Std {
|
||||
compiler: builder.compiler(self.compiler.stage, builder.config.build),
|
||||
target: builder.config.build,
|
||||
});
|
||||
@ -872,16 +750,6 @@ pub fn libstd_stamp(
|
||||
builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for libtest in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn libtest_stamp(
|
||||
builder: &Builder<'_>,
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
) -> PathBuf {
|
||||
builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for librustc in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn librustc_stamp(
|
||||
|
@ -122,7 +122,6 @@ pub struct Config {
|
||||
|
||||
// libstd features
|
||||
pub backtrace: bool, // support for RUST_BACKTRACE
|
||||
pub wasm_syscall: bool,
|
||||
|
||||
// misc
|
||||
pub low_priority: bool,
|
||||
@ -138,7 +137,7 @@ pub struct Config {
|
||||
pub sysconfdir: Option<PathBuf>,
|
||||
pub datadir: Option<PathBuf>,
|
||||
pub docdir: Option<PathBuf>,
|
||||
pub bindir: Option<PathBuf>,
|
||||
pub bindir: PathBuf,
|
||||
pub libdir: Option<PathBuf>,
|
||||
pub mandir: Option<PathBuf>,
|
||||
pub codegen_tests: bool,
|
||||
@ -318,7 +317,6 @@ struct Rust {
|
||||
save_toolstates: Option<String>,
|
||||
codegen_backends: Option<Vec<String>>,
|
||||
codegen_backends_dir: Option<String>,
|
||||
wasm_syscall: Option<bool>,
|
||||
lld: Option<bool>,
|
||||
lldb: Option<bool>,
|
||||
llvm_tools: Option<bool>,
|
||||
@ -402,6 +400,7 @@ impl Config {
|
||||
config.incremental = flags.incremental;
|
||||
config.dry_run = flags.dry_run;
|
||||
config.keep_stage = flags.keep_stage;
|
||||
config.bindir = "bin".into(); // default
|
||||
if let Some(value) = flags.deny_warnings {
|
||||
config.deny_warnings = value;
|
||||
}
|
||||
@ -484,7 +483,7 @@ impl Config {
|
||||
config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from);
|
||||
config.datadir = install.datadir.clone().map(PathBuf::from);
|
||||
config.docdir = install.docdir.clone().map(PathBuf::from);
|
||||
config.bindir = install.bindir.clone().map(PathBuf::from);
|
||||
set(&mut config.bindir, install.bindir.clone().map(PathBuf::from));
|
||||
config.libdir = install.libdir.clone().map(PathBuf::from);
|
||||
config.mandir = install.mandir.clone().map(PathBuf::from);
|
||||
}
|
||||
@ -558,7 +557,6 @@ impl Config {
|
||||
if let Some(true) = rust.incremental {
|
||||
config.incremental = true;
|
||||
}
|
||||
set(&mut config.wasm_syscall, rust.wasm_syscall);
|
||||
set(&mut config.lld_enabled, rust.lld);
|
||||
set(&mut config.lldb_enabled, rust.lldb);
|
||||
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
|
||||
|
@ -18,7 +18,7 @@ use build_helper::{output, t};
|
||||
|
||||
use crate::{Compiler, Mode, LLVM_TOOLS};
|
||||
use crate::channel;
|
||||
use crate::util::{is_dylib, exe};
|
||||
use crate::util::{is_dylib, exe, timeit};
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::compile;
|
||||
use crate::tool::{self, Tool};
|
||||
@ -91,14 +91,15 @@ impl Step for Docs {
|
||||
|
||||
let name = pkgname(builder, "rust-docs");
|
||||
|
||||
builder.info(&format!("Dist docs ({})", host));
|
||||
if !builder.config.docs {
|
||||
builder.info("\tskipping - docs disabled");
|
||||
return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
|
||||
}
|
||||
|
||||
builder.default_doc(None);
|
||||
|
||||
builder.info(&format!("Dist docs ({})", host));
|
||||
let _time = timeit(builder);
|
||||
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
|
||||
@ -151,9 +152,7 @@ impl Step for RustcDocs {
|
||||
|
||||
let name = pkgname(builder, "rustc-docs");
|
||||
|
||||
builder.info(&format!("Dist compiler docs ({})", host));
|
||||
if !builder.config.compiler_docs {
|
||||
builder.info("\tskipping - compiler docs disabled");
|
||||
return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
|
||||
}
|
||||
|
||||
@ -179,6 +178,9 @@ impl Step for RustcDocs {
|
||||
.arg("--component-name=rustc-docs")
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--bulk-dirs=share/doc/rust/html");
|
||||
|
||||
builder.info(&format!("Dist compiler docs ({})", host));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
|
||||
@ -350,6 +352,7 @@ impl Step for Mingw {
|
||||
}
|
||||
|
||||
builder.info(&format!("Dist mingw ({})", host));
|
||||
let _time = timeit(builder);
|
||||
let name = pkgname(builder, "rust-mingw");
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
@ -403,7 +406,6 @@ impl Step for Rustc {
|
||||
let compiler = self.compiler;
|
||||
let host = self.compiler.host;
|
||||
|
||||
builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
|
||||
let name = pkgname(builder, "rustc");
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
@ -460,6 +462,9 @@ impl Step for Rustc {
|
||||
.arg(format!("--package-name={}-{}", name, host))
|
||||
.arg("--component-name=rustc")
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
builder.remove_dir(&overlay);
|
||||
@ -662,8 +667,6 @@ impl Step for Std {
|
||||
let target = self.target;
|
||||
|
||||
let name = pkgname(builder, "rust-std");
|
||||
builder.info(&format!("Dist std stage{} ({} -> {})",
|
||||
compiler.stage, &compiler.host, target));
|
||||
|
||||
// The only true set of target libraries came from the build triple, so
|
||||
// let's reduce redundant work by only producing archives from that host.
|
||||
@ -678,12 +681,7 @@ impl Step for Std {
|
||||
if builder.hosts.iter().any(|t| t == target) {
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
} else {
|
||||
if builder.no_std(target) == Some(true) {
|
||||
// the `test` doesn't compile for no-std targets
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
} else {
|
||||
builder.ensure(compile::Test { compiler, target });
|
||||
}
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
}
|
||||
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||
@ -719,6 +717,10 @@ impl Step for Std {
|
||||
.arg(format!("--package-name={}-{}", name, target))
|
||||
.arg(format!("--component-name=rust-std-{}", target))
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info(&format!("Dist std stage{} ({} -> {})",
|
||||
compiler.stage, &compiler.host, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
distdir(builder).join(format!("{}-{}.tar.gz", name, target))
|
||||
@ -759,15 +761,13 @@ impl Step for Analysis {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
builder.info("Dist analysis");
|
||||
let name = pkgname(builder, "rust-analysis");
|
||||
|
||||
if &compiler.host != builder.config.build {
|
||||
builder.info("\tskipping, not a build host");
|
||||
return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||
}
|
||||
|
||||
builder.ensure(Std { compiler, target });
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||
|
||||
@ -791,6 +791,9 @@ impl Step for Analysis {
|
||||
.arg(format!("--package-name={}-{}", name, target))
|
||||
.arg(format!("--component-name=rust-analysis-{}", target))
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info("Dist analysis");
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
distdir(builder).join(format!("{}-{}.tar.gz", name, target))
|
||||
@ -813,6 +816,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str]
|
||||
"llvm-project/lld", "llvm-project\\lld",
|
||||
"llvm-project/lldb", "llvm-project\\lldb",
|
||||
"llvm-project/llvm", "llvm-project\\llvm",
|
||||
"llvm-project/compiler-rt", "llvm-project\\compiler-rt",
|
||||
];
|
||||
if spath.contains("llvm-project") && !spath.ends_with("llvm-project")
|
||||
&& !LLVM_PROJECTS.iter().any(|path| spath.contains(path))
|
||||
@ -878,8 +882,6 @@ impl Step for Src {
|
||||
|
||||
/// Creates the `rust-src` installer component
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
builder.info("Dist src");
|
||||
|
||||
let name = pkgname(builder, "rust-src");
|
||||
let image = tmpdir(builder).join(format!("{}-image", name));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
@ -912,6 +914,7 @@ impl Step for Src {
|
||||
"src/libproc_macro",
|
||||
"src/tools/rustc-std-workspace-core",
|
||||
"src/tools/rustc-std-workspace-alloc",
|
||||
"src/tools/rustc-std-workspace-std",
|
||||
"src/librustc",
|
||||
"src/libsyntax",
|
||||
];
|
||||
@ -933,6 +936,9 @@ impl Step for Src {
|
||||
.arg(format!("--package-name={}", name))
|
||||
.arg("--component-name=rust-src")
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info("Dist src");
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
|
||||
builder.remove_dir(&image);
|
||||
@ -960,8 +966,6 @@ impl Step for PlainSourceTarball {
|
||||
|
||||
/// Creates the plain source tarball
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
builder.info("Create plain source tarball");
|
||||
|
||||
// Make sure that the root folder of tarball has the correct name
|
||||
let plain_name = format!("{}-src", pkgname(builder, "rustc"));
|
||||
let plain_dst_src = tmpdir(builder).join(&plain_name);
|
||||
@ -1023,6 +1027,9 @@ impl Step for PlainSourceTarball {
|
||||
.arg("--output").arg(&tarball)
|
||||
.arg("--work-dir=.")
|
||||
.current_dir(tmpdir(builder));
|
||||
|
||||
builder.info("Create plain source tarball");
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
distdir(builder).join(&format!("{}.tar.gz", plain_name))
|
||||
}
|
||||
@ -1076,7 +1083,6 @@ impl Step for Cargo {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
|
||||
let src = builder.src.join("src/tools/cargo");
|
||||
let etc = src.join("src/etc");
|
||||
let release_num = builder.release_num("cargo");
|
||||
@ -1129,6 +1135,9 @@ impl Step for Cargo {
|
||||
.arg(format!("--package-name={}-{}", name, target))
|
||||
.arg("--component-name=cargo")
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
distdir(builder).join(format!("{}-{}.tar.gz", name, target))
|
||||
}
|
||||
@ -1164,7 +1173,6 @@ impl Step for Rls {
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
|
||||
builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
|
||||
let src = builder.src.join("src/tools/rls");
|
||||
let release_num = builder.release_num("rls");
|
||||
let name = pkgname(builder, "rls");
|
||||
@ -1213,6 +1221,8 @@ impl Step for Rls {
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--component-name=rls-preview");
|
||||
|
||||
builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
|
||||
}
|
||||
@ -1248,7 +1258,6 @@ impl Step for Clippy {
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
|
||||
builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
|
||||
let src = builder.src.join("src/tools/clippy");
|
||||
let release_num = builder.release_num("clippy");
|
||||
let name = pkgname(builder, "clippy");
|
||||
@ -1302,6 +1311,8 @@ impl Step for Clippy {
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--component-name=clippy-preview");
|
||||
|
||||
builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
|
||||
}
|
||||
@ -1337,7 +1348,6 @@ impl Step for Miri {
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
|
||||
builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
|
||||
let src = builder.src.join("src/tools/miri");
|
||||
let release_num = builder.release_num("miri");
|
||||
let name = pkgname(builder, "miri");
|
||||
@ -1392,6 +1402,8 @@ impl Step for Miri {
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--component-name=miri-preview");
|
||||
|
||||
builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
|
||||
}
|
||||
@ -1426,7 +1438,6 @@ impl Step for Rustfmt {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
|
||||
let src = builder.src.join("src/tools/rustfmt");
|
||||
let release_num = builder.release_num("rustfmt");
|
||||
let name = pkgname(builder, "rustfmt");
|
||||
@ -1479,6 +1490,8 @@ impl Step for Rustfmt {
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--component-name=rustfmt-preview");
|
||||
|
||||
builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
|
||||
}
|
||||
@ -1579,6 +1592,7 @@ impl Step for Extended {
|
||||
input_tarballs.push(tarball);
|
||||
}
|
||||
|
||||
builder.info("building combined installer");
|
||||
let mut cmd = rust_installer(builder);
|
||||
cmd.arg("combine")
|
||||
.arg("--product-name=Rust")
|
||||
@ -1590,7 +1604,9 @@ impl Step for Extended {
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo")
|
||||
.arg("--input-tarballs").arg(input_tarballs)
|
||||
.arg("--non-installed-overlay").arg(&overlay);
|
||||
let time = timeit(&builder);
|
||||
builder.run(&mut cmd);
|
||||
drop(time);
|
||||
|
||||
let mut license = String::new();
|
||||
license += &builder.read(&builder.src.join("COPYRIGHT"));
|
||||
@ -1646,6 +1662,7 @@ impl Step for Extended {
|
||||
};
|
||||
|
||||
if target.contains("apple-darwin") {
|
||||
builder.info("building pkg installer");
|
||||
let pkg = tmp.join("pkg");
|
||||
let _ = fs::remove_dir_all(&pkg);
|
||||
|
||||
@ -1695,6 +1712,7 @@ impl Step for Extended {
|
||||
pkgname(builder, "rust"),
|
||||
target)))
|
||||
.arg("--package-path").arg(&pkg);
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
}
|
||||
|
||||
@ -1745,14 +1763,18 @@ impl Step for Extended {
|
||||
builder.create(&exe.join("LICENSE.txt"), &license);
|
||||
|
||||
// Generate exe installer
|
||||
builder.info("building `exe` installer with `iscc`");
|
||||
let mut cmd = Command::new("iscc");
|
||||
cmd.arg("rust.iss")
|
||||
.arg("/Q")
|
||||
.current_dir(&exe);
|
||||
if target.contains("windows-gnu") {
|
||||
cmd.arg("/dMINGW");
|
||||
}
|
||||
add_env(builder, &mut cmd, target);
|
||||
let time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
drop(time);
|
||||
builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)),
|
||||
&distdir(builder),
|
||||
0o755);
|
||||
@ -1917,6 +1939,7 @@ impl Step for Extended {
|
||||
builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644);
|
||||
builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644);
|
||||
|
||||
builder.info(&format!("building `msi` installer with {:?}", light));
|
||||
let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target);
|
||||
let mut cmd = Command::new(&light);
|
||||
cmd.arg("-nologo")
|
||||
@ -1949,6 +1972,7 @@ impl Step for Extended {
|
||||
// ICE57 wrongly complains about the shortcuts
|
||||
cmd.arg("-sice:ICE57");
|
||||
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
|
||||
if !builder.config.dry_run {
|
||||
@ -2003,6 +2027,8 @@ impl Step for HashSign {
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
// This gets called by `promote-release`
|
||||
// (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
|
||||
let mut cmd = builder.tool_cmd(Tool::BuildManifest);
|
||||
if builder.config.dry_run {
|
||||
return;
|
||||
@ -2013,10 +2039,14 @@ impl Step for HashSign {
|
||||
let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
|
||||
panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
|
||||
});
|
||||
let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
|
||||
panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
|
||||
});
|
||||
let pass = t!(fs::read_to_string(&file));
|
||||
let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
|
||||
let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
|
||||
panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
|
||||
});
|
||||
t!(fs::read_to_string(&file))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let today = output(Command::new("date").arg("+%Y-%m-%d"));
|
||||
|
||||
@ -2111,6 +2141,7 @@ impl Step for LlvmTools {
|
||||
}
|
||||
|
||||
builder.info(&format!("Dist LlvmTools ({})", target));
|
||||
let _time = timeit(builder);
|
||||
let src = builder.src.join("src/llvm-project/llvm");
|
||||
let name = pkgname(builder, "llvm-tools");
|
||||
|
||||
|
@ -375,7 +375,7 @@ impl Step for Standalone {
|
||||
up_to_date(&footer, &html) &&
|
||||
up_to_date(&favicon, &html) &&
|
||||
up_to_date(&full_toc, &html) &&
|
||||
up_to_date(&version_info, &html) &&
|
||||
(builder.config.dry_run || up_to_date(&version_info, &html)) &&
|
||||
(builder.config.dry_run || up_to_date(&rustdoc, &html)) {
|
||||
continue
|
||||
}
|
||||
@ -413,7 +413,7 @@ impl Step for Std {
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.all_krates("std").default_condition(builder.config.docs)
|
||||
run.all_krates("test").default_condition(builder.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
@ -476,136 +476,10 @@ impl Step for Std {
|
||||
.arg("--index-page").arg(&builder.src.join("src/doc/index.md"));
|
||||
|
||||
builder.run(&mut cargo);
|
||||
builder.cp_r(&my_out, &out);
|
||||
};
|
||||
for krate in &["alloc", "core", "std"] {
|
||||
for krate in &["alloc", "core", "std", "proc_macro", "test"] {
|
||||
run_cargo_rustdoc_for(krate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Test {
|
||||
stage: u32,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.krate("test").default_condition(builder.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(Test {
|
||||
stage: run.builder.top_stage,
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Compile all libtest documentation.
|
||||
///
|
||||
/// This will generate all documentation for libtest and its dependencies. This
|
||||
/// is largely just a wrapper around `cargo doc`.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let stage = self.stage;
|
||||
let target = self.target;
|
||||
builder.info(&format!("Documenting stage{} test ({})", stage, target));
|
||||
let out = builder.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler_for(stage, builder.config.build, target);
|
||||
|
||||
// Build libstd docs so that we generate relative links
|
||||
builder.ensure(Std { stage, target });
|
||||
|
||||
builder.ensure(compile::Test { compiler, target });
|
||||
let out_dir = builder.stage_out(compiler, Mode::Test)
|
||||
.join(target).join("doc");
|
||||
|
||||
// See docs in std above for why we symlink
|
||||
let my_out = builder.crate_doc_out(target);
|
||||
t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc");
|
||||
compile::test_cargo(builder, &compiler, target, &mut cargo);
|
||||
|
||||
cargo.arg("--no-deps")
|
||||
.arg("-p").arg("test")
|
||||
.env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
|
||||
.env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
|
||||
|
||||
builder.run(&mut cargo);
|
||||
builder.cp_r(&my_out, &out);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct WhitelistedRustc {
|
||||
stage: u32,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for WhitelistedRustc {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.krate("rustc-main").default_condition(builder.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(WhitelistedRustc {
|
||||
stage: run.builder.top_stage,
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Generates whitelisted compiler crate documentation.
|
||||
///
|
||||
/// This will generate all documentation for crates that are whitelisted
|
||||
/// to be included in the standard documentation. This documentation is
|
||||
/// included in the standard Rust documentation, so we should always
|
||||
/// document it and symlink to merge with the rest of the std and test
|
||||
/// documentation. We don't build other compiler documentation
|
||||
/// here as we want to be able to keep it separate from the standard
|
||||
/// documentation. This is largely just a wrapper around `cargo doc`.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let stage = self.stage;
|
||||
let target = self.target;
|
||||
builder.info(&format!("Documenting stage{} whitelisted compiler ({})", stage, target));
|
||||
let out = builder.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler_for(stage, builder.config.build, target);
|
||||
|
||||
// Build libstd docs so that we generate relative links
|
||||
builder.ensure(Std { stage, target });
|
||||
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
let out_dir = builder.stage_out(compiler, Mode::Rustc)
|
||||
.join(target).join("doc");
|
||||
|
||||
// See docs in std above for why we symlink
|
||||
let my_out = builder.crate_doc_out(target);
|
||||
t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
|
||||
compile::rustc_cargo(builder, &mut cargo);
|
||||
|
||||
// We don't want to build docs for internal compiler dependencies in this
|
||||
// step (there is another step for that). Therefore, we whitelist the crates
|
||||
// for which docs must be built.
|
||||
for krate in &["proc_macro"] {
|
||||
cargo.arg("-p").arg(krate)
|
||||
.env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
|
||||
.env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
|
||||
}
|
||||
|
||||
builder.run(&mut cargo);
|
||||
builder.cp_r(&my_out, &out);
|
||||
}
|
||||
}
|
||||
@ -825,8 +699,7 @@ impl Step for ErrorIndex {
|
||||
index.arg(crate::channel::CFG_RELEASE_NUM);
|
||||
|
||||
// FIXME: shouldn't have to pass this env var
|
||||
index.env("CFG_BUILD", &builder.config.build)
|
||||
.env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
|
||||
index.env("CFG_BUILD", &builder.config.build);
|
||||
|
||||
builder.run(&mut index);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ pub struct Flags {
|
||||
// This overrides the deny-warnings configuation option,
|
||||
// which passes -Dwarnings to the compiler invocations.
|
||||
//
|
||||
// true => deny, false => allow
|
||||
// true => deny, false => warn
|
||||
pub deny_warnings: Option<bool>,
|
||||
}
|
||||
|
||||
@ -556,10 +556,10 @@ fn split(s: &[String]) -> Vec<String> {
|
||||
fn parse_deny_warnings(matches: &getopts::Matches) -> Option<bool> {
|
||||
match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) {
|
||||
Some("deny") => Some(true),
|
||||
Some("allow") => Some(false),
|
||||
Some("warn") => Some(false),
|
||||
Some(value) => {
|
||||
eprintln!(
|
||||
r#"invalid value for --warnings: {:?}, expected "allow" or "deny""#,
|
||||
r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#,
|
||||
value,
|
||||
);
|
||||
process::exit(1);
|
||||
|
@ -67,7 +67,6 @@ fn install_sh(
|
||||
let sysconfdir_default = PathBuf::from("/etc");
|
||||
let datadir_default = PathBuf::from("share");
|
||||
let docdir_default = datadir_default.join("doc/rust");
|
||||
let bindir_default = PathBuf::from("bin");
|
||||
let libdir_default = PathBuf::from("lib");
|
||||
let mandir_default = datadir_default.join("man");
|
||||
let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| {
|
||||
@ -76,7 +75,7 @@ fn install_sh(
|
||||
let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default);
|
||||
let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default);
|
||||
let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default);
|
||||
let bindir = builder.config.bindir.as_ref().unwrap_or(&bindir_default);
|
||||
let bindir = &builder.config.bindir;
|
||||
let libdir = builder.config.libdir.as_ref().unwrap_or(&libdir_default);
|
||||
let mandir = builder.config.mandir.as_ref().unwrap_or(&mandir_default);
|
||||
|
||||
|
@ -103,9 +103,6 @@
|
||||
//! More documentation can be found in each respective module below, and you can
|
||||
//! also check out the `src/bootstrap/README.md` file for more information.
|
||||
|
||||
// NO-RUSTC-WRAPPER
|
||||
#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(drain_filter)]
|
||||
|
||||
@ -297,9 +294,6 @@ pub enum Mode {
|
||||
/// Build the standard library, placing output in the "stageN-std" directory.
|
||||
Std,
|
||||
|
||||
/// Build libtest, placing output in the "stageN-test" directory.
|
||||
Test,
|
||||
|
||||
/// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
|
||||
Rustc,
|
||||
|
||||
@ -315,7 +309,6 @@ pub enum Mode {
|
||||
/// Compile a tool which uses all libraries we compile (up to rustc).
|
||||
/// Doesn't use the stage0 compiler libraries like "other", and includes
|
||||
/// tools like rustdoc, cargo, rls, etc.
|
||||
ToolTest,
|
||||
ToolStd,
|
||||
ToolRustc,
|
||||
}
|
||||
@ -502,9 +495,6 @@ impl Build {
|
||||
if self.config.profiler {
|
||||
features.push_str(" profiler");
|
||||
}
|
||||
if self.config.wasm_syscall {
|
||||
features.push_str(" wasm_syscall");
|
||||
}
|
||||
features
|
||||
}
|
||||
|
||||
@ -536,11 +526,10 @@ impl Build {
|
||||
fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
|
||||
let suffix = match mode {
|
||||
Mode::Std => "-std",
|
||||
Mode::Test => "-test",
|
||||
Mode::Rustc => "-rustc",
|
||||
Mode::Codegen => "-codegen",
|
||||
Mode::ToolBootstrap => "-bootstrap-tools",
|
||||
Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
|
||||
Mode::ToolStd | Mode::ToolRustc => "-tools",
|
||||
};
|
||||
self.out.join(&*compiler.host)
|
||||
.join(format!("stage{}{}", compiler.stage, suffix))
|
||||
|
@ -81,26 +81,29 @@ impl Step for Llvm {
|
||||
(info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin"))
|
||||
};
|
||||
|
||||
if !llvm_info.is_git() {
|
||||
println!(
|
||||
"git could not determine the LLVM submodule commit hash. \
|
||||
Assuming that an LLVM build is necessary.",
|
||||
);
|
||||
}
|
||||
|
||||
let build_llvm_config = llvm_config_ret_dir
|
||||
.join(exe("llvm-config", &*builder.config.build));
|
||||
let done_stamp = out_dir.join("llvm-finished-building");
|
||||
|
||||
if let Some(llvm_commit) = llvm_info.sha() {
|
||||
if done_stamp.exists() {
|
||||
if done_stamp.exists() {
|
||||
if let Some(llvm_commit) = llvm_info.sha() {
|
||||
let done_contents = t!(fs::read(&done_stamp));
|
||||
|
||||
// If LLVM was already built previously and the submodule's commit didn't change
|
||||
// from the previous build, then no action is required.
|
||||
if done_contents == llvm_commit.as_bytes() {
|
||||
return build_llvm_config
|
||||
return build_llvm_config;
|
||||
}
|
||||
} else {
|
||||
builder.info(
|
||||
"Could not determine the LLVM submodule commit hash. \
|
||||
Assuming that an LLVM rebuild is not necessary.",
|
||||
);
|
||||
builder.info(&format!(
|
||||
"To force LLVM to rebuild, remove the file `{}`",
|
||||
done_stamp.display()
|
||||
));
|
||||
return build_llvm_config;
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,9 +306,7 @@ impl Step for Llvm {
|
||||
|
||||
cfg.build();
|
||||
|
||||
if let Some(llvm_commit) = llvm_info.sha() {
|
||||
t!(fs::write(&done_stamp, llvm_commit));
|
||||
}
|
||||
t!(fs::write(&done_stamp, llvm_info.sha().unwrap_or("")));
|
||||
|
||||
build_llvm_config
|
||||
}
|
||||
|
@ -1040,21 +1040,10 @@ impl Step for Compiletest {
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
}
|
||||
|
||||
if builder.no_std(target) == Some(true) {
|
||||
// the `test` doesn't compile for no-std targets
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
} else {
|
||||
builder.ensure(compile::Test { compiler, target });
|
||||
}
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
// ensure that `libproc_macro` is available on the host.
|
||||
builder.ensure(compile::Std { compiler, target: compiler.host });
|
||||
|
||||
if builder.no_std(target) == Some(true) {
|
||||
// for no_std run-make (e.g., thumb*),
|
||||
// we need a host compiler which is called by cargo.
|
||||
builder.ensure(compile::Std { compiler, target: compiler.host });
|
||||
}
|
||||
|
||||
// HACK(eddyb) ensure that `libproc_macro` is available on the host.
|
||||
builder.ensure(compile::Test { compiler, target: compiler.host });
|
||||
// Also provide `rust_test_helpers` for the host.
|
||||
builder.ensure(native::TestHelpers { target: compiler.host });
|
||||
|
||||
@ -1338,7 +1327,10 @@ impl Step for Compiletest {
|
||||
cmd.env("RUSTC_PROFILER_SUPPORT", "1");
|
||||
}
|
||||
|
||||
cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp"));
|
||||
let tmp = builder.out.join("tmp");
|
||||
std::fs::create_dir_all(&tmp).unwrap();
|
||||
cmd.env("RUST_TEST_TMPDIR", tmp);
|
||||
|
||||
|
||||
cmd.arg("--adb-path").arg("adb");
|
||||
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
|
||||
@ -1399,7 +1391,7 @@ impl Step for DocTest {
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let compiler = self.compiler;
|
||||
|
||||
builder.ensure(compile::Test {
|
||||
builder.ensure(compile::Std {
|
||||
compiler,
|
||||
target: compiler.host,
|
||||
});
|
||||
@ -1535,8 +1527,7 @@ impl Step for ErrorIndex {
|
||||
);
|
||||
tool.arg("markdown")
|
||||
.arg(&output)
|
||||
.env("CFG_BUILD", &builder.config.build)
|
||||
.env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
|
||||
.env("CFG_BUILD", &builder.config.build);
|
||||
|
||||
builder.info(&format!("Testing error-index stage{}", compiler.stage));
|
||||
let _time = util::timeit(&builder);
|
||||
@ -1710,8 +1701,7 @@ impl Step for Crate {
|
||||
|
||||
fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run = run.krate("test");
|
||||
for krate in run.builder.in_tree_crates("std") {
|
||||
for krate in run.builder.in_tree_crates("test") {
|
||||
if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
|
||||
run = run.path(krate.local_path(&builder).to_str().unwrap());
|
||||
}
|
||||
@ -1735,14 +1725,9 @@ impl Step for Crate {
|
||||
});
|
||||
};
|
||||
|
||||
for krate in builder.in_tree_crates("std") {
|
||||
if run.path.ends_with(&krate.local_path(&builder)) {
|
||||
make(Mode::Std, krate);
|
||||
}
|
||||
}
|
||||
for krate in builder.in_tree_crates("test") {
|
||||
if run.path.ends_with(&krate.local_path(&builder)) {
|
||||
make(Mode::Test, krate);
|
||||
make(Mode::Std, krate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1762,7 +1747,7 @@ impl Step for Crate {
|
||||
let test_kind = self.test_kind;
|
||||
let krate = self.krate;
|
||||
|
||||
builder.ensure(compile::Test { compiler, target });
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
|
||||
// If we're not doing a full bootstrap but we're testing a stage2
|
||||
@ -1776,9 +1761,6 @@ impl Step for Crate {
|
||||
Mode::Std => {
|
||||
compile::std_cargo(builder, &compiler, target, &mut cargo);
|
||||
}
|
||||
Mode::Test => {
|
||||
compile::test_cargo(builder, &compiler, target, &mut cargo);
|
||||
}
|
||||
Mode::Rustc => {
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
compile::rustc_cargo(builder, &mut cargo);
|
||||
@ -1832,16 +1814,6 @@ impl Step for Crate {
|
||||
.expect("nodejs not configured"),
|
||||
);
|
||||
} else if target.starts_with("wasm32") {
|
||||
// Warn about running tests without the `wasm_syscall` feature enabled.
|
||||
// The javascript shim implements the syscall interface so that test
|
||||
// output can be correctly reported.
|
||||
if !builder.config.wasm_syscall {
|
||||
builder.info(
|
||||
"Libstd was built without `wasm_syscall` feature enabled: \
|
||||
test output may not be visible."
|
||||
);
|
||||
}
|
||||
|
||||
// On the wasm32-unknown-unknown target we're using LTO which is
|
||||
// incompatible with `-C prefer-dynamic`, so disable that here
|
||||
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
||||
@ -1980,7 +1952,7 @@ impl Step for RemoteCopyLibs {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.ensure(compile::Test { compiler, target });
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
|
||||
builder.info(&format!("REMOTE copy libs to emulator ({})", target));
|
||||
t!(fs::create_dir_all(builder.out.join("tmp")));
|
||||
|
@ -577,12 +577,6 @@ impl Step for Cargo {
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// Cargo depends on procedural macros, so make sure the host
|
||||
// libstd/libproc_macro is available.
|
||||
builder.ensure(compile::Test {
|
||||
compiler: self.compiler,
|
||||
target: builder.config.build,
|
||||
});
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
@ -650,31 +644,10 @@ macro_rules! tool_extended {
|
||||
|
||||
tool_extended!((self, builder),
|
||||
Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {};
|
||||
CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {
|
||||
// Clippy depends on procedural macros, so make sure that's built for
|
||||
// the compiler itself.
|
||||
builder.ensure(compile::Test {
|
||||
compiler: self.compiler,
|
||||
target: builder.config.build,
|
||||
});
|
||||
};
|
||||
Clippy, clippy, "src/tools/clippy", "clippy-driver", {
|
||||
// Clippy depends on procedural macros, so make sure that's built for
|
||||
// the compiler itself.
|
||||
builder.ensure(compile::Test {
|
||||
compiler: self.compiler,
|
||||
target: builder.config.build,
|
||||
});
|
||||
};
|
||||
CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {};
|
||||
Clippy, clippy, "src/tools/clippy", "clippy-driver", {};
|
||||
Miri, miri, "src/tools/miri", "miri", {};
|
||||
CargoMiri, miri, "src/tools/miri", "cargo-miri", {
|
||||
// Miri depends on procedural macros, so make sure that's built for
|
||||
// the compiler itself.
|
||||
builder.ensure(compile::Test {
|
||||
compiler: self.compiler,
|
||||
target: builder.config.build,
|
||||
});
|
||||
};
|
||||
CargoMiri, miri, "src/tools/miri", "cargo-miri", {};
|
||||
Rls, rls, "src/tools/rls", "rls", {
|
||||
let clippy = builder.ensure(Clippy {
|
||||
compiler: self.compiler,
|
||||
@ -684,12 +657,6 @@ tool_extended!((self, builder),
|
||||
if clippy.is_some() {
|
||||
self.extra_features.push("clippy".to_owned());
|
||||
}
|
||||
// RLS depends on procedural macros, so make sure that's built for
|
||||
// the compiler itself.
|
||||
builder.ensure(compile::Test {
|
||||
compiler: self.compiler,
|
||||
target: builder.config.build,
|
||||
});
|
||||
};
|
||||
Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", {};
|
||||
);
|
||||
|
@ -1,6 +1,3 @@
|
||||
// NO-RUSTC-WRAPPER
|
||||
#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
use std::fs::File;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
@ -262,7 +259,7 @@ pub fn native_lib_boilerplate(
|
||||
if !up_to_date(Path::new("build.rs"), ×tamp) || !up_to_date(src_dir, ×tamp) {
|
||||
Ok(NativeLibBoilerplate {
|
||||
src_dir: src_dir.to_path_buf(),
|
||||
out_dir: out_dir,
|
||||
out_dir,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
|
@ -7,7 +7,7 @@ trigger:
|
||||
- auto
|
||||
|
||||
variables:
|
||||
- group: real-prod-credentials
|
||||
- group: prod-credentials
|
||||
|
||||
jobs:
|
||||
- job: Linux
|
||||
@ -236,10 +236,16 @@ jobs:
|
||||
MSYS_BITS: 32
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
|
||||
SCRIPT: make ci-subset-1
|
||||
# FIXME(#59637)
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
i686-msvc-2:
|
||||
MSYS_BITS: 32
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
|
||||
SCRIPT: make ci-subset-2
|
||||
# FIXME(#59637)
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
# MSVC aux tests
|
||||
x86_64-msvc-aux:
|
||||
MSYS_BITS: 64
|
||||
@ -250,6 +256,9 @@ jobs:
|
||||
SCRIPT: python x.py test src/tools/cargotest src/tools/cargo
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
|
||||
VCVARS_BAT: vcvars64.bat
|
||||
# FIXME(#59637)
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
# MSVC tools tests
|
||||
x86_64-msvc-tools:
|
||||
MSYS_BITS: 64
|
||||
|
@ -7,7 +7,7 @@ trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
- group: real-prod-credentials
|
||||
- group: prod-credentials
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
|
@ -18,9 +18,9 @@ steps:
|
||||
# one is MSI installers and one is EXE, but they're not used so frequently at
|
||||
# this point anyway so perhaps it's a wash!
|
||||
- script: |
|
||||
powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe"
|
||||
is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
|
||||
echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5
|
||||
curl.exe -o is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe
|
||||
is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
|
||||
displayName: Install InnoSetup
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
@ -43,24 +43,18 @@ steps:
|
||||
# FIXME: we should probe the default azure image and see if we can use the MSYS2
|
||||
# toolchain there. (if there's even one there). For now though this gets the job
|
||||
# done.
|
||||
- script: |
|
||||
set MSYS_PATH=%CD%\citools\msys64
|
||||
choco install msys2 --params="/InstallDir:%MSYS_PATH% /NoPath" -y
|
||||
set PATH=%MSYS_PATH%\usr\bin;%PATH%
|
||||
pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
|
||||
IF "%MINGW_URL%"=="" (
|
||||
IF "%MSYS_BITS%"=="32" pacman -S --noconfirm --needed mingw-w64-i686-toolchain mingw-w64-i686-cmake mingw-w64-i686-gcc mingw-w64-i686-python2
|
||||
IF "%MSYS_BITS%"=="64" pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-python2
|
||||
)
|
||||
where rev
|
||||
rev --help
|
||||
where make
|
||||
|
||||
echo ##vso[task.setvariable variable=MSYS_PATH]%MSYS_PATH%
|
||||
echo ##vso[task.prependpath]%MSYS_PATH%\usr\bin
|
||||
- bash: |
|
||||
set -e
|
||||
choco install msys2 --params="/InstallDir:$(System.Workfolder)/msys2 /NoPath" -y --no-progress
|
||||
echo "##vso[task.prependpath]$(System.Workfolder)/msys2/usr/bin"
|
||||
mkdir -p "$(System.Workfolder)/msys2/home/$USERNAME"
|
||||
displayName: Install msys2
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
- bash: pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
|
||||
displayName: Install msys2 base deps
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# If we need to download a custom MinGW, do so here and set the path
|
||||
# appropriately.
|
||||
#
|
||||
@ -81,39 +75,46 @@ steps:
|
||||
#
|
||||
# Note that we don't literally overwrite the gdb.exe binary because it appears
|
||||
# to just use gdborig.exe, so that's the binary we deal with instead.
|
||||
- script: |
|
||||
powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %MINGW_ARCHIVE% %MINGW_URL%/%MINGW_ARCHIVE%"
|
||||
7z x -y %MINGW_ARCHIVE% > nul
|
||||
powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_URL%/2017-04-20-%MSYS_BITS%bit-gdborig.exe"
|
||||
mv 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_DIR%\bin\gdborig.exe
|
||||
echo ##vso[task.prependpath]%CD%\%MINGW_DIR%\bin
|
||||
- bash: |
|
||||
set -e
|
||||
curl -o mingw.7z $MINGW_URL/$MINGW_ARCHIVE
|
||||
7z x -y mingw.7z > /dev/null
|
||||
curl -o $MINGW_DIR/bin/gdborig.exe $MINGW_URL/2017-04-20-${MSYS_BITS}bit-gdborig.exe
|
||||
echo "##vso[task.prependpath]`pwd`/$MINGW_DIR/bin"
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
|
||||
displayName: Download custom MinGW
|
||||
|
||||
# Otherwise pull in the MinGW installed on appveyor
|
||||
- script: |
|
||||
echo ##vso[task.prependpath]%MSYS_PATH%\mingw%MSYS_BITS%\bin
|
||||
# Otherwise install MinGW through `pacman`
|
||||
- bash: |
|
||||
set -e
|
||||
arch=i686
|
||||
if [ "$MSYS_BITS" = "64" ]; then
|
||||
arch=x86_64
|
||||
fi
|
||||
pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake mingw-w64-$arch-gcc mingw-w64-$arch-python2
|
||||
echo "##vso[task.prependpath]$(System.Workfolder)/msys2/mingw$MSYS_BITS/bin"
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
|
||||
displayName: Add MinGW to path
|
||||
displayName: Download standard MinGW
|
||||
|
||||
# Make sure we use the native python interpreter instead of some msys equivalent
|
||||
# one way or another. The msys interpreters seem to have weird path conversions
|
||||
# baked in which break LLVM's build system one way or another, so let's use the
|
||||
# native version which keeps everything as native as possible.
|
||||
- script: |
|
||||
copy C:\Python27amd64\python.exe C:\Python27amd64\python2.7.exe
|
||||
echo ##vso[task.prependpath]C:\Python27amd64
|
||||
- bash: |
|
||||
set -e
|
||||
cp C:/Python27amd64/python.exe C:/Python27amd64/python2.7.exe
|
||||
echo "##vso[task.prependpath]C:/Python27amd64"
|
||||
displayName: Prefer the "native" Python as LLVM has trouble building with MSYS sometimes
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Note that this is originally from the github releases patch of Ninja
|
||||
- script: |
|
||||
md ninja
|
||||
powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip"
|
||||
7z x -oninja 2017-03-15-ninja-win.zip
|
||||
del 2017-03-15-ninja-win.zip
|
||||
set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja
|
||||
echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS%
|
||||
echo ##vso[task.prependpath]%CD%\ninja
|
||||
- bash: |
|
||||
set -e
|
||||
mkdir ninja
|
||||
curl -o ninja.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip
|
||||
7z x -oninja ninja.zip
|
||||
rm ninja.zip
|
||||
echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --enable-ninja"
|
||||
echo "##vso[task.prependpath]`pwd`/ninja"
|
||||
displayName: Download and install ninja
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
@ -147,8 +147,15 @@ steps:
|
||||
git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
|
||||
cd rust-toolstate
|
||||
python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" ""
|
||||
# Only check maintainers if this build is supposed to publish toolstate.
|
||||
# Builds that are not supposed to publish don't have the access token.
|
||||
if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
|
||||
TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py"
|
||||
fi
|
||||
cd ..
|
||||
rm -rf rust-toolstate
|
||||
env:
|
||||
TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
|
||||
condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check'))
|
||||
displayName: Verify the publish_toolstate script works
|
||||
|
||||
@ -168,7 +175,8 @@ steps:
|
||||
env:
|
||||
CI: true
|
||||
SRC: .
|
||||
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
|
||||
AWS_ACCESS_KEY_ID: $(SCCACHE_AWS_ACCESS_KEY_ID)
|
||||
AWS_SECRET_ACCESS_KEY: $(SCCACHE_AWS_SECRET_ACCESS_KEY)
|
||||
TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
|
||||
condition: and(succeeded(), not(variables.SKIP_JOB))
|
||||
displayName: Run build
|
||||
@ -192,7 +200,8 @@ steps:
|
||||
fi
|
||||
retry aws s3 cp --no-progress --recursive --acl public-read ./$upload_dir s3://$DEPLOY_BUCKET/$deploy_dir/$BUILD_SOURCEVERSION
|
||||
env:
|
||||
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
|
||||
AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
|
||||
AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
|
||||
condition: and(succeeded(), not(variables.SKIP_JOB), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1')))
|
||||
displayName: Upload artifacts
|
||||
|
||||
@ -201,7 +210,8 @@ steps:
|
||||
# errors here ever fail the build since this is just informational.
|
||||
- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$CI_JOB_NAME.csv
|
||||
env:
|
||||
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
|
||||
condition: variables['AWS_SECRET_ACCESS_KEY']
|
||||
AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
|
||||
AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
|
||||
condition: variables['UPLOAD_AWS_SECRET_ACCESS_KEY']
|
||||
continueOnError: true
|
||||
displayName: Upload CPU usage statistics
|
||||
|
@ -3,7 +3,7 @@ trigger:
|
||||
- try
|
||||
|
||||
variables:
|
||||
- group: real-prod-credentials
|
||||
- group: prod-credentials
|
||||
|
||||
jobs:
|
||||
- job: Linux
|
||||
|
@ -104,9 +104,7 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi
|
||||
ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf
|
||||
ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl
|
||||
ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu
|
||||
# FIXME: temporarily disable the redox builder,
|
||||
# see: https://github.com/rust-lang/rust/issues/63160
|
||||
# ENV TARGETS=$TARGETS,x86_64-unknown-redox
|
||||
ENV TARGETS=$TARGETS,x86_64-unknown-redox
|
||||
ENV TARGETS=$TARGETS,thumbv6m-none-eabi
|
||||
ENV TARGETS=$TARGETS,thumbv7m-none-eabi
|
||||
ENV TARGETS=$TARGETS,thumbv7em-none-eabi
|
||||
@ -132,7 +130,7 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
|
||||
CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
|
||||
AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
|
||||
CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++
|
||||
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--musl-root-armv5te=/musl-armv5te \
|
||||
--musl-root-arm=/musl-arm \
|
||||
|
@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl
|
||||
# Note that this originally came from:
|
||||
# https://downloads.openwrt.org/snapshots/trunk/malta/generic/
|
||||
# OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2
|
||||
URL="https://rust-lang-ci2.s3.amazonaws.com/libc"
|
||||
URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc"
|
||||
FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2"
|
||||
curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2
|
||||
|
||||
|
@ -19,3 +19,6 @@ RUN sh /scripts/sccache.sh
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests
|
||||
ENV SCRIPT python2.7 ../x.py test
|
||||
|
||||
# FIXME(#59637) takes too long on CI right now
|
||||
ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1
|
||||
|
@ -25,3 +25,6 @@ ENV SCRIPT python2.7 ../x.py test \
|
||||
--exclude src/test/rustdoc-js \
|
||||
--exclude src/tools/error_index_generator \
|
||||
--exclude src/tools/linkchecker
|
||||
|
||||
# FIXME(#59637) takes too long on CI right now
|
||||
ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 7ddc46460f09a5cd9bd2a620565bdc20b3315ea9
|
||||
Subproject commit 871416b85c1a73717d65d6f4a9ea29e5aef3db0e
|
@ -1 +1 @@
|
||||
Subproject commit c5da1e11915d3f28266168baaf55822f7e3fe999
|
||||
Subproject commit 5ca585c4a7552efb546e7681c3de0712f4ae4fdc
|
@ -1 +1 @@
|
||||
Subproject commit 8a7d05615e5bc0a7fb961b4919c44f5221ee54da
|
||||
Subproject commit 4374786f0b4bf0606b35d5c30a9681f342e5707b
|
@ -1 +1 @@
|
||||
Subproject commit b4b3536839042a6743fc76f0d9ad2a812020aeaa
|
||||
Subproject commit fa5dfb832ef8a7568e17dabf612f486d641ff4ac
|
@ -1 +1 @@
|
||||
Subproject commit f2c15ba5ee89ae9469a2cf60494977749901d764
|
||||
Subproject commit 67cfbf31df880728dcf7cb35b15b028ec92caf31
|
@ -1 +1 @@
|
||||
Subproject commit 6f4ba673ff9d4613e98415bc095347a6a0031e9c
|
||||
Subproject commit 941968db2fd9c85788a4f971c8e425d46b4cb734
|
@ -304,3 +304,10 @@ to customize the output:
|
||||
|
||||
Note that it is invalid to combine the `--json` argument with the `--color`
|
||||
argument, and it is required to combine `--json` with `--error-format=json`.
|
||||
|
||||
## `@path`: load command-line flags from a path
|
||||
|
||||
If you specify `@path` on the command-line, then it will open `path` and read
|
||||
command line options from it. These options are one per line; a blank line indicates
|
||||
an empty option. The file can use Unix or Windows style line endings, and must be
|
||||
encoded as UTF-8.
|
||||
|
@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
|
||||
| Rust 1.34 | ✗ | ✓ |
|
||||
| Rust 1.35 | ✗ | ✓ |
|
||||
| Rust 1.36 | ✗ | ✓ |
|
||||
| Rust 1.37 | ✗ | ✓ |
|
||||
|
||||
Note that the compatibility policy for this feature might change in the future.
|
||||
|
@ -208,7 +208,7 @@ error: missing documentation for a function
|
||||
|
||||
To fix the lint, add documentation to all items.
|
||||
|
||||
## single-use-lifetime
|
||||
## single-use-lifetimes
|
||||
|
||||
This lint detects lifetimes that are only used once. Some example code that
|
||||
triggers this lint:
|
||||
|
@ -311,19 +311,6 @@ When `rustdoc` receives this flag, it will print an extra "Version (version)" in
|
||||
the crate root's docs. You can use this flag to differentiate between different versions of your
|
||||
library's documentation.
|
||||
|
||||
### `--linker`: control the linker used for documentation tests
|
||||
|
||||
Using this flag looks like this:
|
||||
|
||||
```bash
|
||||
$ rustdoc --test src/lib.rs -Z unstable-options --linker foo
|
||||
$ rustdoc --test README.md -Z unstable-options --linker foo
|
||||
```
|
||||
|
||||
When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables
|
||||
before running them. This flag can be used to change the linker used on these executables. It's
|
||||
equivalent to passing `-C linker=foo` to `rustc`.
|
||||
|
||||
### `--sort-modules-by-appearance`: control how items on module pages are sorted
|
||||
|
||||
Using this flag looks like this:
|
||||
@ -484,3 +471,53 @@ Some methodology notes about what rustdoc counts in this metric:
|
||||
|
||||
Public items that are not documented can be seen with the built-in `missing_docs` lint. Private
|
||||
items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint.
|
||||
|
||||
### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests
|
||||
|
||||
Using this flag looks like this:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores
|
||||
```
|
||||
|
||||
This flag allows you to tag doctests with compiltest style `ignore-foo` filters that prevent
|
||||
rustdoc from running that test if the target triple string contains foo. For example:
|
||||
|
||||
```rust
|
||||
///```ignore-foo,ignore-bar
|
||||
///assert!(2 == 2);
|
||||
///```
|
||||
struct Foo;
|
||||
```
|
||||
|
||||
This will not be run when the build target is `super-awesome-foo` or `less-bar-awesome`.
|
||||
If the flag is not enabled, then rustdoc will consume the filter, but do nothing with it, and
|
||||
the above example will be run for all targets.
|
||||
If you want to preserve backwards compatibility for older versions of rustdoc, you can use
|
||||
|
||||
```rust
|
||||
///```ignore,ignore-foo
|
||||
///assert!(2 == 2);
|
||||
///```
|
||||
struct Foo;
|
||||
```
|
||||
|
||||
In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will
|
||||
override `ignore`.
|
||||
|
||||
### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it
|
||||
|
||||
Using thses options looks like this:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --runtool runner --runtool-arg --do-thing --runtool-arg --do-other-thing
|
||||
```
|
||||
|
||||
These options can be used to run the doctest under a program, and also pass arguments to
|
||||
that program. For example, if you want to run your doctests under valgrind you might run
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --runtool valgrind
|
||||
```
|
||||
|
||||
Another use case would be to run a test inside an emulator, or through a Virtual Machine.
|
||||
|
@ -1,27 +0,0 @@
|
||||
# `param_attrs`
|
||||
|
||||
The tracking issue for this feature is: [#60406]
|
||||
|
||||
[#60406]: https://github.com/rust-lang/rust/issues/60406
|
||||
|
||||
Allow attributes in formal function parameter position so external tools and compiler internals can
|
||||
take advantage of the additional information that the parameters provide.
|
||||
|
||||
Enables finer conditional compilation with `#[cfg(..)]` and linting control of variables. Moreover,
|
||||
opens the path to richer DSLs created by users.
|
||||
|
||||
------------------------
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
#![feature(param_attrs)]
|
||||
|
||||
fn len(
|
||||
#[cfg(windows)] slice: &[u16],
|
||||
#[cfg(not(windows))] slice: &[u8],
|
||||
) -> usize
|
||||
{
|
||||
slice.len()
|
||||
}
|
||||
```
|
@ -57,12 +57,12 @@ extern crate rustc;
|
||||
extern crate rustc_driver;
|
||||
|
||||
use syntax::parse::token::{self, Token};
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::tokenstream::{TokenTree, TokenStream};
|
||||
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
|
||||
use syntax_pos::Span;
|
||||
use rustc_driver::plugin::Registry;
|
||||
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
|
||||
-> Box<dyn MacResult + 'static> {
|
||||
|
||||
static NUMERALS: &'static [(&'static str, usize)] = &[
|
||||
@ -78,7 +78,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
|
||||
let text = match args[0] {
|
||||
let text = match args.into_trees().next().unwrap() {
|
||||
TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
|
||||
_ => {
|
||||
cx.span_err(sp, "argument should be a single identifier");
|
||||
|
@ -14,6 +14,8 @@ TEST_DIR = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
|
||||
|
||||
TEMPLATE = """\
|
||||
// ignore-x86
|
||||
// ^ due to stderr output differences
|
||||
// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
|
||||
|
||||
{error_deriving}
|
||||
|
@ -25,9 +25,9 @@ SourceDir=.\
|
||||
OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD}
|
||||
DefaultDirName={sd}\Rust
|
||||
|
||||
Compression=lzma2/ultra
|
||||
InternalCompressLevel=ultra
|
||||
SolidCompression=true
|
||||
Compression=lzma2/normal
|
||||
InternalCompressLevel=normal
|
||||
SolidCompression=no
|
||||
|
||||
ChangesEnvironment=true
|
||||
ChangesAssociations=no
|
||||
|
@ -152,7 +152,7 @@
|
||||
</Upgrade>
|
||||
|
||||
<!-- Specifies a single cab file to be embedded in the installer's .msi. -->
|
||||
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
|
||||
<MediaTemplate EmbedCab="yes" CompressionLevel="mszip" />
|
||||
|
||||
<!-- Send a WM_SETTINGCHANGE message to tell processes like explorer to update their
|
||||
environments so any new command prompts get the updated %PATH% -->
|
||||
|
@ -45,7 +45,10 @@ def normalize_whitespace(s):
|
||||
|
||||
def breakpoint_callback(frame, bp_loc, dict):
|
||||
"""This callback is registered with every breakpoint and makes sure that the
|
||||
frame containing the breakpoint location is selected"""
|
||||
frame containing the breakpoint location is selected """
|
||||
|
||||
# HACK(eddyb) print a newline to avoid continuing an unfinished line.
|
||||
print("")
|
||||
print("Hit breakpoint " + str(bp_loc))
|
||||
|
||||
# Select the frame and the thread containing it
|
||||
|
@ -15,113 +15,7 @@ const buffer = fs.readFileSync(process.argv[2]);
|
||||
Error.stackTraceLimit = 20;
|
||||
|
||||
let m = new WebAssembly.Module(buffer);
|
||||
|
||||
let memory = null;
|
||||
|
||||
function viewstruct(data, fields) {
|
||||
return new Uint32Array(memory.buffer).subarray(data/4, data/4 + fields);
|
||||
}
|
||||
|
||||
function copystr(a, b) {
|
||||
let view = new Uint8Array(memory.buffer).subarray(a, a + b);
|
||||
return String.fromCharCode.apply(null, view);
|
||||
}
|
||||
|
||||
function syscall_write([fd, ptr, len]) {
|
||||
let s = copystr(ptr, len);
|
||||
switch (fd) {
|
||||
case 1: process.stdout.write(s); break;
|
||||
case 2: process.stderr.write(s); break;
|
||||
}
|
||||
}
|
||||
|
||||
function syscall_exit([code]) {
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function syscall_args(params) {
|
||||
let [ptr, len] = params;
|
||||
|
||||
// Calculate total required buffer size
|
||||
let totalLen = -1;
|
||||
for (let i = 2; i < process.argv.length; ++i) {
|
||||
totalLen += Buffer.byteLength(process.argv[i]) + 1;
|
||||
}
|
||||
if (totalLen < 0) { totalLen = 0; }
|
||||
params[2] = totalLen;
|
||||
|
||||
// If buffer is large enough, copy data
|
||||
if (len >= totalLen) {
|
||||
let view = new Uint8Array(memory.buffer);
|
||||
for (let i = 2; i < process.argv.length; ++i) {
|
||||
let value = process.argv[i];
|
||||
Buffer.from(value).copy(view, ptr);
|
||||
ptr += Buffer.byteLength(process.argv[i]) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function syscall_getenv(params) {
|
||||
let [keyPtr, keyLen, valuePtr, valueLen] = params;
|
||||
|
||||
let key = copystr(keyPtr, keyLen);
|
||||
let value = process.env[key];
|
||||
|
||||
if (value == null) {
|
||||
params[4] = 0xFFFFFFFF;
|
||||
} else {
|
||||
let view = new Uint8Array(memory.buffer);
|
||||
let totalLen = Buffer.byteLength(value);
|
||||
params[4] = totalLen;
|
||||
if (valueLen >= totalLen) {
|
||||
Buffer.from(value).copy(view, valuePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function syscall_time(params) {
|
||||
let t = Date.now();
|
||||
let secs = Math.floor(t / 1000);
|
||||
let millis = t % 1000;
|
||||
params[1] = Math.floor(secs / 0x100000000);
|
||||
params[2] = secs % 0x100000000;
|
||||
params[3] = Math.floor(millis * 1000000);
|
||||
}
|
||||
|
||||
let imports = {};
|
||||
imports.env = {
|
||||
// These are generated by LLVM itself for various intrinsic calls. Hopefully
|
||||
// one day this is not necessary and something will automatically do this.
|
||||
fmod: function(x, y) { return x % y; },
|
||||
exp2: function(x) { return Math.pow(2, x); },
|
||||
exp2f: function(x) { return Math.pow(2, x); },
|
||||
ldexp: function(x, y) { return x * Math.pow(2, y); },
|
||||
ldexpf: function(x, y) { return x * Math.pow(2, y); },
|
||||
sin: Math.sin,
|
||||
sinf: Math.sin,
|
||||
cos: Math.cos,
|
||||
cosf: Math.cos,
|
||||
log: Math.log,
|
||||
log2: Math.log2,
|
||||
log10: Math.log10,
|
||||
log10f: Math.log10,
|
||||
|
||||
rust_wasm_syscall: function(index, data) {
|
||||
switch (index) {
|
||||
case 1: syscall_write(viewstruct(data, 3)); return true;
|
||||
case 2: syscall_exit(viewstruct(data, 1)); return true;
|
||||
case 3: syscall_args(viewstruct(data, 3)); return true;
|
||||
case 4: syscall_getenv(viewstruct(data, 5)); return true;
|
||||
case 6: syscall_time(viewstruct(data, 4)); return true;
|
||||
default:
|
||||
console.log("Unsupported syscall: " + index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let instance = new WebAssembly.Instance(m, imports);
|
||||
memory = instance.exports.memory;
|
||||
let instance = new WebAssembly.Instance(m, {});
|
||||
try {
|
||||
instance.exports.main();
|
||||
} catch (e) {
|
||||
|
@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
|
||||
#[stable(feature = "global_alloc", since = "1.28.0")]
|
||||
#[rustc_allocator_nounwind]
|
||||
pub fn handle_alloc_error(layout: Layout) -> ! {
|
||||
#[allow(improper_ctypes)]
|
||||
#[cfg_attr(bootstrap, allow(improper_ctypes))]
|
||||
extern "Rust" {
|
||||
#[lang = "oom"]
|
||||
fn oom_impl(layout: Layout) -> !;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
use core::borrow::Borrow;
|
||||
use core::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
use core::cmp::max;
|
||||
use core::cmp::{max, min};
|
||||
use core::fmt::{self, Debug};
|
||||
use core::iter::{Peekable, FromIterator, FusedIterator};
|
||||
use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds};
|
||||
@ -187,8 +187,8 @@ pub struct Intersection<'a, T: 'a> {
|
||||
}
|
||||
enum IntersectionInner<'a, T: 'a> {
|
||||
Stitch {
|
||||
small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets
|
||||
other_iter: Iter<'a, T>,
|
||||
a: Iter<'a, T>,
|
||||
b: Iter<'a, T>,
|
||||
},
|
||||
Search {
|
||||
small_iter: Iter<'a, T>,
|
||||
@ -201,12 +201,12 @@ impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match &self.inner {
|
||||
IntersectionInner::Stitch {
|
||||
small_iter,
|
||||
other_iter,
|
||||
a,
|
||||
b,
|
||||
} => f
|
||||
.debug_tuple("Intersection")
|
||||
.field(&small_iter)
|
||||
.field(&other_iter)
|
||||
.field(&a)
|
||||
.field(&b)
|
||||
.finish(),
|
||||
IntersectionInner::Search {
|
||||
small_iter,
|
||||
@ -397,8 +397,8 @@ impl<T: Ord> BTreeSet<T> {
|
||||
// Iterate both sets jointly, spotting matches along the way.
|
||||
Intersection {
|
||||
inner: IntersectionInner::Stitch {
|
||||
small_iter: small.iter(),
|
||||
other_iter: other.iter(),
|
||||
a: small.iter(),
|
||||
b: other.iter(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
@ -1221,11 +1221,11 @@ impl<T> Clone for Intersection<'_, T> {
|
||||
Intersection {
|
||||
inner: match &self.inner {
|
||||
IntersectionInner::Stitch {
|
||||
small_iter,
|
||||
other_iter,
|
||||
a,
|
||||
b,
|
||||
} => IntersectionInner::Stitch {
|
||||
small_iter: small_iter.clone(),
|
||||
other_iter: other_iter.clone(),
|
||||
a: a.clone(),
|
||||
b: b.clone(),
|
||||
},
|
||||
IntersectionInner::Search {
|
||||
small_iter,
|
||||
@ -1245,16 +1245,16 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
|
||||
fn next(&mut self) -> Option<&'a T> {
|
||||
match &mut self.inner {
|
||||
IntersectionInner::Stitch {
|
||||
small_iter,
|
||||
other_iter,
|
||||
a,
|
||||
b,
|
||||
} => {
|
||||
let mut small_next = small_iter.next()?;
|
||||
let mut other_next = other_iter.next()?;
|
||||
let mut a_next = a.next()?;
|
||||
let mut b_next = b.next()?;
|
||||
loop {
|
||||
match Ord::cmp(small_next, other_next) {
|
||||
Less => small_next = small_iter.next()?,
|
||||
Greater => other_next = other_iter.next()?,
|
||||
Equal => return Some(small_next),
|
||||
match Ord::cmp(a_next, b_next) {
|
||||
Less => a_next = a.next()?,
|
||||
Greater => b_next = b.next()?,
|
||||
Equal => return Some(a_next),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1272,7 +1272,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let min_len = match &self.inner {
|
||||
IntersectionInner::Stitch { small_iter, .. } => small_iter.len(),
|
||||
IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
|
||||
IntersectionInner::Search { small_iter, .. } => small_iter.len(),
|
||||
};
|
||||
(0, Some(min_len))
|
||||
|
@ -276,7 +276,7 @@ impl<T> LinkedList<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
LinkedList {
|
||||
head: None,
|
||||
tail: None,
|
||||
|
@ -102,8 +102,8 @@ fn test_append() {
|
||||
assert_eq!(m.pop_front(), Some(elt))
|
||||
}
|
||||
assert_eq!(n.len(), 0);
|
||||
// let's make sure it's working properly, since we
|
||||
// did some direct changes to private members
|
||||
// Let's make sure it's working properly, since we
|
||||
// did some direct changes to private members.
|
||||
n.push_back(3);
|
||||
assert_eq!(n.len(), 1);
|
||||
assert_eq!(n.pop_front(), Some(3));
|
||||
|
@ -1810,7 +1810,7 @@ impl<T> VecDeque<T> {
|
||||
other
|
||||
}
|
||||
|
||||
/// Moves all the elements of `other` into `Self`, leaving `other` empty.
|
||||
/// Moves all the elements of `other` into `self`, leaving `other` empty.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -1847,7 +1847,7 @@ impl<T> VecDeque<T> {
|
||||
///
|
||||
/// let mut buf = VecDeque::new();
|
||||
/// buf.extend(1..5);
|
||||
/// buf.retain(|&x| x%2 == 0);
|
||||
/// buf.retain(|&x| x % 2 == 0);
|
||||
/// assert_eq!(buf, [2, 4]);
|
||||
/// ```
|
||||
///
|
||||
|
@ -117,7 +117,7 @@
|
||||
#![feature(allocator_internals)]
|
||||
#![feature(on_unimplemented)]
|
||||
#![feature(rustc_const_unstable)]
|
||||
#![feature(const_vec_new)]
|
||||
#![cfg_attr(bootstrap, feature(const_vec_new))]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
@ -171,3 +171,9 @@ pub mod vec;
|
||||
mod std {
|
||||
pub use core::ops; // RangeFull
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "liballoc_internals", issue = "0", reason = "implementation detail")]
|
||||
pub mod __export {
|
||||
pub use core::format_args;
|
||||
}
|
||||
|
@ -98,5 +98,5 @@ macro_rules! vec {
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
macro_rules! format {
|
||||
($($arg:tt)*) => ($crate::fmt::format(::core::format_args!($($arg)*)))
|
||||
($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
|
||||
}
|
||||
|
@ -19,26 +19,26 @@ mod tests;
|
||||
/// involved. This type is excellent for building your own data structures like Vec and VecDeque.
|
||||
/// In particular:
|
||||
///
|
||||
/// * Produces Unique::empty() on zero-sized types
|
||||
/// * Produces Unique::empty() on zero-length allocations
|
||||
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
|
||||
/// * Guards against 32-bit systems allocating more than isize::MAX bytes
|
||||
/// * Guards against overflowing your length
|
||||
/// * Aborts on OOM or calls handle_alloc_error as applicable
|
||||
/// * Avoids freeing Unique::empty()
|
||||
/// * Contains a ptr::Unique and thus endows the user with all related benefits
|
||||
/// * Produces `Unique::empty()` on zero-sized types.
|
||||
/// * Produces `Unique::empty()` on zero-length allocations.
|
||||
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
|
||||
/// * Guards against 32-bit systems allocating more than isize::MAX bytes.
|
||||
/// * Guards against overflowing your length.
|
||||
/// * Aborts on OOM or calls `handle_alloc_error` as applicable.
|
||||
/// * Avoids freeing `Unique::empty()`.
|
||||
/// * Contains a `ptr::Unique` and thus endows the user with all related benefits.
|
||||
///
|
||||
/// This type does not in anyway inspect the memory that it manages. When dropped it *will*
|
||||
/// free its memory, but it *won't* try to Drop its contents. It is up to the user of RawVec
|
||||
/// to handle the actual things *stored* inside of a RawVec.
|
||||
/// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec`
|
||||
/// to handle the actual things *stored* inside of a `RawVec`.
|
||||
///
|
||||
/// Note that a RawVec always forces its capacity to be usize::MAX for zero-sized types.
|
||||
/// This enables you to use capacity growing logic catch the overflows in your length
|
||||
/// Note that a `RawVec` always forces its capacity to be `usize::MAX` for zero-sized types.
|
||||
/// This enables you to use capacity-growing logic catch the overflows in your length
|
||||
/// that might occur with zero-sized types.
|
||||
///
|
||||
/// However this means that you need to be careful when round-tripping this type
|
||||
/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`,
|
||||
/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
|
||||
/// The above means that you need to be careful when round-tripping this type with a
|
||||
/// `Box<[T]>`, since `capacity()` won't yield the length. However, `with_capacity`,
|
||||
/// `shrink_to_fit`, and `from_box` will actually set `RawVec`'s private capacity
|
||||
/// field. This allows zero-sized types to not be special-cased by consumers of
|
||||
/// this type.
|
||||
#[allow(missing_debug_implementations)]
|
||||
@ -49,14 +49,14 @@ pub struct RawVec<T, A: Alloc = Global> {
|
||||
}
|
||||
|
||||
impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// Like `new` but parameterized over the choice of allocator for
|
||||
/// the returned RawVec.
|
||||
/// Like `new`, but parameterized over the choice of allocator for
|
||||
/// the returned `RawVec`.
|
||||
pub const fn new_in(a: A) -> Self {
|
||||
// !0 is usize::MAX. This branch should be stripped at compile time.
|
||||
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`
|
||||
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
|
||||
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
|
||||
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
||||
|
||||
// Unique::empty() doubles as "unallocated" and "zero-sized allocation"
|
||||
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
|
||||
RawVec {
|
||||
ptr: Unique::empty(),
|
||||
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
|
||||
@ -65,15 +65,15 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `with_capacity` but parameterized over the choice of
|
||||
/// allocator for the returned RawVec.
|
||||
/// Like `with_capacity`, but parameterized over the choice of
|
||||
/// allocator for the returned `RawVec`.
|
||||
#[inline]
|
||||
pub fn with_capacity_in(capacity: usize, a: A) -> Self {
|
||||
RawVec::allocate_in(capacity, false, a)
|
||||
}
|
||||
|
||||
/// Like `with_capacity_zeroed` but parameterized over the choice
|
||||
/// of allocator for the returned RawVec.
|
||||
/// Like `with_capacity_zeroed`, but parameterized over the choice
|
||||
/// of allocator for the returned `RawVec`.
|
||||
#[inline]
|
||||
pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self {
|
||||
RawVec::allocate_in(capacity, true, a)
|
||||
@ -86,7 +86,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
|
||||
alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());
|
||||
|
||||
// handles ZSTs and `capacity = 0` alike
|
||||
// Handles ZSTs and `capacity == 0` alike.
|
||||
let ptr = if alloc_size == 0 {
|
||||
NonNull::<T>::dangling()
|
||||
} else {
|
||||
@ -113,20 +113,45 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
|
||||
impl<T> RawVec<T, Global> {
|
||||
/// Creates the biggest possible RawVec (on the system heap)
|
||||
/// without allocating. If T has positive size, then this makes a
|
||||
/// RawVec with capacity 0. If T has 0 size, then it makes a
|
||||
/// RawVec with capacity `usize::MAX`. Useful for implementing
|
||||
/// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform
|
||||
/// to `min_const_fn` and so they cannot be called in `min_const_fn`s either.
|
||||
///
|
||||
/// If you change `RawVec<T>::new` or dependencies, please take care to not
|
||||
/// introduce anything that would truly violate `min_const_fn`.
|
||||
///
|
||||
/// NOTE: We could avoid this hack and check conformance with some
|
||||
/// `#[rustc_force_min_const_fn]` attribute which requires conformance
|
||||
/// with `min_const_fn` but does not necessarily allow calling it in
|
||||
/// `stable(...) const fn` / user code not enabling `foo` when
|
||||
/// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
|
||||
pub const NEW: Self = Self::new();
|
||||
|
||||
/// Creates the biggest possible `RawVec` (on the system heap)
|
||||
/// without allocating. If `T` has positive size, then this makes a
|
||||
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
|
||||
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
|
||||
/// delayed allocation.
|
||||
pub const fn new() -> Self {
|
||||
Self::new_in(Global)
|
||||
// FIXME(Centril): Reintegrate this with `fn new_in` when we can.
|
||||
|
||||
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
|
||||
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
|
||||
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
||||
|
||||
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
|
||||
RawVec {
|
||||
ptr: Unique::empty(),
|
||||
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
|
||||
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
|
||||
a: Global,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a RawVec (on the system heap) with exactly the
|
||||
/// Creates a `RawVec` (on the system heap) with exactly the
|
||||
/// capacity and alignment requirements for a `[T; capacity]`. This is
|
||||
/// equivalent to calling RawVec::new when `capacity` is 0 or T is
|
||||
/// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is
|
||||
/// zero-sized. Note that if `T` is zero-sized this means you will
|
||||
/// *not* get a RawVec with the requested capacity!
|
||||
/// *not* get a `RawVec` with the requested capacity.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -136,13 +161,13 @@ impl<T> RawVec<T, Global> {
|
||||
///
|
||||
/// # Aborts
|
||||
///
|
||||
/// Aborts on OOM
|
||||
/// Aborts on OOM.
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
RawVec::allocate_in(capacity, false, Global)
|
||||
}
|
||||
|
||||
/// Like `with_capacity` but guarantees the buffer is zeroed.
|
||||
/// Like `with_capacity`, but guarantees the buffer is zeroed.
|
||||
#[inline]
|
||||
pub fn with_capacity_zeroed(capacity: usize) -> Self {
|
||||
RawVec::allocate_in(capacity, true, Global)
|
||||
@ -150,13 +175,13 @@ impl<T> RawVec<T, Global> {
|
||||
}
|
||||
|
||||
impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// Reconstitutes a RawVec from a pointer, capacity, and allocator.
|
||||
/// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
|
||||
///
|
||||
/// # Undefined Behavior
|
||||
///
|
||||
/// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The
|
||||
/// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
||||
/// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.
|
||||
/// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`.
|
||||
/// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
||||
/// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed.
|
||||
pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
|
||||
RawVec {
|
||||
ptr: Unique::new_unchecked(ptr),
|
||||
@ -167,13 +192,13 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
|
||||
impl<T> RawVec<T, Global> {
|
||||
/// Reconstitutes a RawVec from a pointer, capacity.
|
||||
/// Reconstitutes a `RawVec` from a pointer and capacity.
|
||||
///
|
||||
/// # Undefined Behavior
|
||||
///
|
||||
/// The ptr must be allocated (on the system heap), and with the given capacity. The
|
||||
/// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
||||
/// If the ptr and capacity come from a RawVec, then this is guaranteed.
|
||||
/// The `ptr` must be allocated (on the system heap), and with the given `capacity`.
|
||||
/// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
||||
/// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed.
|
||||
pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
|
||||
RawVec {
|
||||
ptr: Unique::new_unchecked(ptr),
|
||||
@ -194,7 +219,7 @@ impl<T> RawVec<T, Global> {
|
||||
|
||||
impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// Gets a raw pointer to the start of the allocation. Note that this is
|
||||
/// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must
|
||||
/// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
|
||||
/// be careful.
|
||||
pub fn ptr(&self) -> *mut T {
|
||||
self.ptr.as_ptr()
|
||||
@ -212,12 +237,12 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the allocator backing this RawVec.
|
||||
/// Returns a shared reference to the allocator backing this `RawVec`.
|
||||
pub fn alloc(&self) -> &A {
|
||||
&self.a
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the allocator backing this RawVec.
|
||||
/// Returns a mutable reference to the allocator backing this `RawVec`.
|
||||
pub fn alloc_mut(&mut self) -> &mut A {
|
||||
&mut self.a
|
||||
}
|
||||
@ -247,7 +272,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// * Panics if T is zero-sized on the assumption that you managed to exhaust
|
||||
/// * Panics if `T` is zero-sized on the assumption that you managed to exhaust
|
||||
/// all `usize::MAX` slots in your imaginary buffer.
|
||||
/// * Panics on 32-bit platforms if the requested capacity exceeds
|
||||
/// `isize::MAX` bytes.
|
||||
@ -290,20 +315,20 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
unsafe {
|
||||
let elem_size = mem::size_of::<T>();
|
||||
|
||||
// since we set the capacity to usize::MAX when elem_size is
|
||||
// 0, getting to here necessarily means the RawVec is overfull.
|
||||
// Since we set the capacity to `usize::MAX` when `elem_size` is
|
||||
// 0, getting to here necessarily means the `RawVec` is overfull.
|
||||
assert!(elem_size != 0, "capacity overflow");
|
||||
|
||||
let (new_cap, uniq) = match self.current_layout() {
|
||||
Some(cur) => {
|
||||
// Since we guarantee that we never allocate more than
|
||||
// isize::MAX bytes, `elem_size * self.cap <= isize::MAX` as
|
||||
// `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as
|
||||
// a precondition, so this can't overflow. Additionally the
|
||||
// alignment will never be too large as to "not be
|
||||
// satisfiable", so `Layout::from_size_align` will always
|
||||
// return `Some`.
|
||||
//
|
||||
// tl;dr; we bypass runtime checks due to dynamic assertions
|
||||
// TL;DR, we bypass runtime checks due to dynamic assertions
|
||||
// in this module, allowing us to use
|
||||
// `from_size_align_unchecked`.
|
||||
let new_cap = 2 * self.cap;
|
||||
@ -320,8 +345,8 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// skip to 4 because tiny Vec's are dumb; but not if that
|
||||
// would cause overflow
|
||||
// Skip to 4 because tiny `Vec`'s are dumb; but not if that
|
||||
// would cause overflow.
|
||||
let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
|
||||
match self.a.alloc_array::<T>(new_cap) {
|
||||
Ok(ptr) => (new_cap, ptr.into()),
|
||||
@ -342,7 +367,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// * Panics if T is zero-sized on the assumption that you managed to exhaust
|
||||
/// * Panics if `T` is zero-sized on the assumption that you managed to exhaust
|
||||
/// all `usize::MAX` slots in your imaginary buffer.
|
||||
/// * Panics on 32-bit platforms if the requested capacity exceeds
|
||||
/// `isize::MAX` bytes.
|
||||
@ -356,15 +381,15 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
None => return false, // nothing to double
|
||||
};
|
||||
|
||||
// since we set the capacity to usize::MAX when elem_size is
|
||||
// 0, getting to here necessarily means the RawVec is overfull.
|
||||
// Since we set the capacity to `usize::MAX` when `elem_size` is
|
||||
// 0, getting to here necessarily means the `RawVec` is overfull.
|
||||
assert!(elem_size != 0, "capacity overflow");
|
||||
|
||||
// Since we guarantee that we never allocate more than isize::MAX
|
||||
// Since we guarantee that we never allocate more than `isize::MAX`
|
||||
// bytes, `elem_size * self.cap <= isize::MAX` as a precondition, so
|
||||
// this can't overflow.
|
||||
//
|
||||
// Similarly like with `double` above we can go straight to
|
||||
// Similarly to with `double` above, we can go straight to
|
||||
// `Layout::from_size_align_unchecked` as we know this won't
|
||||
// overflow and the alignment is sufficiently small.
|
||||
let new_cap = 2 * self.cap;
|
||||
@ -409,7 +434,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
///
|
||||
/// # Aborts
|
||||
///
|
||||
/// Aborts on OOM
|
||||
/// Aborts on OOM.
|
||||
pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
|
||||
match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) {
|
||||
Err(CapacityOverflow) => capacity_overflow(),
|
||||
@ -424,7 +449,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize)
|
||||
-> Result<usize, TryReserveError> {
|
||||
|
||||
// Nothing we can really do about these checks :(
|
||||
// Nothing we can really do about these checks, sadly.
|
||||
let required_cap = used_capacity.checked_add(needed_extra_capacity)
|
||||
.ok_or(CapacityOverflow)?;
|
||||
// Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
|
||||
@ -459,7 +484,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
///
|
||||
/// # Aborts
|
||||
///
|
||||
/// Aborts on OOM
|
||||
/// Aborts on OOM.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -538,7 +563,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
|
||||
// Here, `cap < used_capacity + needed_extra_capacity <= new_cap`
|
||||
// (regardless of whether `self.cap - used_capacity` wrapped).
|
||||
// Therefore we can safely call grow_in_place.
|
||||
// Therefore, we can safely call `grow_in_place`.
|
||||
|
||||
let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
|
||||
// FIXME: may crash and burn on over-reserve
|
||||
@ -576,14 +601,14 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
return;
|
||||
}
|
||||
|
||||
// This check is my waterloo; it's the only thing Vec wouldn't have to do.
|
||||
// This check is my waterloo; it's the only thing `Vec` wouldn't have to do.
|
||||
assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
|
||||
|
||||
if amount == 0 {
|
||||
// We want to create a new zero-length vector within the
|
||||
// same allocator. We use ptr::write to avoid an
|
||||
// same allocator. We use `ptr::write` to avoid an
|
||||
// erroneous attempt to drop the contents, and we use
|
||||
// ptr::read to sidestep condition against destructuring
|
||||
// `ptr::read` to sidestep condition against destructuring
|
||||
// types that implement Drop.
|
||||
|
||||
unsafe {
|
||||
@ -600,7 +625,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
//
|
||||
// We also know that `self.cap` is greater than `amount`, and
|
||||
// consequently we don't need runtime checks for creating either
|
||||
// layout
|
||||
// layout.
|
||||
let old_size = elem_size * self.cap;
|
||||
let new_size = elem_size * amount;
|
||||
let align = mem::align_of::<T>();
|
||||
@ -653,7 +678,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Nothing we can really do about these checks :(
|
||||
// Nothing we can really do about these checks, sadly.
|
||||
let new_cap = match strategy {
|
||||
Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?,
|
||||
Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?,
|
||||
@ -692,7 +717,7 @@ impl<T> RawVec<T, Global> {
|
||||
/// Converts the entire buffer into `Box<[T]>`.
|
||||
///
|
||||
/// Note that this will correctly reconstitute any `cap` changes
|
||||
/// that may have been performed. (see description of type for details)
|
||||
/// that may have been performed. (See description of type for details.)
|
||||
///
|
||||
/// # Undefined Behavior
|
||||
///
|
||||
@ -700,7 +725,7 @@ impl<T> RawVec<T, Global> {
|
||||
/// the rules around uninitialized boxed values are not finalized yet,
|
||||
/// but until they are, it is advisable to avoid them.
|
||||
pub unsafe fn into_box(self) -> Box<[T]> {
|
||||
// NOTE: not calling `capacity()` here, actually using the real `cap` field!
|
||||
// NOTE: not calling `capacity()` here; actually using the real `cap` field!
|
||||
let slice = slice::from_raw_parts_mut(self.ptr(), self.cap);
|
||||
let output: Box<[T]> = Box::from_raw(slice);
|
||||
mem::forget(self);
|
||||
@ -709,7 +734,7 @@ impl<T> RawVec<T, Global> {
|
||||
}
|
||||
|
||||
impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// Frees the memory owned by the RawVec *without* trying to Drop its contents.
|
||||
/// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
|
||||
pub unsafe fn dealloc_buffer(&mut self) {
|
||||
let elem_size = mem::size_of::<T>();
|
||||
if elem_size != 0 {
|
||||
@ -721,22 +746,20 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
}
|
||||
|
||||
unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
|
||||
/// Frees the memory owned by the RawVec *without* trying to Drop its contents.
|
||||
/// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
|
||||
fn drop(&mut self) {
|
||||
unsafe { self.dealloc_buffer(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We need to guarantee the following:
|
||||
// * We don't ever allocate `> isize::MAX` byte-size objects
|
||||
// * We don't overflow `usize::MAX` and actually allocate too little
|
||||
// * We don't ever allocate `> isize::MAX` byte-size objects.
|
||||
// * We don't overflow `usize::MAX` and actually allocate too little.
|
||||
//
|
||||
// On 64-bit we just need to check for overflow since trying to allocate
|
||||
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
|
||||
// an extra guard for this in case we're running on a platform which can use
|
||||
// all 4GB in user-space. e.g., PAE or x32
|
||||
// all 4GB in user-space, e.g., PAE or x32.
|
||||
|
||||
#[inline]
|
||||
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
|
||||
@ -751,5 +774,5 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
|
||||
// ensure that the code generation related to these panics is minimal as there's
|
||||
// only one location which panics rather than a bunch throughout the module.
|
||||
fn capacity_overflow() -> ! {
|
||||
panic!("capacity overflow")
|
||||
panic!("capacity overflow");
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ fn allocator_param() {
|
||||
use crate::alloc::AllocErr;
|
||||
|
||||
// Writing a test of integration between third-party
|
||||
// allocators and RawVec is a little tricky because the RawVec
|
||||
// allocators and `RawVec` is a little tricky because the `RawVec`
|
||||
// API does not expose fallible allocation methods, so we
|
||||
// cannot check what happens when allocator is exhausted
|
||||
// (beyond detecting a panic).
|
||||
//
|
||||
// Instead, this just checks that the RawVec methods do at
|
||||
// Instead, this just checks that the `RawVec` methods do at
|
||||
// least go through the Allocator API when it reserves
|
||||
// storage.
|
||||
|
||||
@ -44,7 +44,7 @@ fn allocator_param() {
|
||||
fn reserve_does_not_overallocate() {
|
||||
{
|
||||
let mut v: RawVec<u32> = RawVec::new();
|
||||
// First `reserve` allocates like `reserve_exact`
|
||||
// First, `reserve` allocates like `reserve_exact`.
|
||||
v.reserve(0, 9);
|
||||
assert_eq!(9, v.capacity());
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ impl<T: ?Sized> Rc<T> {
|
||||
/// let x = Rc::from_raw(x_ptr);
|
||||
/// assert_eq!(&*x, "hello");
|
||||
///
|
||||
/// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe.
|
||||
/// // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.
|
||||
/// }
|
||||
///
|
||||
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
|
||||
@ -1832,8 +1832,9 @@ impl<T: ?Sized> Weak<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the two `Weak`s point to the same value (not just values
|
||||
/// that compare as equal).
|
||||
/// Returns `true` if the two `Weak`s point to the same value (not just
|
||||
/// values that compare as equal), or if both don't point to any value
|
||||
/// (because they were created with `Weak::new()`).
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
@ -1843,7 +1844,6 @@ impl<T: ?Sized> Weak<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_ptr_eq)]
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// let first_rc = Rc::new(5);
|
||||
@ -1861,7 +1861,6 @@ impl<T: ?Sized> Weak<T> {
|
||||
/// Comparing `Weak::new`.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_ptr_eq)]
|
||||
/// use std::rc::{Rc, Weak};
|
||||
///
|
||||
/// let first = Weak::new();
|
||||
@ -1873,7 +1872,7 @@ impl<T: ?Sized> Weak<T> {
|
||||
/// assert!(!first.ptr_eq(&third));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "weak_ptr_eq", issue = "55981")]
|
||||
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
|
||||
pub fn ptr_eq(&self, other: &Self) -> bool {
|
||||
self.ptr.as_ptr() == other.ptr.as_ptr()
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ impl String {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_string_new")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))]
|
||||
pub const fn new() -> String {
|
||||
String { vec: Vec::new() }
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ impl<T: ?Sized> Arc<T> {
|
||||
/// let x = Arc::from_raw(x_ptr);
|
||||
/// assert_eq!(&*x, "hello");
|
||||
///
|
||||
/// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
|
||||
/// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe.
|
||||
/// }
|
||||
///
|
||||
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
|
||||
@ -1550,19 +1550,18 @@ impl<T: ?Sized> Weak<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the two `Weak`s point to the same value (not just values
|
||||
/// that compare as equal).
|
||||
/// Returns `true` if the two `Weak`s point to the same value (not just
|
||||
/// values that compare as equal), or if both don't point to any value
|
||||
/// (because they were created with `Weak::new()`).
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Since this compares pointers it means that `Weak::new()` will equal each
|
||||
/// other, even though they don't point to any value.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_ptr_eq)]
|
||||
/// use std::sync::Arc;
|
||||
///
|
||||
/// let first_rc = Arc::new(5);
|
||||
@ -1580,7 +1579,6 @@ impl<T: ?Sized> Weak<T> {
|
||||
/// Comparing `Weak::new`.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_ptr_eq)]
|
||||
/// use std::sync::{Arc, Weak};
|
||||
///
|
||||
/// let first = Weak::new();
|
||||
@ -1592,7 +1590,7 @@ impl<T: ?Sized> Weak<T> {
|
||||
/// assert!(!first.ptr_eq(&third));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "weak_ptr_eq", issue = "55981")]
|
||||
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
|
||||
pub fn ptr_eq(&self, other: &Self) -> bool {
|
||||
self.ptr.as_ptr() == other.ptr.as_ptr()
|
||||
}
|
||||
|
@ -90,6 +90,17 @@ fn test_intersection() {
|
||||
&[1, 3, 11, 77, 103]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_size_hint() {
|
||||
let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
|
||||
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
|
||||
let mut iter = x.intersection(&y);
|
||||
assert_eq!(iter.size_hint(), (0, Some(2)));
|
||||
assert_eq!(iter.next(), Some(&3));
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difference() {
|
||||
fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
|
||||
|
@ -291,6 +291,7 @@ use crate::raw_vec::RawVec;
|
||||
/// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
|
||||
/// [owned slice]: ../../std/boxed/struct.Box.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(all(not(bootstrap), not(test)), rustc_diagnostic_item = "vec_type")]
|
||||
pub struct Vec<T> {
|
||||
buf: RawVec<T>,
|
||||
len: usize,
|
||||
@ -313,10 +314,10 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_vec_new")]
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))]
|
||||
pub const fn new() -> Vec<T> {
|
||||
Vec {
|
||||
buf: RawVec::new(),
|
||||
buf: RawVec::NEW,
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
@ -684,21 +685,25 @@ impl<T> Vec<T> {
|
||||
/// [`drain`]: #method.drain
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn truncate(&mut self, len: usize) {
|
||||
let current_len = self.len;
|
||||
unsafe {
|
||||
let mut ptr = self.as_mut_ptr().add(self.len);
|
||||
// Set the final length at the end, keeping in mind that
|
||||
// dropping an element might panic. Works around a missed
|
||||
// optimization, as seen in the following issue:
|
||||
// https://github.com/rust-lang/rust/issues/51802
|
||||
let mut local_len = SetLenOnDrop::new(&mut self.len);
|
||||
if mem::needs_drop::<T>() {
|
||||
let current_len = self.len;
|
||||
unsafe {
|
||||
let mut ptr = self.as_mut_ptr().add(self.len);
|
||||
// Set the final length at the end, keeping in mind that
|
||||
// dropping an element might panic. Works around a missed
|
||||
// optimization, as seen in the following issue:
|
||||
// https://github.com/rust-lang/rust/issues/51802
|
||||
let mut local_len = SetLenOnDrop::new(&mut self.len);
|
||||
|
||||
// drop any extra elements
|
||||
for _ in len..current_len {
|
||||
local_len.decrement_len(1);
|
||||
ptr = ptr.offset(-1);
|
||||
ptr::drop_in_place(ptr);
|
||||
// drop any extra elements
|
||||
for _ in len..current_len {
|
||||
local_len.decrement_len(1);
|
||||
ptr = ptr.offset(-1);
|
||||
ptr::drop_in_place(ptr);
|
||||
}
|
||||
}
|
||||
} else if len <= self.len {
|
||||
self.len = len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,13 +153,13 @@ impl dyn Any {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is<T: Any>(&self) -> bool {
|
||||
// Get TypeId of the type this function is instantiated with
|
||||
// Get `TypeId` of the type this function is instantiated with.
|
||||
let t = TypeId::of::<T>();
|
||||
|
||||
// Get TypeId of the type in the trait object
|
||||
// Get `TypeId` of the type in the trait object.
|
||||
let concrete = self.type_id();
|
||||
|
||||
// Compare both TypeIds on equality
|
||||
// Compare both `TypeId`s on equality.
|
||||
t == concrete
|
||||
}
|
||||
|
||||
|
45
src/libcore/bool.rs
Normal file
45
src/libcore/bool.rs
Normal file
@ -0,0 +1,45 @@
|
||||
//! impl bool {}
|
||||
|
||||
#[cfg(not(boostrap_stdarch_ignore_this))]
|
||||
#[lang = "bool"]
|
||||
impl bool {
|
||||
/// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_option)]
|
||||
///
|
||||
/// assert_eq!(false.then(0), None);
|
||||
/// assert_eq!(true.then(0), Some(0));
|
||||
/// ```
|
||||
#[unstable(feature = "bool_to_option", issue = "64260")]
|
||||
#[inline]
|
||||
pub fn then<T>(self, t: T) -> Option<T> {
|
||||
if self {
|
||||
Some(t)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bool_to_option)]
|
||||
///
|
||||
/// assert_eq!(false.then_with(|| 0), None);
|
||||
/// assert_eq!(true.then_with(|| 0), Some(0));
|
||||
/// ```
|
||||
#[unstable(feature = "bool_to_option", issue = "64260")]
|
||||
#[inline]
|
||||
pub fn then_with<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
||||
if self {
|
||||
Some(f())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -547,29 +547,6 @@ impl char {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// `XID_Start` is a Unicode Derived Property specified in
|
||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
||||
#[unstable(feature = "unicode_internals", issue = "0")]
|
||||
pub fn is_xid_start(self) -> bool {
|
||||
derived_property::XID_Start(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// `XID_Continue` is a Unicode Derived Property specified in
|
||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||
/// mostly similar to `ID_Continue` but modified for closure under NFKx.
|
||||
#[unstable(feature = "unicode_internals", issue = "0")]
|
||||
#[inline]
|
||||
pub fn is_xid_continue(self) -> bool {
|
||||
derived_property::XID_Continue(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` is lowercase.
|
||||
///
|
||||
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core
|
||||
|
@ -9,14 +9,22 @@
|
||||
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
|
||||
//! partial orderings between values, respectively. Implementing them overloads
|
||||
//! the `<`, `<=`, `>`, and `>=` operators.
|
||||
//! * [`Ordering`][cmp::Ordering] is an enum returned by the
|
||||
//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
|
||||
//! an ordering.
|
||||
//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
|
||||
//! [`Ord`] and allow you to find the maximum or minimum of two values.
|
||||
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
|
||||
//! [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
|
||||
//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
|
||||
//! to find the maximum or minimum of two values.
|
||||
//!
|
||||
//! For more details, see the respective documentation of each item in the list.
|
||||
//!
|
||||
//! [`Eq`]: trait.Eq.html
|
||||
//! [`PartialEq`]: trait.PartialEq.html
|
||||
//! [`Ord`]: trait.Ord.html
|
||||
//! [`PartialOrd`]: trait.PartialOrd.html
|
||||
//! [`Ordering`]: enum.Ordering.html
|
||||
//! [`Reverse`]: struct.Reverse.html
|
||||
//! [`max`]: fn.max.html
|
||||
//! [`min`]: fn.min.html
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
@ -562,7 +570,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
#[inline]
|
||||
fn max(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if other >= self { other } else { self }
|
||||
max_by(self, other, Ord::cmp)
|
||||
}
|
||||
|
||||
/// Compares and returns the minimum of two values.
|
||||
@ -579,7 +587,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
#[inline]
|
||||
fn min(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if self <= other { self } else { other }
|
||||
min_by(self, other, Ord::cmp)
|
||||
}
|
||||
|
||||
/// Restrict a value to a certain interval.
|
||||
@ -890,6 +898,49 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
|
||||
v1.min(v2)
|
||||
}
|
||||
|
||||
/// Returns the minimum of two values with respect to the specified comparison function.
|
||||
///
|
||||
/// Returns the first argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
|
||||
/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
|
||||
match compare(&v1, &v2) {
|
||||
Ordering::Less | Ordering::Equal => v1,
|
||||
Ordering::Greater => v2,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the element that gives the minimum value from the specified function.
|
||||
///
|
||||
/// Returns the first argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
|
||||
/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
||||
min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
|
||||
}
|
||||
|
||||
/// Compares and returns the maximum of two values.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
@ -910,6 +961,49 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
||||
v1.max(v2)
|
||||
}
|
||||
|
||||
/// Returns the maximum of two values with respect to the specified comparison function.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
|
||||
/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
|
||||
match compare(&v1, &v2) {
|
||||
Ordering::Less | Ordering::Equal => v2,
|
||||
Ordering::Greater => v1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the element that gives the maximum value from the specified function.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
|
||||
/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
||||
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
|
||||
}
|
||||
|
||||
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
|
||||
mod impls {
|
||||
use crate::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
@ -1012,8 +1106,10 @@ mod impls {
|
||||
impl Ord for $t {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &$t) -> Ordering {
|
||||
if *self == *other { Equal }
|
||||
else if *self < *other { Less }
|
||||
// The order here is important to generate more optimal assembly.
|
||||
// See <https://github.com/rust-lang/rust/issues/63758> for more info.
|
||||
if *self < *other { Less }
|
||||
else if *self == *other { Equal }
|
||||
else { Greater }
|
||||
}
|
||||
}
|
||||
|
@ -42,11 +42,11 @@
|
||||
|
||||
use crate::fmt;
|
||||
|
||||
/// An identity function.
|
||||
/// The identity function.
|
||||
///
|
||||
/// Two things are important to note about this function:
|
||||
///
|
||||
/// - It is not always equivalent to a closure like `|x| x` since the
|
||||
/// - It is not always equivalent to a closure like `|x| x`, since the
|
||||
/// closure may coerce `x` into a different type.
|
||||
///
|
||||
/// - It moves the input `x` passed to the function.
|
||||
@ -56,31 +56,32 @@ use crate::fmt;
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Using `identity` to do nothing among other interesting functions:
|
||||
/// Using `identity` to do nothing in a sequence of other, interesting,
|
||||
/// functions:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::convert::identity;
|
||||
///
|
||||
/// fn manipulation(x: u32) -> u32 {
|
||||
/// // Let's assume that this function does something interesting.
|
||||
/// // Let's pretend that adding one is an interesting function.
|
||||
/// x + 1
|
||||
/// }
|
||||
///
|
||||
/// let _arr = &[identity, manipulation];
|
||||
/// ```
|
||||
///
|
||||
/// Using `identity` to get a function that changes nothing in a conditional:
|
||||
/// Using `identity` as a "do nothing" base case in a conditional:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::convert::identity;
|
||||
///
|
||||
/// # let condition = true;
|
||||
///
|
||||
/// #
|
||||
/// # fn manipulation(x: u32) -> u32 { x + 1 }
|
||||
///
|
||||
/// #
|
||||
/// let do_stuff = if condition { manipulation } else { identity };
|
||||
///
|
||||
/// // do more interesting stuff..
|
||||
/// // Do more interesting stuff...
|
||||
///
|
||||
/// let _results = do_stuff(42);
|
||||
/// ```
|
||||
@ -104,22 +105,17 @@ pub const fn identity<T>(x: T) -> T { x }
|
||||
/// If you need to do a costly conversion it is better to implement [`From`] with type
|
||||
/// `&T` or write a custom function.
|
||||
///
|
||||
/// `AsRef` has the same signature as [`Borrow`], but `Borrow` is different in few aspects:
|
||||
/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in few aspects:
|
||||
///
|
||||
/// - Unlike `AsRef`, `Borrow` has a blanket impl for any `T`, and can be used to accept either
|
||||
/// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either
|
||||
/// a reference or a value.
|
||||
/// - `Borrow` also requires that `Hash`, `Eq` and `Ord` for borrowed value are
|
||||
/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for borrowed value are
|
||||
/// equivalent to those of the owned value. For this reason, if you want to
|
||||
/// borrow only a single field of a struct you can implement `AsRef`, but not `Borrow`.
|
||||
///
|
||||
/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
|
||||
/// borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`].
|
||||
///
|
||||
/// **Note: This trait must not fail**. If the conversion can fail, use a
|
||||
/// dedicated method which returns an [`Option<T>`] or a [`Result<T, E>`].
|
||||
///
|
||||
/// [`Option<T>`]: ../../std/option/enum.Option.html
|
||||
/// [`Result<T, E>`]: ../../std/result/enum.Result.html
|
||||
///
|
||||
/// # Generic Implementations
|
||||
///
|
||||
/// - `AsRef` auto-dereferences if the inner type is a reference or a mutable
|
||||
@ -132,9 +128,16 @@ pub const fn identity<T>(x: T) -> T { x }
|
||||
/// converted to the specified type `T`.
|
||||
///
|
||||
/// For example: By creating a generic function that takes an `AsRef<str>` we express that we
|
||||
/// want to accept all references that can be converted to `&str` as an argument.
|
||||
/// Since both [`String`] and `&str` implement `AsRef<str>` we can accept both as input argument.
|
||||
/// want to accept all references that can be converted to [`&str`] as an argument.
|
||||
/// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument.
|
||||
///
|
||||
/// [`Option<T>`]: ../../std/option/enum.Option.html
|
||||
/// [`Result<T, E>`]: ../../std/result/enum.Result.html
|
||||
/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
|
||||
/// [`Hash`]: ../../std/hash/trait.Hash.html
|
||||
/// [`Eq`]: ../../std/cmp/trait.Eq.html
|
||||
/// [`Ord`]: ../../std/cmp/trait.Ord.html
|
||||
/// [`&str`]: ../../std/primitive.str.html
|
||||
/// [`String`]: ../../std/string/struct.String.html
|
||||
///
|
||||
/// ```
|
||||
|
@ -518,7 +518,8 @@ impl Display for Arguments<'_> {
|
||||
label="`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`",
|
||||
)]
|
||||
#[doc(alias = "{:?}")]
|
||||
#[lang = "debug_trait"]
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, lang = "debug_trait")]
|
||||
#[cfg_attr(not(boostrap_stdarch_ignore_this), rustc_diagnostic_item = "debug_trait")]
|
||||
pub trait Debug {
|
||||
/// Formats the value using the given formatter.
|
||||
///
|
||||
|
@ -49,28 +49,16 @@ pub unsafe fn unreachable_unchecked() -> ! {
|
||||
intrinsics::unreachable()
|
||||
}
|
||||
|
||||
/// Signals the processor that it is entering a busy-wait spin-loop.
|
||||
/// Emits a machine instruction hinting to the processor that it is running in busy-wait
|
||||
/// spin-loop ("spin lock").
|
||||
///
|
||||
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
|
||||
/// power or switching hyper-threads.
|
||||
///
|
||||
/// This function is different than [`std::thread::yield_now`] which directly yields to the
|
||||
/// system's scheduler, whereas `spin_loop` only signals the processor that it is entering a
|
||||
/// busy-wait spin-loop without yielding control to the system's scheduler.
|
||||
///
|
||||
/// Using a busy-wait spin-loop with `spin_loop` is ideally used in situations where a
|
||||
/// contended lock is held by another thread executed on a different CPU and where the waiting
|
||||
/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
|
||||
/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
|
||||
/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
|
||||
/// before switching to the thread that holds the lock. If the contending lock is held by a thread
|
||||
/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
|
||||
/// use [`std::thread::yield_now`].
|
||||
/// For a discussion of different locking strategies and their trade-offs, see
|
||||
/// [`core::sync::atomic::spin_loop_hint`].
|
||||
///
|
||||
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
|
||||
/// do anything at all.
|
||||
///
|
||||
/// [`std::thread::yield_now`]: ../../std/thread/fn.yield_now.html
|
||||
/// [`core::sync::atomic::spin_loop_hint`]: ../sync/atomic/fn.spin_loop_hint.html
|
||||
#[inline]
|
||||
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
|
||||
pub fn spin_loop() {
|
||||
@ -104,11 +92,19 @@ pub fn spin_loop() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A function that is opaque to the optimizer, to allow benchmarks to
|
||||
/// pretend to use outputs to assist in avoiding dead-code
|
||||
/// elimination.
|
||||
/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what
|
||||
/// `black_box` could do.
|
||||
///
|
||||
/// This function is a no-op, and does not even read from `dummy`.
|
||||
/// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html
|
||||
///
|
||||
/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
|
||||
/// use `x` in any possible valid way that Rust code is allowed to without introducing undefined
|
||||
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
|
||||
/// certain optimizations are not desired, such as benchmarks.
|
||||
///
|
||||
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
|
||||
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
|
||||
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
|
||||
#[inline]
|
||||
#[unstable(feature = "test", issue = "50297")]
|
||||
#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
|
||||
|
@ -845,21 +845,26 @@ extern "rust-intrinsic" {
|
||||
///
|
||||
/// ```
|
||||
/// let store = [0, 1, 2, 3];
|
||||
/// let mut v_orig = store.iter().collect::<Vec<&i32>>();
|
||||
/// let v_orig = store.iter().collect::<Vec<&i32>>();
|
||||
///
|
||||
/// // clone the vector as we will reuse them later
|
||||
/// let v_clone = v_orig.clone();
|
||||
///
|
||||
/// // Using transmute: this is Undefined Behavior, and a bad idea.
|
||||
/// // However, it is no-copy.
|
||||
/// let v_transmuted = unsafe {
|
||||
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
|
||||
/// v_orig.clone())
|
||||
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
|
||||
/// };
|
||||
///
|
||||
/// let v_clone = v_orig.clone();
|
||||
///
|
||||
/// // This is the suggested, safe way.
|
||||
/// // It does copy the entire vector, though, into a new array.
|
||||
/// let v_collected = v_orig.clone()
|
||||
/// .into_iter()
|
||||
/// .map(|r| Some(r))
|
||||
/// .collect::<Vec<Option<&i32>>>();
|
||||
/// let v_collected = v_clone.into_iter()
|
||||
/// .map(Some)
|
||||
/// .collect::<Vec<Option<&i32>>>();
|
||||
///
|
||||
/// let v_clone = v_orig.clone();
|
||||
///
|
||||
/// // The no-copy, unsafe way, still using transmute, but not UB.
|
||||
/// // This is equivalent to the original, but safer, and reuses the
|
||||
@ -869,11 +874,12 @@ extern "rust-intrinsic" {
|
||||
/// // the original inner type (`&i32`) to the converted inner type
|
||||
/// // (`Option<&i32>`), so read the nomicon pages linked above.
|
||||
/// let v_from_raw = unsafe {
|
||||
/// Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>,
|
||||
/// v_orig.len(),
|
||||
/// v_orig.capacity())
|
||||
/// // Ensure the original vector is not dropped.
|
||||
/// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
|
||||
/// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
|
||||
/// v_clone.len(),
|
||||
/// v_clone.capacity())
|
||||
/// };
|
||||
/// std::mem::forget(v_orig);
|
||||
/// ```
|
||||
///
|
||||
/// Implementing `split_at_mut`:
|
||||
|
@ -5,7 +5,7 @@ use crate::usize;
|
||||
use crate::intrinsics;
|
||||
|
||||
use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
|
||||
use super::LoopState;
|
||||
use super::{LoopState, from_fn};
|
||||
|
||||
mod chain;
|
||||
mod flatten;
|
||||
@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
|
||||
{
|
||||
self.iter.rfind(predicate)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
|
||||
P: FnMut(Self::Item) -> bool
|
||||
{
|
||||
self.iter.position(predicate)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -541,6 +534,26 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
|
||||
self.iter.nth(nth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
|
||||
where
|
||||
F: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Ok = Acc>,
|
||||
{
|
||||
#[inline]
|
||||
fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
|
||||
move || iter.nth(step)
|
||||
}
|
||||
|
||||
if self.first_take {
|
||||
self.first_take = false;
|
||||
match self.iter.next() {
|
||||
None => return Try::from_ok(acc),
|
||||
Some(x) => acc = f(acc, x)?,
|
||||
}
|
||||
}
|
||||
from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> StepBy<I> where I: ExactSizeIterator {
|
||||
@ -574,6 +587,28 @@ impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSi
|
||||
.saturating_add(self.next_back_index());
|
||||
self.iter.nth_back(n)
|
||||
}
|
||||
|
||||
fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
|
||||
where
|
||||
F: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Ok = Acc>,
|
||||
{
|
||||
#[inline]
|
||||
fn nth_back<I: DoubleEndedIterator>(
|
||||
iter: &mut I,
|
||||
step: usize,
|
||||
) -> impl FnMut() -> Option<I::Item> + '_ {
|
||||
move || iter.nth_back(step)
|
||||
}
|
||||
|
||||
match self.next_back() {
|
||||
None => Try::from_ok(init),
|
||||
Some(x) => {
|
||||
let acc = f(init, x)?;
|
||||
from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StepBy can only make the iterator shorter, so the len will still fit.
|
||||
@ -1309,7 +1344,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
||||
{
|
||||
match self.peeked.take() {
|
||||
Some(None) => return Try::from_ok(init),
|
||||
Some(None) => Try::from_ok(init),
|
||||
Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
|
||||
Ok(acc) => f(acc, v),
|
||||
Err(e) => {
|
||||
@ -1326,7 +1361,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
|
||||
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
match self.peeked {
|
||||
Some(None) => return init,
|
||||
Some(None) => init,
|
||||
Some(Some(v)) => {
|
||||
let acc = self.iter.rfold(init, &mut fold);
|
||||
fold(acc, v)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmp::Ordering;
|
||||
use crate::cmp::{self, Ordering};
|
||||
use crate::ops::{Add, Try};
|
||||
|
||||
use super::super::LoopState;
|
||||
@ -2223,13 +2223,12 @@ pub trait Iterator {
|
||||
move |x| (f(&x), x)
|
||||
}
|
||||
|
||||
// switch to y even if it is only equal, to preserve stability.
|
||||
#[inline]
|
||||
fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
|
||||
x_p <= y_p
|
||||
fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
|
||||
x_p.cmp(y_p)
|
||||
}
|
||||
|
||||
let (_, x) = select_fold1(self.map(key(f)), select)?;
|
||||
let (_, x) = self.map(key(f)).max_by(compare)?;
|
||||
Some(x)
|
||||
}
|
||||
|
||||
@ -2252,13 +2251,12 @@ pub trait Iterator {
|
||||
fn max_by<F>(self, compare: F) -> Option<Self::Item>
|
||||
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||
{
|
||||
// switch to y even if it is only equal, to preserve stability.
|
||||
#[inline]
|
||||
fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
|
||||
move |x, y| compare(x, y) != Ordering::Greater
|
||||
fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T {
|
||||
move |x, y| cmp::max_by(x, y, &mut compare)
|
||||
}
|
||||
|
||||
select_fold1(self, select(compare))
|
||||
fold1(self, fold(compare))
|
||||
}
|
||||
|
||||
/// Returns the element that gives the minimum value from the
|
||||
@ -2285,13 +2283,12 @@ pub trait Iterator {
|
||||
move |x| (f(&x), x)
|
||||
}
|
||||
|
||||
// only switch to y if it is strictly smaller, to preserve stability.
|
||||
#[inline]
|
||||
fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
|
||||
x_p > y_p
|
||||
fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
|
||||
x_p.cmp(y_p)
|
||||
}
|
||||
|
||||
let (_, x) = select_fold1(self.map(key(f)), select)?;
|
||||
let (_, x) = self.map(key(f)).min_by(compare)?;
|
||||
Some(x)
|
||||
}
|
||||
|
||||
@ -2314,13 +2311,12 @@ pub trait Iterator {
|
||||
fn min_by<F>(self, compare: F) -> Option<Self::Item>
|
||||
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||
{
|
||||
// only switch to y if it is strictly smaller, to preserve stability.
|
||||
#[inline]
|
||||
fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
|
||||
move |x, y| compare(x, y) == Ordering::Greater
|
||||
fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T {
|
||||
move |x, y| cmp::min_by(x, y, &mut compare)
|
||||
}
|
||||
|
||||
select_fold1(self, select(compare))
|
||||
fold1(self, fold(compare))
|
||||
}
|
||||
|
||||
|
||||
@ -2546,11 +2542,51 @@ pub trait Iterator {
|
||||
|
||||
/// Lexicographically compares the elements of this `Iterator` with those
|
||||
/// of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// assert_eq!([1].iter().cmp([1].iter()), Ordering::Equal);
|
||||
/// assert_eq!([1].iter().cmp([1, 2].iter()), Ordering::Less);
|
||||
/// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn cmp<I>(mut self, other: I) -> Ordering where
|
||||
fn cmp<I>(self, other: I) -> Ordering
|
||||
where
|
||||
I: IntoIterator<Item = Self::Item>,
|
||||
Self::Item: Ord,
|
||||
Self: Sized,
|
||||
{
|
||||
self.cmp_by(other, |x, y| x.cmp(&y))
|
||||
}
|
||||
|
||||
/// Lexicographically compares the elements of this `Iterator` with those
|
||||
/// of another with respect to the specified comparison function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// let xs = [1, 2, 3, 4];
|
||||
/// let ys = [1, 4, 9, 16];
|
||||
///
|
||||
/// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
|
||||
/// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
|
||||
/// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
|
||||
/// ```
|
||||
#[unstable(feature = "iter_order_by", issue = "0")]
|
||||
fn cmp_by<I, F>(mut self, other: I, mut cmp: F) -> Ordering
|
||||
where
|
||||
Self: Sized,
|
||||
I: IntoIterator,
|
||||
F: FnMut(Self::Item, I::Item) -> Ordering,
|
||||
{
|
||||
let mut other = other.into_iter();
|
||||
|
||||
@ -2569,7 +2605,7 @@ pub trait Iterator {
|
||||
Some(val) => val,
|
||||
};
|
||||
|
||||
match x.cmp(&y) {
|
||||
match cmp(x, y) {
|
||||
Ordering::Equal => (),
|
||||
non_eq => return non_eq,
|
||||
}
|
||||
@ -2578,11 +2614,62 @@ pub trait Iterator {
|
||||
|
||||
/// Lexicographically compares the elements of this `Iterator` with those
|
||||
/// of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// assert_eq!([1.].iter().partial_cmp([1.].iter()), Some(Ordering::Equal));
|
||||
/// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
|
||||
/// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));
|
||||
///
|
||||
/// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn partial_cmp<I>(mut self, other: I) -> Option<Ordering> where
|
||||
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
|
||||
where
|
||||
I: IntoIterator,
|
||||
Self::Item: PartialOrd<I::Item>,
|
||||
Self: Sized,
|
||||
{
|
||||
self.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
|
||||
}
|
||||
|
||||
/// Lexicographically compares the elements of this `Iterator` with those
|
||||
/// of another with respect to the specified comparison function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// let xs = [1.0, 2.0, 3.0, 4.0];
|
||||
/// let ys = [1.0, 4.0, 9.0, 16.0];
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)),
|
||||
/// Some(Ordering::Less)
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)),
|
||||
/// Some(Ordering::Equal)
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)),
|
||||
/// Some(Ordering::Greater)
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "iter_order_by", issue = "0")]
|
||||
fn partial_cmp_by<I, F>(mut self, other: I, mut partial_cmp: F) -> Option<Ordering>
|
||||
where
|
||||
Self: Sized,
|
||||
I: IntoIterator,
|
||||
F: FnMut(Self::Item, I::Item) -> Option<Ordering>,
|
||||
{
|
||||
let mut other = other.into_iter();
|
||||
|
||||
@ -2601,7 +2688,7 @@ pub trait Iterator {
|
||||
Some(val) => val,
|
||||
};
|
||||
|
||||
match x.partial_cmp(&y) {
|
||||
match partial_cmp(x, y) {
|
||||
Some(Ordering::Equal) => (),
|
||||
non_eq => return non_eq,
|
||||
}
|
||||
@ -2610,11 +2697,44 @@ pub trait Iterator {
|
||||
|
||||
/// Determines if the elements of this `Iterator` are equal to those of
|
||||
/// another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().eq([1].iter()), true);
|
||||
/// assert_eq!([1].iter().eq([1, 2].iter()), false);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn eq<I>(mut self, other: I) -> bool where
|
||||
fn eq<I>(self, other: I) -> bool
|
||||
where
|
||||
I: IntoIterator,
|
||||
Self::Item: PartialEq<I::Item>,
|
||||
Self: Sized,
|
||||
{
|
||||
self.eq_by(other, |x, y| x == y)
|
||||
}
|
||||
|
||||
/// Determines if the elements of this `Iterator` are equal to those of
|
||||
/// another with respect to the specified equality function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_order_by)]
|
||||
///
|
||||
/// let xs = [1, 2, 3, 4];
|
||||
/// let ys = [1, 4, 9, 16];
|
||||
///
|
||||
/// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
|
||||
/// ```
|
||||
#[unstable(feature = "iter_order_by", issue = "0")]
|
||||
fn eq_by<I, F>(mut self, other: I, mut eq: F) -> bool
|
||||
where
|
||||
Self: Sized,
|
||||
I: IntoIterator,
|
||||
F: FnMut(Self::Item, I::Item) -> bool,
|
||||
{
|
||||
let mut other = other.into_iter();
|
||||
|
||||
@ -2629,12 +2749,21 @@ pub trait Iterator {
|
||||
Some(val) => val,
|
||||
};
|
||||
|
||||
if x != y { return false }
|
||||
if !eq(x, y) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the elements of this `Iterator` are unequal to those of
|
||||
/// another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().ne([1].iter()), false);
|
||||
/// assert_eq!([1].iter().ne([1, 2].iter()), true);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn ne<I>(self, other: I) -> bool where
|
||||
I: IntoIterator,
|
||||
@ -2646,6 +2775,14 @@ pub trait Iterator {
|
||||
|
||||
/// Determines if the elements of this `Iterator` are lexicographically
|
||||
/// less than those of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().lt([1].iter()), false);
|
||||
/// assert_eq!([1].iter().lt([1, 2].iter()), true);
|
||||
/// assert_eq!([1, 2].iter().lt([1].iter()), false);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn lt<I>(self, other: I) -> bool where
|
||||
I: IntoIterator,
|
||||
@ -2657,6 +2794,14 @@ pub trait Iterator {
|
||||
|
||||
/// Determines if the elements of this `Iterator` are lexicographically
|
||||
/// less or equal to those of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().le([1].iter()), true);
|
||||
/// assert_eq!([1].iter().le([1, 2].iter()), true);
|
||||
/// assert_eq!([1, 2].iter().le([1].iter()), false);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn le<I>(self, other: I) -> bool where
|
||||
I: IntoIterator,
|
||||
@ -2671,6 +2816,14 @@ pub trait Iterator {
|
||||
|
||||
/// Determines if the elements of this `Iterator` are lexicographically
|
||||
/// greater than those of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().gt([1].iter()), false);
|
||||
/// assert_eq!([1].iter().gt([1, 2].iter()), false);
|
||||
/// assert_eq!([1, 2].iter().gt([1].iter()), true);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn gt<I>(self, other: I) -> bool where
|
||||
I: IntoIterator,
|
||||
@ -2682,6 +2835,14 @@ pub trait Iterator {
|
||||
|
||||
/// Determines if the elements of this `Iterator` are lexicographically
|
||||
/// greater than or equal to those of another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!([1].iter().ge([1].iter()), true);
|
||||
/// assert_eq!([1].iter().ge([1, 2].iter()), false);
|
||||
/// assert_eq!([1, 2].iter().ge([1].iter()), true);
|
||||
/// ```
|
||||
#[stable(feature = "iter_order", since = "1.5.0")]
|
||||
fn ge<I>(self, other: I) -> bool where
|
||||
I: IntoIterator,
|
||||
@ -2730,6 +2891,18 @@ pub trait Iterator {
|
||||
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
|
||||
/// [`is_sorted`]; see its documentation for more information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(is_sorted)]
|
||||
///
|
||||
/// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
|
||||
/// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
|
||||
/// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
|
||||
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
|
||||
/// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
|
||||
/// ```
|
||||
///
|
||||
/// [`is_sorted`]: trait.Iterator.html#method.is_sorted
|
||||
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
|
||||
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
|
||||
@ -2781,28 +2954,18 @@ pub trait Iterator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Select an element from an iterator based on the given "comparison"
|
||||
/// function.
|
||||
///
|
||||
/// This is an idiosyncratic helper to try to factor out the
|
||||
/// commonalities of {max,min}{,_by}. In particular, this avoids
|
||||
/// having to implement optimizations several times.
|
||||
/// Fold an iterator without having to provide an initial value.
|
||||
#[inline]
|
||||
fn select_fold1<I, F>(mut it: I, f: F) -> Option<I::Item>
|
||||
fn fold1<I, F>(mut it: I, f: F) -> Option<I::Item>
|
||||
where
|
||||
I: Iterator,
|
||||
F: FnMut(&I::Item, &I::Item) -> bool,
|
||||
F: FnMut(I::Item, I::Item) -> I::Item,
|
||||
{
|
||||
#[inline]
|
||||
fn select<T>(mut f: impl FnMut(&T, &T) -> bool) -> impl FnMut(T, T) -> T {
|
||||
move |sel, x| if f(&sel, &x) { x } else { sel }
|
||||
}
|
||||
|
||||
// start with the first element as our selection. This avoids
|
||||
// having to use `Option`s inside the loop, translating to a
|
||||
// sizeable performance gain (6x in one case).
|
||||
let first = it.next()?;
|
||||
Some(it.fold(first, select(f)))
|
||||
Some(it.fold(first, f))
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -87,7 +87,7 @@
|
||||
#![feature(link_llvm_intrinsics)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(bind_by_move_pattern_guards)]
|
||||
#![cfg_attr(boostrap_stdarch_ignore_this, feature(bind_by_move_pattern_guards))]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(no_core)]
|
||||
#![feature(on_unimplemented)]
|
||||
@ -227,6 +227,7 @@ pub mod task;
|
||||
pub mod alloc;
|
||||
|
||||
// note: does not need to be public
|
||||
mod bool;
|
||||
mod tuple;
|
||||
mod unit;
|
||||
|
||||
|
@ -734,7 +734,6 @@ pub(crate) mod builtin {
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
#[rustc_macro_transparency = "opaque"]
|
||||
macro_rules! format_args {
|
||||
($fmt:expr) => ({ /* compiler built-in */ });
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
@ -747,7 +746,6 @@ pub(crate) mod builtin {
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
#[rustc_macro_transparency = "opaque"]
|
||||
macro_rules! format_args_nl {
|
||||
($fmt:expr) => ({ /* compiler built-in */ });
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
@ -1235,15 +1233,15 @@ pub(crate) mod builtin {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro test($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a benchmark test.
|
||||
#[unstable(feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable")]
|
||||
#[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable"))]
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable"))]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro bench($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// An implementation detail of the `#[test]` and `#[bench]` macros.
|
||||
@ -1251,26 +1249,22 @@ pub(crate) mod builtin {
|
||||
reason = "custom test frameworks are an unstable feature")]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro test_case($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Attribute macro applied to a static to register it as a global allocator.
|
||||
#[stable(feature = "global_allocator", since = "1.28.0")]
|
||||
#[allow_internal_unstable(rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro global_allocator($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
||||
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
|
||||
|
@ -602,10 +602,10 @@ unsafe impl<T: ?Sized> Freeze for *mut T {}
|
||||
unsafe impl<T: ?Sized> Freeze for &T {}
|
||||
unsafe impl<T: ?Sized> Freeze for &mut T {}
|
||||
|
||||
/// Types which can be safely moved after being pinned.
|
||||
/// Types that can be safely moved after being pinned.
|
||||
///
|
||||
/// Since Rust itself has no notion of immovable types, and considers moves
|
||||
/// (e.g. through assignment or [`mem::replace`]) to always be safe,
|
||||
/// (e.g., through assignment or [`mem::replace`]) to always be safe,
|
||||
/// this trait cannot prevent types from moving by itself.
|
||||
///
|
||||
/// Instead it is used to prevent moves through the type system,
|
||||
|
@ -315,7 +315,7 @@ impl f32 {
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let x = 2.0_f32;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
/// let abs_difference = (x.recip() - (1.0 / x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
|
@ -327,7 +327,7 @@ impl f64 {
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
/// let abs_difference = (x.recip() - (1.0 / x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
|
@ -1401,12 +1401,8 @@ $EndFeature, "
|
||||
```"),
|
||||
#[stable(feature = "no_panic_abs", since = "1.13.0")]
|
||||
#[inline]
|
||||
pub fn wrapping_abs(self) -> Self {
|
||||
if self.is_negative() {
|
||||
self.wrapping_neg()
|
||||
} else {
|
||||
self
|
||||
}
|
||||
pub const fn wrapping_abs(self) -> Self {
|
||||
(self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1764,12 +1760,8 @@ $EndFeature, "
|
||||
```"),
|
||||
#[stable(feature = "no_panic_abs", since = "1.13.0")]
|
||||
#[inline]
|
||||
pub fn overflowing_abs(self) -> (Self, bool) {
|
||||
if self.is_negative() {
|
||||
self.overflowing_neg()
|
||||
} else {
|
||||
(self, false)
|
||||
}
|
||||
pub const fn overflowing_abs(self) -> (Self, bool) {
|
||||
(self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1973,15 +1965,11 @@ $EndFeature, "
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn abs(self) -> Self {
|
||||
if self.is_negative() {
|
||||
// Note that the #[inline] above means that the overflow
|
||||
// semantics of this negation depend on the crate we're being
|
||||
// inlined into.
|
||||
-self
|
||||
} else {
|
||||
self
|
||||
}
|
||||
pub const fn abs(self) -> Self {
|
||||
// Note that the #[inline] above means that the overflow
|
||||
// semantics of the subtraction depend on the crate we're being
|
||||
// inlined into.
|
||||
(self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -2104,11 +2092,14 @@ $to_xe_bytes_doc,
|
||||
|
||||
```
|
||||
let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
|
||||
assert_eq!(bytes, if cfg!(target_endian = \"big\") {
|
||||
assert_eq!(
|
||||
bytes,
|
||||
if cfg!(target_endian = \"big\") {
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
}
|
||||
);
|
||||
```"),
|
||||
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
|
||||
#[rustc_const_unstable(feature = "const_int_conversion")]
|
||||
@ -2200,10 +2191,10 @@ $from_xe_bytes_doc,
|
||||
|
||||
```
|
||||
let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
assert_eq!(value, ", $swap_op, ");
|
||||
```
|
||||
|
||||
@ -3923,11 +3914,14 @@ $to_xe_bytes_doc,
|
||||
|
||||
```
|
||||
let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
|
||||
assert_eq!(bytes, if cfg!(target_endian = \"big\") {
|
||||
assert_eq!(
|
||||
bytes,
|
||||
if cfg!(target_endian = \"big\") {
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
}
|
||||
);
|
||||
```"),
|
||||
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
|
||||
#[rustc_const_unstable(feature = "const_int_conversion")]
|
||||
@ -4019,10 +4013,10 @@ $from_xe_bytes_doc,
|
||||
|
||||
```
|
||||
let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
", $be_bytes, "
|
||||
} else {
|
||||
", $le_bytes, "
|
||||
});
|
||||
assert_eq!(value, ", $swap_op, ");
|
||||
```
|
||||
|
||||
|
@ -18,6 +18,8 @@ macro_rules! sh_impl_signed {
|
||||
}
|
||||
}
|
||||
}
|
||||
forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
|
||||
#[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
|
||||
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShlAssign<$f> for Wrapping<$t> {
|
||||
@ -41,6 +43,8 @@ macro_rules! sh_impl_signed {
|
||||
}
|
||||
}
|
||||
}
|
||||
forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
|
||||
#[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
|
||||
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShrAssign<$f> for Wrapping<$t> {
|
||||
@ -64,6 +68,8 @@ macro_rules! sh_impl_unsigned {
|
||||
Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32))
|
||||
}
|
||||
}
|
||||
forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
|
||||
#[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
|
||||
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShlAssign<$f> for Wrapping<$t> {
|
||||
@ -83,6 +89,8 @@ macro_rules! sh_impl_unsigned {
|
||||
Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32))
|
||||
}
|
||||
}
|
||||
forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
|
||||
#[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
|
||||
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShrAssign<$f> for Wrapping<$t> {
|
||||
|
@ -185,14 +185,6 @@ pub trait FnMut<Args> : FnOnce<Args> {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ## Calling a by-value closure
|
||||
///
|
||||
/// ```
|
||||
/// let x = 5;
|
||||
/// let square_x = move || x * x;
|
||||
/// assert_eq!(square_x(), 25);
|
||||
/// ```
|
||||
///
|
||||
/// ## Using a `FnOnce` parameter
|
||||
///
|
||||
/// ```
|
||||
|
@ -295,7 +295,7 @@ impl<T> Option<T> {
|
||||
/// [`Pin`]: ../pin/struct.Pin.html
|
||||
#[inline]
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub fn as_pin_ref<'a>(self: Pin<&'a Option<T>>) -> Option<Pin<&'a T>> {
|
||||
pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
|
||||
unsafe {
|
||||
Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
|
||||
}
|
||||
@ -306,7 +306,7 @@ impl<T> Option<T> {
|
||||
/// [`Pin`]: ../pin/struct.Pin.html
|
||||
#[inline]
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub fn as_pin_mut<'a>(self: Pin<&'a mut Option<T>>) -> Option<Pin<&'a mut T>> {
|
||||
pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
|
||||
unsafe {
|
||||
Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x))
|
||||
}
|
||||
@ -1110,6 +1110,18 @@ impl<T: Deref> Option<T> {
|
||||
/// to the original one, additionally coercing the contents via [`Deref`].
|
||||
///
|
||||
/// [`Deref`]: ../../std/ops/trait.Deref.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inner_deref)]
|
||||
///
|
||||
/// let x: Option<String> = Some("hey".to_owned());
|
||||
/// assert_eq!(x.as_deref(), Some("hey"));
|
||||
///
|
||||
/// let x: Option<String> = None;
|
||||
/// assert_eq!(x.as_deref(), None);
|
||||
/// ```
|
||||
pub fn as_deref(&self) -> Option<&T::Target> {
|
||||
self.as_ref().map(|t| t.deref())
|
||||
}
|
||||
@ -1121,6 +1133,18 @@ impl<T: DerefMut> Option<T> {
|
||||
///
|
||||
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
|
||||
/// the inner type's `Deref::Target` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inner_deref)]
|
||||
///
|
||||
/// let mut x: Option<String> = Some("hey".to_owned());
|
||||
/// assert_eq!(x.as_deref_mut().map(|x| {
|
||||
/// x.make_ascii_uppercase();
|
||||
/// x
|
||||
/// }), Some("HEY".to_owned().as_mut_str()));
|
||||
/// ```
|
||||
pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
|
||||
self.as_mut().map(|t| t.deref_mut())
|
||||
}
|
||||
@ -1199,6 +1223,13 @@ impl<T: Clone> Clone for Option<T> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> Default for Option<T> {
|
||||
/// Returns [`None`][Option::None].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let opt: Option<u32> = Option::default();
|
||||
/// assert!(opt.is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn default() -> Option<T> { None }
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3
|
||||
}
|
||||
|
||||
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
|
||||
#[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))]
|
||||
extern "Rust" {
|
||||
#[lang = "panic_impl"]
|
||||
fn panic_impl(pi: &PanicInfo<'_>) -> !;
|
||||
|
@ -233,7 +233,7 @@
|
||||
//! # type Field = i32;
|
||||
//! # struct Struct { field: Field }
|
||||
//! impl Struct {
|
||||
//! fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> &'a mut Field {
|
||||
//! fn pin_get_field(self: Pin<&mut Self>) -> &mut Field {
|
||||
//! // This is okay because `field` is never considered pinned.
|
||||
//! unsafe { &mut self.get_unchecked_mut().field }
|
||||
//! }
|
||||
@ -257,7 +257,7 @@
|
||||
//! # type Field = i32;
|
||||
//! # struct Struct { field: Field }
|
||||
//! impl Struct {
|
||||
//! fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut Field> {
|
||||
//! fn pin_get_field(self: Pin<&mut Self>) -> Pin<&mut Field> {
|
||||
//! // This is okay because `field` is pinned when `self` is.
|
||||
//! unsafe { self.map_unchecked_mut(|s| &mut s.field) }
|
||||
//! }
|
||||
@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
|
||||
/// can ignore the pinning invariants when unwrapping it.
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub fn into_inner(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
@ -549,7 +549,7 @@ impl<P: Deref> Pin<P> {
|
||||
/// ruled out by the contract of `Pin::new_unchecked`.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> {
|
||||
pub fn as_ref(&self) -> Pin<&P::Target> {
|
||||
unsafe { Pin::new_unchecked(&*self.pointer) }
|
||||
}
|
||||
|
||||
@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
/// [`Pin::into_inner`]: #method.into_inner
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
@ -584,9 +584,30 @@ impl<P: DerefMut> Pin<P> {
|
||||
/// the pointee cannot move after `Pin<Pointer<T>>` got created.
|
||||
/// "Malicious" implementations of `Pointer::DerefMut` are likewise
|
||||
/// ruled out by the contract of `Pin::new_unchecked`.
|
||||
///
|
||||
/// This method is useful when doing multiple calls to functions that consume the pinned type.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// # struct Type {}
|
||||
/// impl Type {
|
||||
/// fn method(self: Pin<&mut Self>) {
|
||||
/// // do something
|
||||
/// }
|
||||
///
|
||||
/// fn call_method_twice(mut self: Pin<&mut Self>) {
|
||||
/// // `method` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
|
||||
/// self.as_mut().method();
|
||||
/// self.as_mut().method();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> {
|
||||
pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
|
||||
unsafe { Pin::new_unchecked(&mut *self.pointer) }
|
||||
}
|
||||
|
||||
@ -596,7 +617,7 @@ impl<P: DerefMut> Pin<P> {
|
||||
/// run before being overwritten, so no pinning guarantee is violated.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn set(self: &mut Pin<P>, value: P::Target)
|
||||
pub fn set(&mut self, value: P::Target)
|
||||
where
|
||||
P::Target: Sized,
|
||||
{
|
||||
@ -621,7 +642,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
|
||||
///
|
||||
/// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub unsafe fn map_unchecked<U, F>(self: Pin<&'a T>, func: F) -> Pin<&'a U> where
|
||||
pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U> where
|
||||
F: FnOnce(&T) -> &U,
|
||||
{
|
||||
let pointer = &*self.pointer;
|
||||
@ -648,7 +669,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
|
||||
/// ["pinning projections"]: ../../std/pin/index.html#projections-and-structural-pinning
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn get_ref(self: Pin<&'a T>) -> &'a T {
|
||||
pub fn get_ref(self) -> &'a T {
|
||||
self.pointer
|
||||
}
|
||||
}
|
||||
@ -657,7 +678,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
||||
/// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn into_ref(self: Pin<&'a mut T>) -> Pin<&'a T> {
|
||||
pub fn into_ref(self) -> Pin<&'a T> {
|
||||
Pin { pointer: self.pointer }
|
||||
}
|
||||
|
||||
@ -672,7 +693,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
||||
/// with the same lifetime as the original `Pin`.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn get_mut(self: Pin<&'a mut T>) -> &'a mut T
|
||||
pub fn get_mut(self) -> &'a mut T
|
||||
where T: Unpin,
|
||||
{
|
||||
self.pointer
|
||||
@ -690,7 +711,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
||||
/// instead.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn get_unchecked_mut(self: Pin<&'a mut T>) -> &'a mut T {
|
||||
pub unsafe fn get_unchecked_mut(self) -> &'a mut T {
|
||||
self.pointer
|
||||
}
|
||||
|
||||
@ -710,7 +731,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
||||
///
|
||||
/// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub unsafe fn map_unchecked_mut<U, F>(self: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
|
||||
pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U> where
|
||||
F: FnOnce(&mut T) -> &mut U,
|
||||
{
|
||||
let pointer = Pin::get_unchecked_mut(self);
|
||||
|
@ -1042,7 +1042,7 @@ impl<T: ?Sized> *const T {
|
||||
(self as *const u8) == null()
|
||||
}
|
||||
|
||||
/// Cast to a pointer to a different type
|
||||
/// Casts to a pointer of another type.
|
||||
#[stable(feature = "ptr_cast", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub const fn cast<U>(self) -> *const U {
|
||||
@ -1726,7 +1726,7 @@ impl<T: ?Sized> *mut T {
|
||||
(self as *mut u8) == null_mut()
|
||||
}
|
||||
|
||||
/// Cast to a pointer to a different type
|
||||
/// Casts to a pointer of another type.
|
||||
#[stable(feature = "ptr_cast", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub const fn cast<U>(self) -> *mut U {
|
||||
|
@ -125,7 +125,7 @@ impl<T: ?Sized> NonNull<T> {
|
||||
&mut *self.as_ptr()
|
||||
}
|
||||
|
||||
/// Cast to a pointer of another type
|
||||
/// Casts to a pointer of another type.
|
||||
#[stable(feature = "nonnull_cast", since = "1.27.0")]
|
||||
#[inline]
|
||||
pub const fn cast<U>(self) -> NonNull<U> {
|
||||
|
@ -820,6 +820,87 @@ impl<T, E> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, E> Result<&T, E> {
|
||||
/// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_copied)]
|
||||
/// let val = 12;
|
||||
/// let x: Result<&i32, i32> = Ok(&val);
|
||||
/// assert_eq!(x, Ok(&12));
|
||||
/// let copied = x.copied();
|
||||
/// assert_eq!(copied, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
|
||||
pub fn copied(self) -> Result<T, E> {
|
||||
self.map(|&t| t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, E> Result<&mut T, E> {
|
||||
/// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_copied)]
|
||||
/// let mut val = 12;
|
||||
/// let x: Result<&mut i32, i32> = Ok(&mut val);
|
||||
/// assert_eq!(x, Ok(&mut 12));
|
||||
/// let copied = x.copied();
|
||||
/// assert_eq!(copied, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
|
||||
pub fn copied(self) -> Result<T, E> {
|
||||
self.map(|&mut t| t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E> Result<&T, E> {
|
||||
/// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_cloned)]
|
||||
/// let val = 12;
|
||||
/// let x: Result<&i32, i32> = Ok(&val);
|
||||
/// assert_eq!(x, Ok(&12));
|
||||
/// let cloned = x.cloned();
|
||||
/// assert_eq!(cloned, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
|
||||
pub fn cloned(self) -> Result<T, E> {
|
||||
self.map(|t| t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E> Result<&mut T, E> {
|
||||
/// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_cloned)]
|
||||
/// let mut val = 12;
|
||||
/// let x: Result<&mut i32, i32> = Ok(&mut val);
|
||||
/// assert_eq!(x, Ok(&mut 12));
|
||||
/// let cloned = x.cloned();
|
||||
/// assert_eq!(cloned, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
|
||||
pub fn cloned(self) -> Result<T, E> {
|
||||
self.map(|t| t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T, E: fmt::Debug> Result<T, E> {
|
||||
/// Unwraps a result, yielding the content of an [`Ok`].
|
||||
///
|
||||
|
@ -3026,8 +3026,7 @@ macro_rules! len {
|
||||
if size == 0 {
|
||||
// This _cannot_ use `unchecked_sub` because we depend on wrapping
|
||||
// to represent the length of long ZST slice iterators.
|
||||
let diff = ($self.end as usize).wrapping_sub(start as usize);
|
||||
diff
|
||||
($self.end as usize).wrapping_sub(start as usize)
|
||||
} else {
|
||||
// We know that `start <= end`, so can do better than `offset_from`,
|
||||
// which needs to deal in signed. By setting appropriate flags here
|
||||
|
@ -2170,6 +2170,7 @@ impl str {
|
||||
#[inline(always)]
|
||||
#[rustc_const_unstable(feature="const_str_as_bytes")]
|
||||
pub const fn as_bytes(&self) -> &[u8] {
|
||||
#[repr(C)]
|
||||
union Slices<'a> {
|
||||
str: &'a str,
|
||||
slice: &'a [u8],
|
||||
@ -3557,7 +3558,7 @@ impl str {
|
||||
/// A string is a sequence of bytes. `start` in this context means the first
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be left side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the right side.
|
||||
/// Arabic or Hebrew, this will be the right side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3594,7 +3595,7 @@ impl str {
|
||||
/// A string is a sequence of bytes. `end` in this context means the last
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be right side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the left side.
|
||||
/// Arabic or Hebrew, this will be the left side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3761,7 +3762,7 @@ impl str {
|
||||
/// A string is a sequence of bytes. `start` in this context means the first
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be left side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the right side.
|
||||
/// Arabic or Hebrew, this will be the right side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3800,7 +3801,7 @@ impl str {
|
||||
/// A string is a sequence of bytes. `end` in this context means the last
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be right side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the left side.
|
||||
/// Arabic or Hebrew, this will be the left side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -124,28 +124,31 @@ use crate::fmt;
|
||||
|
||||
use crate::hint::spin_loop;
|
||||
|
||||
/// Signals the processor that it is entering a busy-wait spin-loop.
|
||||
/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
|
||||
///
|
||||
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
|
||||
/// power or switching hyper-threads.
|
||||
///
|
||||
/// This function is different than [`std::thread::yield_now`] which directly yields to the
|
||||
/// system's scheduler, whereas `spin_loop_hint` only signals the processor that it is entering a
|
||||
/// busy-wait spin-loop without yielding control to the system's scheduler.
|
||||
/// This function is different from [`std::thread::yield_now`] which directly yields to the
|
||||
/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
|
||||
///
|
||||
/// Using a busy-wait spin-loop with `spin_loop_hint` is ideally used in situations where a
|
||||
/// contended lock is held by another thread executed on a different CPU and where the waiting
|
||||
/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
|
||||
/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
|
||||
/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
|
||||
/// before switching to the thread that holds the lock. If the contending lock is held by a thread
|
||||
/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
|
||||
/// use [`std::thread::yield_now`].
|
||||
/// Spin locks can be very efficient for short lock durations because they do not involve context
|
||||
/// switches or interaction with the operating system. For long lock durations they become wasteful
|
||||
/// however because they use CPU cycles for the entire lock duration, and using a
|
||||
/// [`std::sync::Mutex`] is likely the better approach. If actively spinning for a long time is
|
||||
/// required, e.g. because code polls a non-blocking API, calling [`std::thread::yield_now`]
|
||||
/// or [`std::thread::sleep`] may be the best option.
|
||||
///
|
||||
/// **Note**: Spin locks are based on the underlying assumption that another thread will release
|
||||
/// the lock 'soon'. In order for this to work, that other thread must run on a different CPU or
|
||||
/// core (at least potentially). Spin locks do not work efficiently on single CPU / core platforms.
|
||||
///
|
||||
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
|
||||
/// do anything at all.
|
||||
///
|
||||
/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
|
||||
/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
|
||||
/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
|
||||
#[inline]
|
||||
#[stable(feature = "spin_loop_hint", since = "1.24.0")]
|
||||
pub fn spin_loop_hint() {
|
||||
@ -979,9 +982,8 @@ impl<T> AtomicPtr<T> {
|
||||
/// let some_ptr = AtomicPtr::new(ptr);
|
||||
///
|
||||
/// let other_ptr = &mut 10;
|
||||
/// let another_ptr = &mut 10;
|
||||
///
|
||||
/// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed);
|
||||
/// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -1021,9 +1023,8 @@ impl<T> AtomicPtr<T> {
|
||||
/// let some_ptr = AtomicPtr::new(ptr);
|
||||
///
|
||||
/// let other_ptr = &mut 10;
|
||||
/// let another_ptr = &mut 10;
|
||||
///
|
||||
/// let value = some_ptr.compare_exchange(other_ptr, another_ptr,
|
||||
/// let value = some_ptr.compare_exchange(ptr, other_ptr,
|
||||
/// Ordering::SeqCst, Ordering::Relaxed);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
7
src/libcore/tests/bool.rs
Normal file
7
src/libcore/tests/bool.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#[test]
|
||||
fn test_bool_to_option() {
|
||||
assert_eq!(false.then(0), None);
|
||||
assert_eq!(true.then(0), Some(0));
|
||||
assert_eq!(false.then_with(|| 0), None);
|
||||
assert_eq!(true.then_with(|| 0), Some(0));
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use core::cmp::Ordering::{Less, Greater, Equal};
|
||||
use core::cmp::{self, Ordering::*};
|
||||
|
||||
#[test]
|
||||
fn test_int_totalord() {
|
||||
@ -28,6 +28,28 @@ fn test_ord_max_min() {
|
||||
assert_eq!(1.min(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_min_max_by() {
|
||||
let f = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
|
||||
assert_eq!(cmp::min_by(1, -1, f), 1);
|
||||
assert_eq!(cmp::min_by(1, -2, f), 1);
|
||||
assert_eq!(cmp::min_by(2, -1, f), -1);
|
||||
assert_eq!(cmp::max_by(1, -1, f), -1);
|
||||
assert_eq!(cmp::max_by(1, -2, f), -2);
|
||||
assert_eq!(cmp::max_by(2, -1, f), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_min_max_by_key() {
|
||||
let f = |x: &i32| x.abs();
|
||||
assert_eq!(cmp::min_by_key(1, -1, f), 1);
|
||||
assert_eq!(cmp::min_by_key(1, -2, f), 1);
|
||||
assert_eq!(cmp::min_by_key(2, -1, f), -1);
|
||||
assert_eq!(cmp::max_by_key(1, -1, f), -1);
|
||||
assert_eq!(cmp::max_by_key(1, -2, f), -2);
|
||||
assert_eq!(cmp::max_by_key(2, -1, f), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ordering_reverse() {
|
||||
assert_eq!(Less.reverse(), Greater);
|
||||
|
@ -57,6 +57,62 @@ fn test_multi_iter() {
|
||||
assert!(xs.iter().lt(xs.iter().skip(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_by() {
|
||||
use core::cmp::Ordering;
|
||||
|
||||
let f = |x: i32, y: i32| (x * x).cmp(&y);
|
||||
let xs = || [1, 2, 3, 4].iter().copied();
|
||||
let ys = || [1, 4, 16].iter().copied();
|
||||
|
||||
assert_eq!(xs().cmp_by(ys(), f), Ordering::Less);
|
||||
assert_eq!(ys().cmp_by(xs(), f), Ordering::Greater);
|
||||
assert_eq!(xs().cmp_by(xs().map(|x| x * x), f), Ordering::Equal);
|
||||
assert_eq!(xs().rev().cmp_by(ys().rev(), f), Ordering::Greater);
|
||||
assert_eq!(xs().cmp_by(ys().rev(), f), Ordering::Less);
|
||||
assert_eq!(xs().cmp_by(ys().take(2), f), Ordering::Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partial_cmp_by() {
|
||||
use core::cmp::Ordering;
|
||||
use core::f64;
|
||||
|
||||
let f = |x: i32, y: i32| (x * x).partial_cmp(&y);
|
||||
let xs = || [1, 2, 3, 4].iter().copied();
|
||||
let ys = || [1, 4, 16].iter().copied();
|
||||
|
||||
assert_eq!(xs().partial_cmp_by(ys(), f), Some(Ordering::Less));
|
||||
assert_eq!(ys().partial_cmp_by(xs(), f), Some(Ordering::Greater));
|
||||
assert_eq!(xs().partial_cmp_by(xs().map(|x| x * x), f), Some(Ordering::Equal));
|
||||
assert_eq!(xs().rev().partial_cmp_by(ys().rev(), f), Some(Ordering::Greater));
|
||||
assert_eq!(xs().partial_cmp_by(xs().rev(), f), Some(Ordering::Less));
|
||||
assert_eq!(xs().partial_cmp_by(ys().take(2), f), Some(Ordering::Greater));
|
||||
|
||||
let f = |x: f64, y: f64| (x * x).partial_cmp(&y);
|
||||
let xs = || [1.0, 2.0, 3.0, 4.0].iter().copied();
|
||||
let ys = || [1.0, 4.0, f64::NAN, 16.0].iter().copied();
|
||||
|
||||
assert_eq!(xs().partial_cmp_by(ys(), f), None);
|
||||
assert_eq!(ys().partial_cmp_by(xs(), f), Some(Ordering::Greater));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_by() {
|
||||
let f = |x: i32, y: i32| x * x == y;
|
||||
let xs = || [1, 2, 3, 4].iter().copied();
|
||||
let ys = || [1, 4, 9, 16].iter().copied();
|
||||
|
||||
assert!(xs().eq_by(ys(), f));
|
||||
assert!(!ys().eq_by(xs(), f));
|
||||
assert!(!xs().eq_by(xs(), f));
|
||||
assert!(!ys().eq_by(ys(), f));
|
||||
|
||||
assert!(!xs().take(3).eq_by(ys(), f));
|
||||
assert!(!xs().eq_by(ys().take(3), f));
|
||||
assert!(xs().take(3).eq_by(ys().take(3), f));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_counter_from_iter() {
|
||||
let it = (0..).step_by(5).take(10);
|
||||
@ -329,6 +385,23 @@ fn test_iterator_step_by_nth_overflow() {
|
||||
assert_eq!(it.0, (usize::MAX as Bigger) * 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_step_by_nth_try_fold() {
|
||||
let mut it = (0..).step_by(10);
|
||||
assert_eq!(it.try_fold(0, i8::checked_add), None);
|
||||
assert_eq!(it.next(), Some(60));
|
||||
assert_eq!(it.try_fold(0, i8::checked_add), None);
|
||||
assert_eq!(it.next(), Some(90));
|
||||
|
||||
let mut it = (100..).step_by(10);
|
||||
assert_eq!(it.try_fold(50, i8::checked_add), None);
|
||||
assert_eq!(it.next(), Some(110));
|
||||
|
||||
let mut it = (100..=100).step_by(10);
|
||||
assert_eq!(it.next(), Some(100));
|
||||
assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_step_by_nth_back() {
|
||||
let mut it = (0..16).step_by(5);
|
||||
@ -354,6 +427,24 @@ fn test_iterator_step_by_nth_back() {
|
||||
assert_eq!(it().nth_back(42), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_step_by_nth_try_rfold() {
|
||||
let mut it = (0..100).step_by(10);
|
||||
assert_eq!(it.try_rfold(0, i8::checked_add), None);
|
||||
assert_eq!(it.next_back(), Some(70));
|
||||
assert_eq!(it.next(), Some(0));
|
||||
assert_eq!(it.try_rfold(0, i8::checked_add), None);
|
||||
assert_eq!(it.next_back(), Some(30));
|
||||
|
||||
let mut it = (0..100).step_by(10);
|
||||
assert_eq!(it.try_rfold(50, i8::checked_add), None);
|
||||
assert_eq!(it.next_back(), Some(80));
|
||||
|
||||
let mut it = (100..=100).step_by(10);
|
||||
assert_eq!(it.next_back(), Some(100));
|
||||
assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_iterator_step_by_zero() {
|
||||
@ -1688,6 +1779,12 @@ fn test_rposition() {
|
||||
assert!(v.iter().rposition(g).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_rposition() {
|
||||
let v = [0, 0, 1, 1];
|
||||
assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rposition_panic() {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(bound_cloned)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_update)]
|
||||
@ -32,6 +33,8 @@
|
||||
#![feature(const_fn)]
|
||||
#![feature(iter_partition_in_place)]
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(iter_order_by)]
|
||||
#![feature(cmp_min_max_by)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
@ -40,6 +43,7 @@ mod any;
|
||||
mod array;
|
||||
mod ascii;
|
||||
mod atomic;
|
||||
mod bool;
|
||||
mod cell;
|
||||
mod char;
|
||||
mod clone;
|
||||
|
@ -13,8 +13,3 @@ pub mod derived_property {
|
||||
pub mod conversions {
|
||||
pub use crate::unicode::tables::conversions::{to_lower, to_upper};
|
||||
}
|
||||
|
||||
// For use in libsyntax
|
||||
pub mod property {
|
||||
pub use crate::unicode::tables::property::Pattern_White_Space;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ def get_codepoints(f):
|
||||
yield Codepoint(codepoint, class_)
|
||||
prev_codepoint = codepoint
|
||||
|
||||
if class_first != None:
|
||||
if class_first is not None:
|
||||
raise ValueError("Missing Last after First")
|
||||
|
||||
for c in range(prev_codepoint + 1, NUM_CODEPOINTS):
|
||||
|
@ -890,384 +890,9 @@ pub(crate) mod derived_property {
|
||||
Uppercase_table.lookup(c)
|
||||
}
|
||||
|
||||
const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
|
||||
0xffffffffffffffff, 0xb8dfffffffffffff, 0xfffffffbffffd7c0, 0xffbfffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffcfb, 0xffffffffffffffff,
|
||||
0xfffeffffffffffff, 0xffffffff027fffff, 0xbffffffffffe01ff, 0x000787ffffff00b6,
|
||||
0xffffffff07ff0000, 0xffffc3ffffffffff, 0xffffffffffffffff, 0x9ffffdff9fefffff,
|
||||
0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x243fffffffffffff
|
||||
],
|
||||
r2: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46, 47, 4, 48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 4, 61, 4, 62, 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60, 60, 60, 60, 60, 60, 86,
|
||||
42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62, 4, 102, 103,
|
||||
104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114,
|
||||
115, 116, 97, 117, 4, 118, 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128,
|
||||
129
|
||||
],
|
||||
r3: &[
|
||||
0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff80000,
|
||||
0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x5003ffcfb080799f,
|
||||
0xd36dfdfffff987ee, 0x003fffc05e023987, 0xf3edfdfffffbbfee, 0xfe00ffcf00013bbf,
|
||||
0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
|
||||
0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
|
||||
0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
|
||||
0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f,
|
||||
0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
|
||||
0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff,
|
||||
0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
|
||||
0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
|
||||
0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x001fffff001fdfff, 0x000ddfff000fffff,
|
||||
0x000003ff308fffff, 0xffffffff03ff3800, 0x01ffffffffffffff, 0xffff07ffffffffff,
|
||||
0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
|
||||
0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
|
||||
0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
|
||||
0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff,
|
||||
0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
|
||||
0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
|
||||
0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
|
||||
0xffffffff7fffffff, 0x000ff81fffffffff, 0xffff20bfffffffff, 0x800080ffffffffff,
|
||||
0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
|
||||
0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
|
||||
0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
|
||||
0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
|
||||
0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
|
||||
0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
|
||||
0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff,
|
||||
0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
|
||||
0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
|
||||
0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
|
||||
0xaa8a00000000e000, 0x1fffffffffffffff, 0x87fffffe03ff0000, 0xffffffc007fffffe,
|
||||
0x7fffffffffffffff, 0x000000001cfcfcfc
|
||||
],
|
||||
r4: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
|
||||
14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
],
|
||||
r5: &[
|
||||
0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
|
||||
2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
|
||||
33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45,
|
||||
46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4,
|
||||
4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4,
|
||||
4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
|
||||
4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2,
|
||||
2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95,
|
||||
96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||||
],
|
||||
r6: &[
|
||||
0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
|
||||
0x0000000000000000, 0x001fffffffffffff, 0x2000000000000000, 0xffffffff1fffffff,
|
||||
0x000000010001ffff, 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff,
|
||||
0x00000000003eff0f, 0xffff03ff3fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff,
|
||||
0x0000000fffffffff, 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f,
|
||||
0x007fffff003fffff, 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff,
|
||||
0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
|
||||
0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
|
||||
0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
|
||||
0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000,
|
||||
0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff,
|
||||
0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f,
|
||||
0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
|
||||
0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff,
|
||||
0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff,
|
||||
0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff,
|
||||
0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff,
|
||||
0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
|
||||
0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f,
|
||||
0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000,
|
||||
0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
|
||||
0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c,
|
||||
0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
|
||||
0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
|
||||
0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff,
|
||||
0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff,
|
||||
0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff,
|
||||
0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
|
||||
0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
|
||||
],
|
||||
};
|
||||
|
||||
pub fn XID_Continue(c: char) -> bool {
|
||||
XID_Continue_table.lookup(c)
|
||||
}
|
||||
|
||||
const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
|
||||
0x0000000000000000, 0xb8df000000000000, 0xfffffffbffffd740, 0xffbfffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
|
||||
0xfffeffffffffffff, 0xffffffff027fffff, 0x00000000000001ff, 0x000787ffffff0000,
|
||||
0xffffffff00000000, 0xfffec000000007ff, 0xffffffffffffffff, 0x9c00c060002fffff,
|
||||
0x0000fffffffd0000, 0xffffffffffffe000, 0x0002003fffffffff, 0x043007fffffffc00
|
||||
],
|
||||
r2: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 3, 61, 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34,
|
||||
34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 78,
|
||||
79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87, 88, 34, 89, 90, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 53, 3, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94,
|
||||
95, 96, 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
|
||||
111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34,
|
||||
116, 34, 117, 118, 119, 120, 121, 34, 122, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128,
|
||||
129, 130, 131, 132
|
||||
],
|
||||
r3: &[
|
||||
0x00000110043fffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0x0000000000000000,
|
||||
0x23fffffffffffff0, 0xfffe0003ff010000, 0x23c5fdfffff99fe1, 0x10030003b0004000,
|
||||
0x036dfdfffff987e0, 0x001c00005e000000, 0x23edfdfffffbbfe0, 0x0200000300010000,
|
||||
0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000,
|
||||
0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000,
|
||||
0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f,
|
||||
0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001,
|
||||
0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000,
|
||||
0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,
|
||||
0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
|
||||
0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
|
||||
0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x0003ffff0003dfff, 0x0001dfff0003ffff,
|
||||
0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x01ffffffffffffff,
|
||||
0xffff05ffffffffff, 0x003fffffffffffff, 0x000000007fffffff, 0x001f3fffffff0000,
|
||||
0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
|
||||
0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
|
||||
0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
|
||||
0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
|
||||
0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
|
||||
0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
|
||||
0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
|
||||
0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
|
||||
0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
|
||||
0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
|
||||
0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c,
|
||||
0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
|
||||
0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
|
||||
0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
|
||||
0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
|
||||
0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb,
|
||||
0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
|
||||
0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000,
|
||||
0x1fffffffffffffff, 0x07fffffe00000000, 0xffffffc007fffffe, 0x7fffffff3fffffff,
|
||||
0x000000001cfcfcfc
|
||||
],
|
||||
r4: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
|
||||
14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
],
|
||||
r5: &[
|
||||
0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
|
||||
2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
|
||||
32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44,
|
||||
20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56,
|
||||
57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70,
|
||||
4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2,
|
||||
2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90,
|
||||
91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||||
],
|
||||
r6: &[
|
||||
0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
|
||||
0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff,
|
||||
0xffffe000ffffffff, 0x003fffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f,
|
||||
0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
|
||||
0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
|
||||
0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
|
||||
0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
|
||||
0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
|
||||
0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000,
|
||||
0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8,
|
||||
0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff,
|
||||
0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780,
|
||||
0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000,
|
||||
0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff,
|
||||
0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff,
|
||||
0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff,
|
||||
0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f,
|
||||
0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff,
|
||||
0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f,
|
||||
0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff,
|
||||
0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff,
|
||||
0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
|
||||
0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
|
||||
0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff,
|
||||
0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef,
|
||||
0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
|
||||
0x00000001ffffffff, 0x000000003fffffff
|
||||
],
|
||||
};
|
||||
|
||||
pub fn XID_Start(c: char) -> bool {
|
||||
XID_Start_table.lookup(c)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub(crate) mod property {
|
||||
const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
|
||||
],
|
||||
r2: &[
|
||||
0x0000000100003e00, 0x0000000000000000, 0x0000000000000020, 0x000003000000c000
|
||||
],
|
||||
};
|
||||
|
||||
pub fn Pattern_White_Space(c: char) -> bool {
|
||||
Pattern_White_Space_table.lookup(c)
|
||||
}
|
||||
|
||||
const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user