273 changes: 249 additions & 24 deletions RELEASES.md

Large diffs are not rendered by default.

23 changes: 8 additions & 15 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
environment:
SCCACHE_BUCKET: rust-lang-ci-sccache2
SCCACHE_REGION: us-west-1
AWS_ACCESS_KEY_ID: AKIAJAMV3QAMMA6AXHFQ
AWS_SECRET_ACCESS_KEY:
secure: 7Y+JiquYedOAgnUU26uL0DPzrxmTtR+qIwG6rNKSuWDffqU3vVZxbGXim9QpTO80
SCCACHE_DIGEST: f808afabb4a4eb1d7112bcb3fa6be03b61e93412890c88e177c667eb37f46353d7ec294e559b16f9f4b5e894f2185fe7670a0df15fd064889ecbd80f0c34166c
TOOLSTATE_REPO_ACCESS_TOKEN:
secure: gKGlVktr7iuqCoYSxHxDE9ltLOKU0nYDEuQxvWbNxUIW7ri5ppn8L06jQzN0GGzN

# By default schannel checks revocation of certificates unlike some other SSL
# backends, but we've historically had problems on CI where a revocation
Expand Down Expand Up @@ -85,6 +78,7 @@ environment:
--enable-full-tools
--enable-profiler
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
CI_JOB_NAME: dist-x86_64-msvc
- RUST_CONFIGURE_ARGS: >
Expand All @@ -93,6 +87,7 @@ environment:
--enable-full-tools
--enable-profiler
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
CI_JOB_NAME: dist-i686-msvc
- MSYS_BITS: 32
Expand All @@ -101,6 +96,7 @@ environment:
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
MINGW_DIR: mingw32
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
CI_JOB_NAME: dist-i686-mingw
- MSYS_BITS: 64
Expand All @@ -109,6 +105,7 @@ environment:
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
MINGW_DIR: mingw64
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
CI_JOB_NAME: dist-x86_64-mingw

Expand Down Expand Up @@ -231,10 +228,8 @@ before_deploy:
deploy:
- provider: S3
skip_cleanup: true
access_key_id: AKIAJVBODR3IA4O72THQ
secret_access_key:
secure: tQWIE+DJHjXaV4np/3YeETkEmXngtIuIgAO/LYKQaUshGLgN8cBCFGG3cHx5lKLt
access_key_id: $(AWS_ACCESS_KEY_ID)
secret_access_key: $(AWS_SECRET_ACCESS_KEY)
bucket: rust-lang-ci2
set_public: true
region: us-west-1
Expand All @@ -248,10 +243,8 @@ deploy:
# This provider is the same as the one above except that it has a slightly
# different upload directory and a slightly different trigger
- provider: S3
skip_cleanup: true
access_key_id: AKIAJVBODR3IA4O72THQ
secret_access_key:
secure: tQWIE+DJHjXaV4np/3YeETkEmXngtIuIgAO/LYKQaUshGLgN8cBCFGG3cHx5lKLt
access_key_id: $(AWS_ACCESS_KEY_ID)
secret_access_key: $(AWS_SECRET_ACCESS_KEY)
bucket: rust-lang-ci2
set_public: true
region: us-west-1
Expand Down
51 changes: 38 additions & 13 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,9 @@
# Build the profiler runtime
#profiler = false

# Indicates whether the OpenSSL linked into Cargo will be statically linked or
# not. If static linkage is specified then the build system will download a
# known-good version of OpenSSL, compile it, and link it to Cargo.
#openssl-static = false
# Indicates whether the native libraries linked into Cargo will be statically
# linked or not.
#cargo-native-static = false

# Run the build with low priority, by setting the process group's "nice" value
# to +10 on Unix platforms, and by using a "low priority" job object on Windows.
Expand Down Expand Up @@ -243,19 +242,36 @@
# =============================================================================
[rust]

# Indicates that the build should be optimized for debugging Rust. Note that
# this is typically not what you want as it takes an incredibly large amount of
# time to have a debug-mode rustc compile any code (notably libstd). If this
# value is set to `true` it will affect a number of configuration options below
# as well, if unconfigured.
#debug = false

# Whether or not to optimize the compiler and standard library
# Whether or not to optimize the compiler and standard library.
#
# Note: the slowness of the non optimized compiler compiling itself usually
# outweighs the time gains in not doing optimizations, therefore a
# full bootstrap takes much more time with optimize set to false.
# full bootstrap takes much more time with `optimize` set to false.
#optimize = true

# Indicates that the build should be configured for debugging Rust. A
# `debug`-enabled compiler and standard library will be somewhat
# slower (due to e.g. checking of debug assertions) but should remain
# usable.
#
# Note: If this value is set to `true`, it will affect a number of
# configuration options below as well, if they have been left
# unconfigured in this file.
#
# Note: changes to the `debug` setting do *not* affect `optimize`
# above. In theory, a "maximally debuggable" environment would
# set `optimize` to `false` above to assist the introspection
# facilities of debuggers like lldb and gdb. To recreate such an
# environment, explicitly set `optimize` to `false` and `debug`
# to `true`. In practice, everyone leaves `optimize` set to
# `true`, because an unoptimized rustc with debugging
# enabled becomes *unusably slow* (e.g. rust-lang/rust#24840
# reported a 25x slowdown) and bootstrapping the supposed
# "maximally debuggable" environment (notably libstd) takes
# hours to build.
#
#debug = false

# Number of codegen units to use for each compiler invocation. A value of 0
# means "the number of cores on this machine", and 1+ is passed through to the
# compiler.
Expand Down Expand Up @@ -322,6 +338,7 @@

# Flag indicating whether codegen tests will be run or not. If you get an error
# saying that the FileCheck executable is missing, you may want to disable this.
# Also see the target's llvm-filecheck option.
#codegen-tests = true

# Flag indicating whether git info will be retrieved from .git automatically.
Expand Down Expand Up @@ -416,6 +433,10 @@
# target.
#llvm-config = "../path/to/llvm/root/bin/llvm-config"

# Normally the build system can find LLVM's FileCheck utility, but if
# not, you can specify an explicit file name for it.
#llvm-filecheck = "/path/to/FileCheck"

# Path to the custom jemalloc static library to link into the standard library
# by default. This is only used if jemalloc is still enabled above
#jemalloc = "/path/to/jemalloc/libjemalloc_pic.a"
Expand Down Expand Up @@ -476,3 +497,7 @@
# as the one built on Windows will contain backslashes in paths causing problems
# on linux
#src-tarball = true
#

# Whether to allow failures when building tools
#missing-tools = false
771 changes: 421 additions & 350 deletions src/Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ rustfmt-nightly = { path = "tools/rustfmt" }
# here
rustc-workspace-hack = { path = 'tools/rustc-workspace-hack' }

[patch."https://github.com/rust-lang-nursery/rust-clippy"]
[patch."https://github.com/rust-lang/rust-clippy"]
clippy_lints = { path = "tools/clippy/clippy_lints" }
rustc_tools_util = { path = "tools/clippy/rustc_tools_util" }
13 changes: 0 additions & 13 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,6 @@ fn main() {
cmd.arg("--cfg").arg("parallel_queries");
}

if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
cmd.arg("-Z").arg("verify-llvm-ir");
}

let color = match env::var("RUSTC_COLOR") {
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
Err(_) => 0,
};

if color != 0 {
cmd.arg("--color=always");
}

if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
{
cmd.arg("-Dwarnings");
Expand Down
10 changes: 9 additions & 1 deletion src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ def exe_suffix():
return ''

def bootstrap_binary(self):
"""Return the path of the boostrap binary
"""Return the path of the bootstrap binary
>>> rb = RustBuild()
>>> rb.build_dir = "build"
Expand Down Expand Up @@ -632,6 +632,9 @@ def build_bootstrap(self):
target_features += ["-crt-static"]
if target_features:
env["RUSTFLAGS"] += "-C target-feature=" + (",".join(target_features)) + " "
target_linker = self.get_toml("linker", build_section)
if target_linker is not None:
env["RUSTFLAGS"] += "-C linker=" + target_linker + " "

env["PATH"] = os.path.join(self.bin_root(), "bin") + \
os.pathsep + env["PATH"]
Expand Down Expand Up @@ -844,6 +847,11 @@ def bootstrap(help_triggered):
def main():
"""Entry point for the bootstrap process"""
start_time = time()

# x.py help <cmd> ...
if len(sys.argv) > 1 and sys.argv[1] == 'help':
sys.argv = sys.argv[:1] + [sys.argv[2], '-h'] + sys.argv[3:]

help_triggered = (
'-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
try:
Expand Down
42 changes: 34 additions & 8 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl PathSet {
fn has(&self, needle: &Path) -> bool {
match self {
PathSet::Set(set) => set.iter().any(|p| p.ends_with(needle)),
PathSet::Suite(_) => false,
PathSet::Suite(suite) => suite.ends_with(needle),
}
}

Expand Down Expand Up @@ -379,7 +379,6 @@ impl<'a> Builder<'a> {
test::Ui,
test::RunPass,
test::CompileFail,
test::ParseFail,
test::RunFail,
test::RunPassValgrind,
test::MirOpt,
Expand Down Expand Up @@ -444,7 +443,8 @@ impl<'a> Builder<'a> {
doc::RustdocBook,
doc::RustByExample,
doc::RustcBook,
doc::CargoBook
doc::CargoBook,
doc::EditionGuide,
),
Kind::Dist => describe!(
dist::Docs,
Expand Down Expand Up @@ -1000,10 +1000,6 @@ impl<'a> Builder<'a> {
cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
}

if self.config.rust_verify_llvm_ir {
cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
}

cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());

// in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
Expand Down Expand Up @@ -1849,7 +1845,7 @@ mod __test {
);

// Ensure we don't build any compiler artifacts.
assert!(builder.cache.all::<compile::Rustc>().is_empty());
assert!(!builder.cache.contains::<compile::Rustc>());
assert_eq!(
first(builder.cache.all::<test::Crate>()),
&[test::Crate {
Expand All @@ -1861,4 +1857,34 @@ mod __test {
},]
);
}

#[test]
fn test_exclude() {
let mut config = configure(&[], &[]);
config.exclude = vec![
"src/test/run-pass".into(),
"src/tools/tidy".into(),
];
config.cmd = Subcommand::Test {
paths: Vec::new(),
test_args: Vec::new(),
rustc_args: Vec::new(),
fail_fast: true,
doc_tests: DocTests::No,
bless: false,
compare_mode: None,
};

let build = Build::new(config);
let builder = Builder::new(&build);
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);

// Ensure we have really excluded run-pass & tidy
assert!(!builder.cache.contains::<test::RunPass>());
assert!(!builder.cache.contains::<test::Tidy>());

// Ensure other tests are not affected.
assert!(builder.cache.contains::<test::RunPassFullDeps>());
assert!(builder.cache.contains::<test::RustdocUi>());
}
}
25 changes: 13 additions & 12 deletions src/bootstrap/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,21 @@ impl Ord for Interned<String> {
}
}

struct TyIntern<T> {
struct TyIntern<T: Hash + Clone + Eq> {
items: Vec<T>,
set: HashMap<T, Interned<T>>,
}

impl<T: Hash + Clone + Eq> TyIntern<T> {
fn new() -> TyIntern<T> {
impl<T: Hash + Clone + Eq> Default for TyIntern<T> {
fn default() -> Self {
TyIntern {
items: Vec::new(),
set: HashMap::new(),
set: Default::default(),
}
}
}

impl<T: Hash + Clone + Eq> TyIntern<T> {
fn intern_borrow<B>(&mut self, item: &B) -> Interned<T>
where
B: Eq + Hash + ToOwned<Owned=T> + ?Sized,
Expand Down Expand Up @@ -212,19 +214,13 @@ impl<T: Hash + Clone + Eq> TyIntern<T> {
}
}

#[derive(Default)]
pub struct Interner {
strs: Mutex<TyIntern<String>>,
paths: Mutex<TyIntern<PathBuf>>,
}

impl Interner {
fn new() -> Interner {
Interner {
strs: Mutex::new(TyIntern::new()),
paths: Mutex::new(TyIntern::new()),
}
}

pub fn intern_str(&self, s: &str) -> Interned<String> {
self.strs.lock().unwrap().intern_borrow(s)
}
Expand All @@ -238,7 +234,7 @@ impl Interner {
}

lazy_static! {
pub static ref INTERNER: Interner = Interner::new();
pub static ref INTERNER: Interner = Interner::default();
}

/// This is essentially a HashMap which allows storing any type in its input and
Expand Down Expand Up @@ -290,4 +286,9 @@ impl Cache {
v.sort_by_key(|&(a, _)| a);
v
}

#[cfg(test)]
pub fn contains<S: Step>(&self) -> bool {
self.0.borrow().contains_key(&TypeId::of::<S>())
}
}
2 changes: 1 addition & 1 deletion src/bootstrap/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use Build;
use config::Config;

// The version number
pub const CFG_RELEASE_NUM: &str = "1.30.0";
pub const CFG_RELEASE_NUM: &str = "1.31.0";

pub struct GitInfo {
inner: Option<Info>,
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ impl Step for Rustdoc {
target,
"check",
"src/tools/rustdoc",
SourceType::InTree);
SourceType::InTree,
&[]);

let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage));
println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
Expand Down
39 changes: 5 additions & 34 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use build_helper::{output, mtime, up_to_date};
use filetime::FileTime;
use serde_json;

use util::{exe, libdir, is_dylib, CiEnv};
use util::{exe, libdir, is_dylib};
use {Compiler, Mode, GitRepo};
use native;

Expand Down Expand Up @@ -249,7 +249,7 @@ impl Step for StdLink {

fn copy_apple_sanitizer_dylibs(builder: &Builder, native_dir: &Path, platform: &str, into: &Path) {
for &sanitizer in &["asan", "tsan"] {
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let mut src_path = native_dir.join(sanitizer);
src_path.push("build");
src_path.push("lib");
Expand Down Expand Up @@ -569,6 +569,9 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) {
if builder.config.rustc_parallel_queries {
cargo.env("RUSTC_PARALLEL_QUERIES", "1");
}
if builder.config.rust_verify_llvm_ir {
cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -1034,29 +1037,6 @@ pub fn add_to_sysroot(builder: &Builder, sysroot_dst: &Path, stamp: &Path) {
}
}

// Avoiding a dependency on winapi to keep compile times down
#[cfg(unix)]
fn stderr_isatty() -> bool {
use libc;
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
}
#[cfg(windows)]
fn stderr_isatty() -> bool {
type DWORD = u32;
type BOOL = i32;
type HANDLE = *mut u8;
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
extern "system" {
fn GetStdHandle(which: DWORD) -> HANDLE;
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL;
}
unsafe {
let handle = GetStdHandle(STD_ERROR_HANDLE);
let mut out = 0;
GetConsoleMode(handle, &mut out) != 0
}
}

pub fn run_cargo(builder: &Builder,
cargo: &mut Command,
tail_args: Vec<String>,
Expand Down Expand Up @@ -1218,15 +1198,6 @@ pub fn stream_cargo(
cargo.arg("--message-format").arg("json")
.stdout(Stdio::piped());

if stderr_isatty() && builder.ci_env == CiEnv::None &&
// if the terminal is reported as dumb, then we don't want to enable color for rustc
env::var_os("TERM").map(|t| t != *"dumb").unwrap_or(true) {
// since we pass message-format=json to cargo, we need to tell the rustc
// wrapper to give us colored output if necessary. This is because we
// only want Cargo's JSON output, not rustcs.
cargo.env("RUSTC_COLOR", "1");
}

for arg in tail_args {
cargo.arg(arg);
}
Expand Down
24 changes: 18 additions & 6 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ pub struct Config {
pub test_miri: bool,
pub save_toolstates: Option<PathBuf>,
pub print_step_timings: bool,
pub missing_tools: bool,

// Fallback musl-root for all targets
pub musl_root: Option<PathBuf>,
Expand All @@ -148,7 +149,7 @@ pub struct Config {
pub nodejs: Option<PathBuf>,
pub gdb: Option<PathBuf>,
pub python: Option<PathBuf>,
pub openssl_static: bool,
pub cargo_native_static: bool,
pub configure_args: Vec<String>,

// These are either the stage0 downloaded binaries or the locally installed ones.
Expand All @@ -162,6 +163,8 @@ pub struct Config {
pub struct Target {
/// Some(path to llvm-config) if using an external LLVM.
pub llvm_config: Option<PathBuf>,
/// Some(path to FileCheck) if one was specified.
pub llvm_filecheck: Option<PathBuf>,
pub jemalloc: Option<PathBuf>,
pub cc: Option<PathBuf>,
pub cxx: Option<PathBuf>,
Expand Down Expand Up @@ -218,7 +221,7 @@ struct Build {
verbose: Option<usize>,
sanitizers: Option<bool>,
profiler: Option<bool>,
openssl_static: Option<bool>,
cargo_native_static: Option<bool>,
configure_args: Option<Vec<String>>,
local_rebuild: Option<bool>,
print_step_timings: Option<bool>,
Expand Down Expand Up @@ -269,6 +272,7 @@ struct Dist {
gpg_password_file: Option<String>,
upload_addr: Option<String>,
src_tarball: Option<bool>,
missing_tools: Option<bool>,
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -330,6 +334,7 @@ struct Rust {
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct TomlTarget {
llvm_config: Option<String>,
llvm_filecheck: Option<String>,
jemalloc: Option<String>,
cc: Option<String>,
cxx: Option<String>,
Expand Down Expand Up @@ -372,6 +377,7 @@ impl Config {
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
config.rust_codegen_backends_dir = "codegen-backends".to_owned();
config.deny_warnings = true;
config.missing_tools = false;

// set by bootstrap.py
config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set"));
Expand Down Expand Up @@ -424,7 +430,7 @@ impl Config {
}
}).unwrap_or_else(|| TomlConfig::default());

let build = toml.build.clone().unwrap_or(Build::default());
let build = toml.build.clone().unwrap_or_default();
// set by bootstrap.py
config.hosts.push(config.build.clone());
for host in build.host.iter() {
Expand Down Expand Up @@ -468,7 +474,7 @@ impl Config {
set(&mut config.verbose, build.verbose);
set(&mut config.sanitizers, build.sanitizers);
set(&mut config.profiler, build.profiler);
set(&mut config.openssl_static, build.openssl_static);
set(&mut config.cargo_native_static, build.cargo_native_static);
set(&mut config.configure_args, build.configure_args);
set(&mut config.local_rebuild, build.local_rebuild);
set(&mut config.print_step_timings, build.print_step_timings);
Expand Down Expand Up @@ -518,7 +524,7 @@ impl Config {
set(&mut config.llvm_link_shared, llvm.link_shared);
config.llvm_targets = llvm.targets.clone();
config.llvm_experimental_targets = llvm.experimental_targets.clone()
.unwrap_or("WebAssembly;RISCV".to_string());
.unwrap_or_else(|| "WebAssembly;RISCV".to_string());
config.llvm_link_jobs = llvm.link_jobs;
config.llvm_version_suffix = llvm.version_suffix.clone();
config.llvm_clang_cl = llvm.clang_cl.clone();
Expand Down Expand Up @@ -583,6 +589,9 @@ impl Config {
if let Some(ref s) = cfg.llvm_config {
target.llvm_config = Some(config.src.join(s));
}
if let Some(ref s) = cfg.llvm_filecheck {
target.llvm_filecheck = Some(config.src.join(s));
}
if let Some(ref s) = cfg.jemalloc {
target.jemalloc = Some(config.src.join(s));
}
Expand All @@ -607,6 +616,7 @@ impl Config {
config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from);
config.dist_upload_addr = t.upload_addr.clone();
set(&mut config.rust_dist_src, t.src_tarball);
set(&mut config.missing_tools, t.missing_tools);
}

// Now that we've reached the end of our configuration, infer the
Expand All @@ -618,6 +628,9 @@ impl Config {
let default = false;
config.llvm_assertions = llvm_assertions.unwrap_or(default);

let default = true;
config.rust_optimize = optimize.unwrap_or(default);

let default = match &config.channel[..] {
"stable" | "beta" | "nightly" => true,
_ => false,
Expand All @@ -630,7 +643,6 @@ impl Config {
config.debug_jemalloc = debug_jemalloc.unwrap_or(default);
config.rust_debuginfo = debuginfo.unwrap_or(default);
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
config.rust_optimize = optimize.unwrap_or(!default);

let default = config.channel == "dev";
config.ignore_git = ignore_git.unwrap_or(default);
Expand Down
9 changes: 8 additions & 1 deletion src/bootstrap/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ def v(*args):
o("vendor", "build.vendor", "enable usage of vendored Rust crates")
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan)")
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
o("cargo-openssl-static", "build.openssl-static", "static openssl in cargo")
o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
o("profiler", "build.profiler", "build the profiler runtime")
o("emscripten", None, "compile the emscripten backend as well as LLVM")
o("full-tools", None, "enable all tools")
o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")

# Optimization and debugging options. These may be overridden by the release
# channel, etc.
Expand All @@ -95,6 +96,8 @@ def v(*args):
v("bindir", "install.bindir", "install binaries")

v("llvm-root", None, "set LLVM root")
v("llvm-config", None, "set path to llvm-config")
v("llvm-filecheck", None, "set path to LLVM's FileCheck utility")
v("python", "build.python", "set path to python")
v("jemalloc-root", None, "set directory where libjemalloc_pic.a is located")
v("android-cross-path", "target.arm-linux-androideabi.android-ndk",
Expand Down Expand Up @@ -323,6 +326,10 @@ def set(key, value):
set('build.cargo', value + '/bin/cargo')
elif option.name == 'llvm-root':
set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config')
elif option.name == 'llvm-config':
set('target.{}.llvm-config'.format(build()), value)
elif option.name == 'llvm-filecheck':
set('target.{}.llvm-filecheck'.format(build()), value)
elif option.name == 'jemalloc-root':
set('target.{}.jemalloc'.format(build()), value + '/libjemalloc_pic.a')
elif option.name == 'tools':
Expand Down
35 changes: 19 additions & 16 deletions src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use channel;
use util::{libdir, is_dylib, exe};
use builder::{Builder, RunConfig, ShouldRun, Step};
use compile;
use native;
use tool::{self, Tool};
use cache::{INTERNER, Interned};
use time;
Expand Down Expand Up @@ -67,6 +66,14 @@ fn rust_installer(builder: &Builder) -> Command {
builder.tool_cmd(Tool::RustInstaller)
}

fn missing_tool(tool_name: &str, skip: bool) {
if skip {
println!("Unable to build {}, skipping dist", tool_name)
} else {
panic!("Unable to build {}", tool_name)
}
}

#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Docs {
pub stage: u32,
Expand Down Expand Up @@ -982,12 +989,6 @@ impl Step for PlainSourceTarball {
.arg("--debug")
.arg("--vers").arg(CARGO_VENDOR_VERSION)
.arg("cargo-vendor");
if let Some(dir) = builder.openssl_install_dir(builder.config.build) {
builder.ensure(native::Openssl {
target: builder.config.build,
});
cmd.env("OPENSSL_DIR", dir);
}
builder.run(&mut cmd);
}

Expand Down Expand Up @@ -1166,7 +1167,7 @@ impl Step for Rls {
let rls = builder.ensure(tool::Rls {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build RLS, skipping dist"); None })?;
}).or_else(|| { missing_tool("RLS", builder.build.config.missing_tools); None })?;

builder.install(&rls, &image.join("bin"), 0o755);
let doc = image.join("share/doc/rls");
Expand Down Expand Up @@ -1245,24 +1246,26 @@ impl Step for Clippy {
let clippy = builder.ensure(tool::Clippy {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build clippy, skipping dist"); None })?;
}).or_else(|| { missing_tool("clippy", builder.build.config.missing_tools); None })?;
let cargoclippy = builder.ensure(tool::CargoClippy {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build cargo clippy, skipping dist"); None })?;
}).or_else(|| { missing_tool("cargo clippy", builder.build.config.missing_tools); None })?;

builder.install(&clippy, &image.join("bin"), 0o755);
builder.install(&cargoclippy, &image.join("bin"), 0o755);
let doc = image.join("share/doc/clippy");
builder.install(&src.join("README.md"), &doc, 0o644);
builder.install(&src.join("LICENSE"), &doc, 0o644);
builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);

// Prepare the overlay
let overlay = tmp.join("clippy-overlay");
drop(fs::remove_dir_all(&overlay));
t!(fs::create_dir_all(&overlay));
builder.install(&src.join("README.md"), &overlay, 0o644);
builder.install(&src.join("LICENSE"), &doc, 0o644);
builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
builder.create(&overlay.join("version"), &version);

// Generate the installer tarball
Expand Down Expand Up @@ -1324,11 +1327,11 @@ impl Step for Rustfmt {
let rustfmt = builder.ensure(tool::Rustfmt {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build Rustfmt, skipping dist"); None })?;
}).or_else(|| { missing_tool("Rustfmt", builder.build.config.missing_tools); None })?;
let cargofmt = builder.ensure(tool::Cargofmt {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build Cargofmt, skipping dist"); None })?;
}).or_else(|| { missing_tool("Cargofmt", builder.build.config.missing_tools); None })?;

builder.install(&rustfmt, &image.join("bin"), 0o755);
builder.install(&cargofmt, &image.join("bin"), 0o755);
Expand Down Expand Up @@ -1444,8 +1447,8 @@ impl Step for Extended {
tarballs.extend(rls_installer.clone());
tarballs.extend(clippy_installer.clone());
tarballs.extend(rustfmt_installer.clone());
tarballs.extend(llvm_tools_installer.clone());
tarballs.extend(lldb_installer.clone());
tarballs.extend(llvm_tools_installer);
tarballs.extend(lldb_installer);
tarballs.push(analysis_installer);
tarballs.push(std_installer);
if builder.config.docs {
Expand Down
28 changes: 17 additions & 11 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ macro_rules! book {
book!(
Nomicon, "src/doc/nomicon", "nomicon";
Reference, "src/doc/reference", "reference";
EditionGuide, "src/doc/edition-guide", "edition-guide";
RustdocBook, "src/doc/rustdoc", "rustdoc";
RustcBook, "src/doc/rustc", "rustc";
RustByExample, "src/doc/rust-by-example", "rust-by-example";
Expand Down Expand Up @@ -260,22 +261,31 @@ impl Step for TheBook {
let compiler = self.compiler;
let target = self.target;
let name = self.name;
// build book first edition

// build book
builder.ensure(Rustbook {
target,
name: INTERNER.intern_string(format!("{}/first-edition", name)),
name: INTERNER.intern_string(name.to_string()),
});

// build book second edition
// building older edition redirects

let source_name = format!("{}/first-edition", name);
builder.ensure(Rustbook {
target,
name: INTERNER.intern_string(format!("{}/second-edition", name)),
name: INTERNER.intern_string(source_name),
});

// build book 2018 edition
let source_name = format!("{}/second-edition", name);
builder.ensure(Rustbook {
target,
name: INTERNER.intern_string(format!("{}/2018-edition", name)),
name: INTERNER.intern_string(source_name),
});

let source_name = format!("{}/2018-edition", name);
builder.ensure(Rustbook {
target,
name: INTERNER.intern_string(source_name),
});

// build the version info page and CSS
Expand All @@ -284,11 +294,6 @@ impl Step for TheBook {
target,
});

// build the index page
let index = format!("{}/index.md", name);
builder.info(&format!("Documenting book index ({})", target));
invoke_rustdoc(builder, compiler, target, &index);

// build the redirect pages
builder.info(&format!("Documenting book redirect pages ({})", target));
for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) {
Expand Down Expand Up @@ -805,6 +810,7 @@ impl Step for Rustdoc {
"doc",
"src/tools/rustdoc",
SourceType::InTree,
&[]
);

cargo.env("RUSTDOCFLAGS", "--document-private-items");
Expand Down
53 changes: 25 additions & 28 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,6 @@ pub struct Build {
initial_rustc: PathBuf,
initial_cargo: PathBuf,

// Probed tools at runtime
lldb_version: Option<String>,
lldb_python_dir: Option<String>,

// Runtime state filled in later on
// C/C++ compilers and archiver for all targets
cc: HashMap<Interned<String>, cc::Tool>,
Expand Down Expand Up @@ -416,8 +412,6 @@ impl Build {
ar: HashMap::new(),
ranlib: HashMap::new(),
crates: HashMap::new(),
lldb_version: None,
lldb_python_dir: None,
is_sudo,
ci_env: CiEnv::current(),
delayed_failures: RefCell::new(Vec::new()),
Expand Down Expand Up @@ -641,9 +635,28 @@ impl Build {
/// Returns the path to `FileCheck` binary for the specified target
fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
let target_config = self.config.target_config.get(&target);
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) {
s.to_path_buf()
} else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
let llvm_bindir = output(Command::new(s).arg("--bindir"));
Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target))
let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target));
if filecheck.exists() {
filecheck
} else {
// On Fedora the system LLVM installs FileCheck in the
// llvm subdirectory of the libdir.
let llvm_libdir = output(Command::new(s).arg("--libdir"));
let lib_filecheck = Path::new(llvm_libdir.trim())
.join("llvm").join(exe("FileCheck", &*target));
if lib_filecheck.exists() {
lib_filecheck
} else {
// Return the most normal file name, even though
// it doesn't exist, so that any error message
// refers to that.
filecheck
}
}
} else {
let base = self.llvm_out(self.config.build).join("build");
let base = if !self.config.ninja && self.config.build.contains("msvc") {
Expand Down Expand Up @@ -752,7 +765,7 @@ impl Build {

let path = match which {
GitRepo::Rustc => {
let sha = self.rust_info.sha().expect("failed to find sha");
let sha = self.rust_sha().unwrap_or(channel::CFG_RELEASE_NUM);
format!("/rustc/{}", sha)
}
GitRepo::Llvm => format!("/rustc/llvm"),
Expand Down Expand Up @@ -913,25 +926,6 @@ impl Build {
(self.hosts.iter().any(|h| *h == target) || target == self.build)
}

/// Returns the directory that OpenSSL artifacts are compiled into if
/// configured to do so.
fn openssl_dir(&self, target: Interned<String>) -> Option<PathBuf> {
// OpenSSL not used on Windows
if target.contains("windows") {
None
} else if self.config.openssl_static {
Some(self.out.join(&*target).join("openssl"))
} else {
None
}
}

/// Returns the directory that OpenSSL artifacts are installed into if
/// configured as such.
fn openssl_install_dir(&self, target: Interned<String>) -> Option<PathBuf> {
self.openssl_dir(target).map(|p| p.join("install"))
}

/// Given `num` in the form "a.b.c" return a "release string" which
/// describes the release version number.
///
Expand Down Expand Up @@ -1275,6 +1269,9 @@ impl Build {
t!(fs::create_dir_all(dstdir));
drop(fs::remove_file(&dst));
{
if !src.exists() {
panic!("Error: File \"{}\" not found!", src.display());
}
let mut s = t!(fs::File::open(&src));
let mut d = t!(fs::File::create(&dst));
io::copy(&mut s, &mut d).expect("failed to copy");
Expand Down
7 changes: 6 additions & 1 deletion src/bootstrap/mk/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu:
check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu:
$(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl

TESTS_IN_2 := src/test/run-pass src/test/compile-fail src/test/run-pass-fulldeps
TESTS_IN_2 := \
src/test/ui \
src/test/run-pass \
src/test/compile-fail \
src/test/run-pass-fulldeps \
src/tools/linkchecker

appveyor-subset-1:
$(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %)
Expand Down
186 changes: 0 additions & 186 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,189 +531,3 @@ impl Step for TestHelpers {
.compile("rust_test_helpers");
}
}

const OPENSSL_VERS: &'static str = "1.0.2n";
const OPENSSL_SHA256: &'static str =
"370babb75f278c39e0c50e8c4e7493bc0f18db6867478341a832a982fd15a8fe";

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Openssl {
pub target: Interned<String>,
}

impl Step for Openssl {
type Output = ();

fn should_run(run: ShouldRun) -> ShouldRun {
run.never()
}

fn run(self, builder: &Builder) {
if builder.config.dry_run {
return;
}
let target = self.target;
let out = match builder.openssl_dir(target) {
Some(dir) => dir,
None => return,
};

let stamp = out.join(".stamp");
let mut contents = String::new();
drop(File::open(&stamp).and_then(|mut f| f.read_to_string(&mut contents)));
if contents == OPENSSL_VERS {
return
}
t!(fs::create_dir_all(&out));

let name = format!("openssl-{}.tar.gz", OPENSSL_VERS);
let tarball = out.join(&name);
if !tarball.exists() {
let tmp = tarball.with_extension("tmp");
// originally from https://www.openssl.org/source/...
let url = format!("https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/{}",
name);
let mut last_error = None;
for _ in 0..3 {
let status = Command::new("curl")
.arg("-o").arg(&tmp)
.arg("-f") // make curl fail if the URL does not return HTTP 200
.arg(&url)
.status()
.expect("failed to spawn curl");

// Retry if download failed.
if !status.success() {
last_error = Some(status.to_string());
continue;
}

// Ensure the hash is correct.
let mut shasum = if target.contains("apple") ||
builder.config.build.contains("netbsd") {
let mut cmd = Command::new("shasum");
cmd.arg("-a").arg("256");
cmd
} else {
Command::new("sha256sum")
};
let output = output(&mut shasum.arg(&tmp));
let found = output.split_whitespace().next().unwrap();

// If the hash is wrong, probably the download is incomplete or S3 served an error
// page. In any case, retry.
if found != OPENSSL_SHA256 {
last_error = Some(format!(
"downloaded openssl sha256 different\n\
expected: {}\n\
found: {}\n",
OPENSSL_SHA256,
found
));
continue;
}

// Everything is fine, so exit the retry loop.
last_error = None;
break;
}
if let Some(error) = last_error {
panic!("failed to download openssl source: {}", error);
}
t!(fs::rename(&tmp, &tarball));
}
let obj = out.join(format!("openssl-{}", OPENSSL_VERS));
let dst = builder.openssl_install_dir(target).unwrap();
drop(fs::remove_dir_all(&obj));
drop(fs::remove_dir_all(&dst));
builder.run(Command::new("tar").arg("zxf").arg(&tarball).current_dir(&out));

let mut configure = Command::new("perl");
configure.arg(obj.join("Configure"));
configure.arg(format!("--prefix={}", dst.display()));
configure.arg("no-dso");
configure.arg("no-ssl2");
configure.arg("no-ssl3");

let os = match &*target {
"aarch64-linux-android" => "linux-aarch64",
"aarch64-unknown-linux-gnu" => "linux-aarch64",
"aarch64-unknown-linux-musl" => "linux-aarch64",
"aarch64-unknown-netbsd" => "BSD-generic64",
"arm-linux-androideabi" => "android",
"arm-unknown-linux-gnueabi" => "linux-armv4",
"arm-unknown-linux-gnueabihf" => "linux-armv4",
"armv6-unknown-netbsd-eabihf" => "BSD-generic32",
"armv7-linux-androideabi" => "android-armv7",
"armv7-unknown-linux-gnueabihf" => "linux-armv4",
"armv7-unknown-netbsd-eabihf" => "BSD-generic32",
"i586-unknown-linux-gnu" => "linux-elf",
"i586-unknown-linux-musl" => "linux-elf",
"i686-apple-darwin" => "darwin-i386-cc",
"i686-linux-android" => "android-x86",
"i686-unknown-freebsd" => "BSD-x86-elf",
"i686-unknown-linux-gnu" => "linux-elf",
"i686-unknown-linux-musl" => "linux-elf",
"i686-unknown-netbsd" => "BSD-x86-elf",
"mips-unknown-linux-gnu" => "linux-mips32",
"mips64-unknown-linux-gnuabi64" => "linux64-mips64",
"mips64el-unknown-linux-gnuabi64" => "linux64-mips64",
"mipsel-unknown-linux-gnu" => "linux-mips32",
"powerpc-unknown-linux-gnu" => "linux-ppc",
"powerpc-unknown-linux-gnuspe" => "linux-ppc",
"powerpc-unknown-netbsd" => "BSD-generic32",
"powerpc64-unknown-linux-gnu" => "linux-ppc64",
"powerpc64le-unknown-linux-gnu" => "linux-ppc64le",
"powerpc64le-unknown-linux-musl" => "linux-ppc64le",
"s390x-unknown-linux-gnu" => "linux64-s390x",
"sparc-unknown-linux-gnu" => "linux-sparcv9",
"sparc64-unknown-linux-gnu" => "linux64-sparcv9",
"sparc64-unknown-netbsd" => "BSD-sparc64",
"x86_64-apple-darwin" => "darwin64-x86_64-cc",
"x86_64-linux-android" => "linux-x86_64",
"x86_64-unknown-freebsd" => "BSD-x86_64",
"x86_64-unknown-dragonfly" => "BSD-x86_64",
"x86_64-unknown-linux-gnu" => "linux-x86_64",
"x86_64-unknown-linux-gnux32" => "linux-x32",
"x86_64-unknown-linux-musl" => "linux-x86_64",
"x86_64-unknown-netbsd" => "BSD-x86_64",
_ => panic!("don't know how to configure OpenSSL for {}", target),
};
configure.arg(os);
configure.env("CC", builder.cc(target));
for flag in builder.cflags(target, GitRepo::Rustc) {
configure.arg(flag);
}
// There is no specific os target for android aarch64 or x86_64,
// so we need to pass some extra cflags
if target == "aarch64-linux-android" || target == "x86_64-linux-android" {
configure.arg("-mandroid");
configure.arg("-fomit-frame-pointer");
}
if target == "sparc64-unknown-netbsd" {
// Need -m64 to get assembly generated correctly for sparc64.
configure.arg("-m64");
if builder.config.build.contains("netbsd") {
// Disable sparc64 asm on NetBSD builders, it uses
// m4(1)'s -B flag, which NetBSD m4 does not support.
configure.arg("no-asm");
}
}
// Make PIE binaries
// Non-PIE linker support was removed in Lollipop
// https://source.android.com/security/enhancements/enhancements50
if target == "i686-linux-android" {
configure.arg("no-asm");
}
configure.current_dir(&obj);
builder.info(&format!("Configuring openssl for {}", target));
builder.run_quiet(&mut configure);
builder.info(&format!("Building openssl for {}", target));
builder.run_quiet(Command::new("make").arg("-j1").current_dir(&obj));
builder.info(&format!("Installing openssl for {}", target));
builder.run_quiet(Command::new("make").arg("install").arg("-j1").current_dir(&obj));

let mut f = t!(File::create(&stamp));
t!(f.write_all(OPENSSL_VERS.as_bytes()));
}
}
13 changes: 0 additions & 13 deletions src/bootstrap/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,19 +236,6 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
}
}

let run = |cmd: &mut Command| {
cmd.output().map(|output| {
String::from_utf8_lossy(&output.stdout)
.lines().next().unwrap_or_else(|| {
panic!("{:?} failed {:?}", cmd, output)
}).to_string()
})
};
build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
if build.lldb_version.is_some() {
build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
}

if let Some(ref s) = build.config.ccache {
cmd_finder.must_have(s);
}
Expand Down
82 changes: 49 additions & 33 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ impl Step for Cargo {
self.host,
"test",
"src/tools/cargo",
SourceType::Submodule);
SourceType::Submodule,
&[]);

if !builder.fail_fast {
cargo.arg("--no-fail-fast");
Expand Down Expand Up @@ -290,7 +291,8 @@ impl Step for Rls {
host,
"test",
"src/tools/rls",
SourceType::Submodule);
SourceType::Submodule,
&[]);

// Copy `src/tools/rls/test_data` to a writable drive.
let test_workspace_path = builder.out.join("rls-test-data");
Expand Down Expand Up @@ -352,7 +354,8 @@ impl Step for Rustfmt {
host,
"test",
"src/tools/rustfmt",
SourceType::Submodule);
SourceType::Submodule,
&[]);

let dir = testdir(builder, compiler.host);
t!(fs::create_dir_all(&dir));
Expand Down Expand Up @@ -407,7 +410,8 @@ impl Step for Miri {
host,
"test",
"src/tools/miri",
SourceType::Submodule);
SourceType::Submodule,
&[]);

// miri tests need to know about the stage sysroot
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
Expand Down Expand Up @@ -466,7 +470,8 @@ impl Step for Clippy {
host,
"test",
"src/tools/clippy",
SourceType::Submodule);
SourceType::Submodule,
&[]);

// clippy tests need to know about the stage sysroot
cargo.env("SYSROOT", builder.sysroot(compiler));
Expand Down Expand Up @@ -755,10 +760,11 @@ default_test_with_compare_mode!(Ui {
compare_mode: "nll"
});

default_test!(RunPass {
default_test_with_compare_mode!(RunPass {
path: "src/test/run-pass",
mode: "run-pass",
suite: "run-pass"
suite: "run-pass",
compare_mode: "nll"
});

default_test!(CompileFail {
Expand All @@ -767,12 +773,6 @@ default_test!(CompileFail {
suite: "compile-fail"
});

default_test!(ParseFail {
path: "src/test/parse-fail",
mode: "parse-fail",
suite: "parse-fail"
});

default_test!(RunFail {
path: "src/test/run-fail",
mode: "run-fail",
Expand Down Expand Up @@ -811,8 +811,7 @@ default_test!(Incremental {

default_test!(Debuginfo {
path: "src/test/debuginfo",
// What this runs varies depending on the native platform being apple
mode: "debuginfo-XXX",
mode: "debuginfo",
suite: "debuginfo"
});

Expand Down Expand Up @@ -949,18 +948,11 @@ impl Step for Compiletest {
return;
}

if mode == "debuginfo-XXX" {
return if builder.config.build.contains("apple") {
builder.ensure(Compiletest {
mode: "debuginfo-lldb",
..self
});
} else {
builder.ensure(Compiletest {
mode: "debuginfo-gdb",
..self
});
};
if mode == "debuginfo" {
return builder.ensure(Compiletest {
mode: "debuginfo-both",
..self
});
}

builder.ensure(dist::DebuggerScripts {
Expand Down Expand Up @@ -1060,7 +1052,7 @@ impl Step for Compiletest {
let hostflags = flags.clone();
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));

let mut targetflags = flags.clone();
let mut targetflags = flags;
targetflags.push(format!(
"-Lnative={}",
builder.test_helpers_out(target).display()
Expand All @@ -1081,11 +1073,34 @@ impl Step for Compiletest {
if let Some(ref gdb) = builder.config.gdb {
cmd.arg("--gdb").arg(gdb);
}
if let Some(ref vers) = builder.lldb_version {

let run = |cmd: &mut Command| {
cmd.output().map(|output| {
String::from_utf8_lossy(&output.stdout)
.lines().next().unwrap_or_else(|| {
panic!("{:?} failed {:?}", cmd, output)
}).to_string()
})
};
let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") {
// Test against the lldb that was just built.
builder.llvm_out(target)
.join("bin")
.join("lldb")
} else {
PathBuf::from("lldb")
};
let lldb_version = Command::new(&lldb_exe)
.arg("--version")
.output()
.map(|output| { String::from_utf8_lossy(&output.stdout).to_string() })
.ok();
if let Some(ref vers) = lldb_version {
cmd.arg("--lldb-version").arg(vers);
}
if let Some(ref dir) = builder.lldb_python_dir {
cmd.arg("--lldb-python-dir").arg(dir);
let lldb_python_dir = run(Command::new(&lldb_exe).arg("-P")).ok();
if let Some(ref dir) = lldb_python_dir {
cmd.arg("--lldb-python-dir").arg(dir);
}
}

// Get paths from cmd args
Expand Down Expand Up @@ -1761,7 +1776,8 @@ impl Step for CrateRustdoc {
target,
test_kind.subcommand(),
"src/tools/rustdoc",
SourceType::InTree);
SourceType::InTree,
&[]);
if test_kind.subcommand() == "test" && !builder.fail_fast {
cargo.arg("--no-fail-fast");
}
Expand Down
29 changes: 18 additions & 11 deletions src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use util::{exe, add_lib_path};
use compile;
use native;
use channel::GitInfo;
use channel;
use cache::Interned;
use toolstate::ToolState;

Expand Down Expand Up @@ -80,8 +81,8 @@ impl Step for ToolBuild {
"build",
path,
self.source_type,
&self.extra_features,
);
cargo.arg("--features").arg(self.extra_features.join(" "));

let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
Expand Down Expand Up @@ -208,6 +209,7 @@ pub fn prepare_tool_cargo(
command: &'static str,
path: &'static str,
source_type: SourceType,
extra_features: &[String],
) -> Command {
let mut cargo = builder.cargo(compiler, mode, target, command);
let dir = builder.src.join(path);
Expand All @@ -221,10 +223,16 @@ pub fn prepare_tool_cargo(
cargo.env("RUSTC_EXTERNAL_TOOL", "1");
}

if let Some(dir) = builder.openssl_install_dir(target) {
cargo.env("OPENSSL_STATIC", "1");
cargo.env("OPENSSL_DIR", dir);
cargo.env("LIBZ_SYS_STATIC", "1");
let mut features = extra_features.iter().cloned().collect::<Vec<_>>();
if builder.build.config.cargo_native_static {
if path.ends_with("cargo") ||
path.ends_with("rls") ||
path.ends_with("clippy") ||
path.ends_with("rustfmt")
{
cargo.env("LIBZ_SYS_STATIC", "1");
features.push("rustc-workspace-hack/all-static".to_string());
}
}

// if tools are using lzma we want to force the build script to build its
Expand All @@ -233,6 +241,7 @@ pub fn prepare_tool_cargo(

cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel);
cargo.env("CFG_VERSION", builder.rust_version());
cargo.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM);

let info = GitInfo::new(&builder.config, &dir);
if let Some(sha) = info.sha() {
Expand All @@ -244,6 +253,9 @@ pub fn prepare_tool_cargo(
if let Some(date) = info.commit_date() {
cargo.env("CFG_COMMIT_DATE", date);
}
if features.len() > 0 {
cargo.arg("--features").arg(&features.join(", "));
}
cargo
}

Expand Down Expand Up @@ -439,6 +451,7 @@ impl Step for Rustdoc {
"build",
"src/tools/rustdoc",
SourceType::InTree,
&[],
);

// Most tools don't get debuginfo, but rustdoc should.
Expand Down Expand Up @@ -495,9 +508,6 @@ impl Step for Cargo {
}

fn run(self, builder: &Builder) -> PathBuf {
builder.ensure(native::Openssl {
target: self.target,
});
// Cargo depends on procedural macros, which requires a full host
// compiler to be available, so we need to depend on that.
builder.ensure(compile::Rustc {
Expand Down Expand Up @@ -597,9 +607,6 @@ tool_extended!((self, builder),
if clippy.is_some() {
self.extra_features.push("clippy".to_owned());
}
builder.ensure(native::Openssl {
target: self.target,
});
// RLS depends on procedural macros, which requires a full host
// compiler to be available, so we need to depend on that.
builder.ensure(compile::Rustc {
Expand Down
52 changes: 42 additions & 10 deletions src/build_helper/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ pub fn try_run_suppressed(cmd: &mut Command) -> bool {
output.status.success()
}

pub fn gnu_target(target: &str) -> String {
pub fn gnu_target(target: &str) -> &str {
match target {
"i686-pc-windows-msvc" => "i686-pc-win32".to_string(),
"x86_64-pc-windows-msvc" => "x86_64-pc-win32".to_string(),
"i686-pc-windows-gnu" => "i686-w64-mingw32".to_string(),
"x86_64-pc-windows-gnu" => "x86_64-w64-mingw32".to_string(),
s => s.to_string(),
"i686-pc-windows-msvc" => "i686-pc-win32",
"x86_64-pc-windows-msvc" => "x86_64-pc-win32",
"i686-pc-windows-gnu" => "i686-w64-mingw32",
"x86_64-pc-windows-gnu" => "x86_64-w64-mingw32",
s => s,
}
}

Expand Down Expand Up @@ -178,6 +178,37 @@ pub struct NativeLibBoilerplate {
pub out_dir: PathBuf,
}

impl NativeLibBoilerplate {
/// On OSX we don't want to ship the exact filename that compiler-rt builds.
/// This conflicts with the system and ours is likely a wildly different
/// version, so they can't be substituted.
///
/// As a result, we rename it here but we need to also use
/// `install_name_tool` on OSX to rename the commands listed inside of it to
/// ensure it's linked against correctly.
pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) {
if env::var("TARGET").unwrap() != "x86_64-apple-darwin" {
return
}

let dir = self.out_dir.join("build/lib/darwin");
let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name);
let src = dir.join(&format!("lib{}.dylib", name));
let new_name = format!("lib__rustc__{}.dylib", name);
let dst = dir.join(&new_name);

println!("{} => {}", src.display(), dst.display());
fs::rename(&src, &dst).unwrap();
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{}", new_name))
.arg(&dst)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
}
}

impl Drop for NativeLibBoilerplate {
fn drop(&mut self) {
if !thread::panicking() {
Expand All @@ -202,7 +233,8 @@ pub fn native_lib_boilerplate(
let src_dir = current_dir.join("..").join(src_name);
rerun_if_changed_anything_in_dir(&src_dir);

let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or(env::var_os("OUT_DIR").unwrap());
let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(||
env::var_os("OUT_DIR").unwrap());
let out_dir = PathBuf::from(out_dir).join(out_name);
t!(fs::create_dir_all(&out_dir));
if link_name.contains('=') {
Expand All @@ -229,7 +261,7 @@ pub fn native_lib_boilerplate(
pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
-> Result<(NativeLibBoilerplate, String), ()>
{
let (link_name, search_path, dynamic) = match &*env::var("TARGET").unwrap() {
let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() {
"x86_64-unknown-linux-gnu" => (
format!("clang_rt.{}-x86_64", sanitizer_name),
"build/lib/linux",
Expand All @@ -242,8 +274,8 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
),
_ => return Err(()),
};
let to_link = if dynamic {
format!("dylib={}", link_name)
let to_link = if apple {
format!("dylib=__rustc__{}", link_name)
} else {
format!("static={}", link_name)
};
Expand Down
7 changes: 7 additions & 0 deletions src/ci/docker/dist-i686-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ RUN ./build-git.sh
COPY dist-x86_64-linux/build-headers.sh /tmp/
RUN ./build-headers.sh

# OpenSSL requires a more recent version of perl
# with so we install newer ones here
COPY dist-x86_64-linux/build-perl.sh /tmp/
RUN ./build-perl.sh

COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

Expand Down Expand Up @@ -110,3 +115,5 @@ ENV CFLAGS -mstackrealign
# When we build cargo in this container, we don't want it to use the system
# libcurl, instead it should compile its own.
ENV LIBCURL_NO_PKG_CONFIG 1

ENV DIST_REQUIRE_ALL_TOOLS 1
7 changes: 7 additions & 0 deletions src/ci/docker/dist-x86_64-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ RUN ./build-git.sh
COPY dist-x86_64-linux/build-headers.sh /tmp/
RUN ./build-headers.sh

# OpenSSL requires a more recent version of perl
# with so we install newer ones here
COPY dist-x86_64-linux/build-perl.sh /tmp/
RUN ./build-perl.sh

COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

Expand All @@ -106,3 +111,5 @@ ENV DIST_SRC 1
# When we build cargo in this container, we don't want it to use the system
# libcurl, instead it should compile its own.
ENV LIBCURL_NO_PKG_CONFIG 1

ENV DIST_REQUIRE_ALL_TOOLS 1
29 changes: 29 additions & 0 deletions src/ci/docker/dist-x86_64-linux/build-perl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright 2018 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

set -ex
source shared.sh

curl https://www.cpan.org/src/5.0/perl-5.28.0.tar.gz | \
tar xzf -

cd perl-5.28.0

# Gotta do some hackery to tell python about our custom OpenSSL build, but other
# than that fairly normal.
CC=gcc \
CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \
hide_output ./configure.gnu
hide_output make -j10
hide_output make install

cd ..
rm -rf perl-5.28.0
8 changes: 1 addition & 7 deletions src/ci/docker/scripts/musl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,11 @@ shift

export CFLAGS="-fPIC $CFLAGS"

# FIXME: remove the patch when updating to 1.1.20
MUSL=musl-1.1.19
MUSL=musl-1.1.20

# may have been downloaded in a previous run
if [ ! -d $MUSL ]; then
curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
# Patch to fix https://github.com/rust-lang/rust/issues/48967
cd $MUSL && \
curl "https://git.musl-libc.org/cgit/musl/patch/?id=610c5a8524c3d6cd3ac5a5f1231422e7648a3791" |\
patch -p1 && \
cd -
fi

cd $MUSL
Expand Down
1 change: 0 additions & 1 deletion src/ci/docker/wasm32-unknown/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \
src/test/ui \
src/test/run-pass \
src/test/compile-fail \
src/test/parse-fail \
src/test/mir-opt \
src/test/codegen-units \
src/libcore \
11 changes: 9 additions & 2 deletions src/ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-native-static"

if [ "$DIST_SRC" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
Expand All @@ -51,7 +51,7 @@ fi
#
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
# either automatically or manually.
export RUST_RELEASE_CHANNEL=nightly
export RUST_RELEASE_CHANNEL=stable
if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
Expand All @@ -61,6 +61,7 @@ if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
elif [ "$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
fi
else
# We almost always want debug assertions enabled, but sometimes this takes too
Expand All @@ -74,6 +75,12 @@ else
if [ "$NO_LLVM_ASSERTIONS" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
fi

RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
fi

if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-missing-tools"
fi

# We've had problems in the past of shell scripts leaking fds into the sccache
Expand Down
32 changes: 0 additions & 32 deletions src/doc/README.md

This file was deleted.

2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 449 files
1 change: 1 addition & 0 deletions src/doc/edition-guide
Submodule edition-guide added at 419edb
22 changes: 20 additions & 2 deletions src/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
nav {
display: none;
}
#search-input {
width: calc(100% - 58px);
}
#search-but {
cursor: pointer;
}
#search-but, #search-input {
padding: 4px;
border: 1px solid #ccc;
border-radius: 3px;
outline: none;
font-size: 0.7em;
background-color: #fff;
}
#search-but:hover, #search-input:focus {
border-color: #55a9ff;
}
</style>

Welcome to an overview of the documentation provided by the Rust project.
Expand Down Expand Up @@ -45,8 +62,9 @@ accomplishing various tasks.

<div>
<form action="std/index.html" method="get">
<input type="search" name="search"/>
<button>Search</button>
<input id="search-input" type="search" name="search"
placeholder="Search through the standard library"/>
<button id="search-but">Search</button>
</form>
</div>

Expand Down
2 changes: 1 addition & 1 deletion src/doc/nomicon
75 changes: 54 additions & 21 deletions src/doc/not_found.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@
#TOC { display: none; }
.header-section-number { display: none; }
li {list-style-type: none; }
#search-input {
width: calc(100% - 100px);
}
#search-but {
cursor: pointer;
}
#search-but, #search-input {
padding: 4px;
border: 1px solid #ccc;
border-radius: 3px;
outline: none;
font-size: 0.7em;
background-color: #fff;
}
#search-but:hover, #search-input:focus {
border-color: #55a9ff;
}
#search-from {
border: none;
padding: 0;
font-size: 0.7em;
}
</style>

Looks like you've taken a wrong turn.
Expand All @@ -13,11 +35,20 @@ Some things that might be helpful to you though:

# Search

<form action="https://duckduckgo.com/">
<input type="text" id="site-search" name="q" size="80"></input>
<input type="submit" value="Search DuckDuckGo"></form>

Rust doc search: <span id="core-search"></span>
<div>
<form id="search-form" action="https://duckduckgo.com/">
<input id="search-input" type="search" name="q"></input>
<input type="submit" value="Search" id="search-but">
<!--
Don't show the options by default,
since "From the Standary Library" doesn't work without JavaScript
-->
<fieldset id="search-from" style="display:none">
<label><input name="from" value="library" type="radio"> From the Standard Library</label>
<label><input name="from" value="duckduckgo" type="radio" checked> From DuckDuckGo</label>
</fieldset>
</form>
</div>

# Reference

Expand All @@ -44,26 +75,28 @@ function get_url_fragments() {
return op;
}

function populate_site_search() {
var op = get_url_fragments();
function on_submit(event) {
var form = event.target;
var q = form['q'].value;

event.preventDefault();

var search = document.getElementById('site-search');
search.value = op.join(' ') + " site:doc.rust-lang.org";
if (form['from'].value === 'duckduckgo') {
document.location.href = form.action + '?q=' + encodeURIComponent(q + ' site:doc.rust-lang.org');
} else if (form['from'].value === 'library') {
document.location.href = 'std/index.html?search=' + encodeURIComponent(q);
}
}

function populate_rust_search() {
var op = get_url_fragments();
var lt = op.pop();
function populate_search() {
var form = document.getElementById('search-form');
form.addEventListener('submit', on_submit);
document.getElementById('search-from').style.display = '';

// #18540, use a single token
form['from'].value = 'library';

var a = document.createElement("a");
a.href = "https://doc.rust-lang.org/core/?search=" + encodeURIComponent(lt);
a.textContent = lt;
var search = document.getElementById('core-search');
search.innerHTML = "";
search.appendChild(a);
var op = get_url_fragments();
document.getElementById('search-input').value = op.join(' ');
}
populate_site_search();
populate_rust_search();
populate_search();
</script>
2 changes: 1 addition & 1 deletion src/doc/reference
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
5 changes: 5 additions & 0 deletions src/doc/rustc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ This flag will print out help information for `rustc`.

This flag can turn on or off various `#[cfg]` settings.

The value can either be a single identifier or two identifiers separated by `=`.

For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond
to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.

## `-L`: add a directory to the library search path

When looking for external crates, a directory passed to this flag will be searched.
Expand Down
6 changes: 3 additions & 3 deletions src/doc/rustc/src/lints/listing/warn-by-default.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ warning: functions generic over types must be mangled
1 | #[no_mangle]
| ------------ help: remove this attribute
2 | / fn foo<T>(t: T) {
3 | |
3 | |
4 | | }
| |_^
|
Expand Down Expand Up @@ -513,7 +513,7 @@ This will produce:
warning: borrow of packed field requires unsafe function or block (error E0133)
--> src/main.rs:11:13
|
11 | let y = &x.data.0;
11 | let y = &x.data.0;
| ^^^^^^^^^
|
= note: #[warn(safe_packed_borrows)] on by default
Expand Down Expand Up @@ -874,7 +874,7 @@ fn main() {
This will produce:

```text
warning: unused `std::result::Result` which must be used
warning: unused `std::result::Result` that must be used
--> src/main.rs:6:5
|
6 | returns_result();
Expand Down
16 changes: 16 additions & 0 deletions src/doc/rustdoc/src/documentation-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,22 @@ compiles, then the test will fail. However please note that code failing
with the current Rust release may work in a future release, as new features
are added.
```text
/// Only runs on the 2018 edition.
///
/// ```edition2018
/// let result: Result<i32, ParseIntError> = try {
/// "1".parse::<i32>()?
/// + "2".parse::<i32>()?
/// + "3".parse::<i32>()?
/// };
/// ```
```
`edition2018` tells `rustdoc` that the code sample should be compiled the 2018
edition of Rust. Similarly, you can specify `edition2015` to compile the code
with the 2015 edition.
## Syntax reference
The *exact* syntax for code blocks, including the edge cases, can be found
Expand Down
3 changes: 3 additions & 0 deletions src/doc/rustdoc/src/the-doc-attribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ mod bar {

Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere.

One special case: In Rust 2018 and later, if you `pub use` one of your dependencies, `rustdoc` will
not eagerly inline it as a module unless you add `#[doc(inline)}`.

## `#[doc(hidden)]`

Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless
Expand Down
167 changes: 167 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/emit-stack-sizes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# `emit-stack-sizes`

The tracking issue for this feature is: [#54192]

[#54192]: https://github.com/rust-lang/rust/issues/54192

------------------------

The rustc flag `-Z emit-stack-sizes` makes LLVM emit stack size metadata.

> **NOTE**: This LLVM feature only supports the ELF object format as of LLVM
> 8.0. Using this flag with targets that use other object formats (e.g. macOS
> and Windows) will result in it being ignored.
Consider this crate:

```
#![crate_type = "lib"]
use std::ptr;
pub fn foo() {
// this function doesn't use the stack
}
pub fn bar() {
let xs = [0u32; 2];
// force LLVM to allocate `xs` on the stack
unsafe { ptr::read_volatile(&xs.as_ptr()); }
}
```

Using the `-Z emit-stack-sizes` flag produces extra linker sections in the
output *object file*.

``` console
$ rustc -C opt-level=3 --emit=obj foo.rs

$ size -A foo.o
foo.o :
section size addr
.text 0 0
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
.note.GNU-stack 0 0
.eh_frame 72 0
Total 95

$ rustc -C opt-level=3 --emit=obj -Z emit-stack-sizes foo.rs

$ size -A foo.o
foo.o :
section size addr
.text 0 0
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
.stack_sizes 9 0
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
.stack_sizes 9 0
.note.GNU-stack 0 0
.eh_frame 72 0
Total 113
```

As of LLVM 7.0 the data will be written into a section named `.stack_sizes` and
the format is "an array of pairs of function symbol values (pointer size) and
stack sizes (unsigned LEB128)".

``` console
$ objdump -d foo.o

foo.o: file format elf64-x86-64

Disassembly of section .text._ZN3foo3foo17he211d7b4a3a0c16eE:

0000000000000000 <_ZN3foo3foo17he211d7b4a3a0c16eE>:
0: c3 retq

Disassembly of section .text._ZN3foo3bar17h1acb594305f70c2eE:

0000000000000000 <_ZN3foo3bar17h1acb594305f70c2eE>:
0: 48 83 ec 10 sub $0x10,%rsp
4: 48 8d 44 24 08 lea 0x8(%rsp),%rax
9: 48 89 04 24 mov %rax,(%rsp)
d: 48 8b 04 24 mov (%rsp),%rax
11: 48 83 c4 10 add $0x10,%rsp
15: c3 retq

$ objdump -s -j .stack_sizes foo.o

foo.o: file format elf64-x86-64

Contents of section .stack_sizes:
0000 00000000 00000000 00 .........
Contents of section .stack_sizes:
0000 00000000 00000000 10 .........
```

It's important to note that linkers will discard this linker section by default.
To preserve the section you can use a linker script like the one shown below.

``` text
/* file: keep-stack-sizes.x */
SECTIONS
{
/* `INFO` makes the section not allocatable so it won't be loaded into memory */
.stack_sizes (INFO) :
{
KEEP(*(.stack_sizes));
}
}
```

The linker script must be passed to the linker using a rustc flag like `-C
link-arg`.

```
// file: src/main.rs
use std::ptr;
#[inline(never)]
fn main() {
let xs = [0u32; 2];
// force LLVM to allocate `xs` on the stack
unsafe { ptr::read_volatile(&xs.as_ptr()); }
}
```

``` console
$ RUSTFLAGS="-Z emit-stack-sizes" cargo build --release

$ size -A target/release/hello | grep stack_sizes || echo section was not found
section was not found

$ RUSTFLAGS="-Z emit-stack-sizes" cargo rustc --release -- \
-C link-arg=-Wl,-Tkeep-stack-sizes.x \
-C link-arg=-N

$ size -A target/release/hello | grep stack_sizes
.stack_sizes 90 176272

$ # non-allocatable section (flags don't contain the "A" (alloc) flag)
$ readelf -S target/release/hello
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
(..)
[1031] .stack_sizes PROGBITS 000000000002b090 0002b0f0
000000000000005a 0000000000000000 L 5 0 1

$ objdump -s -j .stack_sizes target/release/hello

target/release/hello: file format elf64-x86-64

Contents of section .stack_sizes:
2b090 c0040000 00000000 08f00400 00000000 ................
2b0a0 00080005 00000000 00000810 05000000 ................
2b0b0 00000000 20050000 00000000 10400500 .... ........@..
2b0c0 00000000 00087005 00000000 00000080 ......p.........
2b0d0 05000000 00000000 90050000 00000000 ................
2b0e0 00a00500 00000000 0000 ..........
```

> Author note: I'm not entirely sure why, in *this* case, `-N` is required in
> addition to `-Tkeep-stack-sizes.x`. For example, it's not required when
> producing statically linked files for the ARM Cortex-M architecture.
2 changes: 1 addition & 1 deletion src/doc/unstable-book/src/compiler-flags/profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ cargo run
```

Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created.
You can parse them with [llvm-cov gcov](http://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/marco-c/grcov).
You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov).
20 changes: 20 additions & 0 deletions src/doc/unstable-book/src/language-features/cfg-attr-multi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `cfg_attr_multi`

The tracking issue for this feature is: [#54881]
The RFC for this feature is: [#2539]

[#54881]: https://github.com/rust-lang/rust/issues/54881
[#2539]: https://github.com/rust-lang/rfcs/pull/2539

------------------------

This feature flag lets you put multiple attributes into a `cfg_attr` attribute.

Example:

```rust,ignore
#[cfg_attr(all(), must_use, optimize)]
```

Because `cfg_attr` resolves before procedural macros, this does not affect
macro resolution at all.
49 changes: 0 additions & 49 deletions src/doc/unstable-book/src/language-features/crate-in-paths.md

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ introducing `extern crate` items, using keyword `extern`.

For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.

`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
`::my_crate::a::b` to paths from extern crates by default.
Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect
and resolve to extern crates (built-in or passed with `--extern`).

```rust,ignore
#![feature(extern_in_paths)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# `impl_trait_in_bindings`

The tracking issue for this feature is: [#34511]

[#34511]: https://github.com/rust-lang/rust/issues/34511

------------------------

The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
`let`, `static`, and `const` bindings.

A simple example is:

```rust
#![feature(impl_trait_in_bindings)]

use std::fmt::Debug;

fn main() {
let a: impl Debug + Clone = 42;
let b = a.clone();
println!("{:?}", b); // prints `42`
}
```

Note however that because the types of `a` and `b` are opaque in the above
example, calling inherent methods or methods outside of the specified traits
(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
2 changes: 2 additions & 0 deletions src/doc/unstable-book/src/language-features/lang-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,5 @@ the source code.
- `freeze`: `libcore/marker.rs`
- `debug_trait`: `libcore/fmt/mod.rs`
- `non_zero`: `libcore/nonzero.rs`
- `arc`: `liballoc/sync.rs`
- `rc`: `liballoc/rc.rs`
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ The tracking issue for this feature is: [#35625]

The RFC is: [rfc#1576].

With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry:
With this feature gate enabled, the [list of designators] gains one more entry:

* `literal`: a literal. Examples: 2, "string", 'c'

A `literal` may be followed by anything, similarly to the `ident` specifier.

[rfc#1576]: http://rust-lang.github.io/rfcs/1576-macros-literal-matcher.html
[#35625]: https://github.com/rust-lang/rust/issues/35625
[frags]: ../book/first-edition/macros.html#syntactic-requirements
[list of designators]: ../reference/macros-by-example.html

------------------------
33 changes: 33 additions & 0 deletions src/doc/unstable-book/src/language-features/marker-trait-attr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# `marker_trait_attr`

The tracking issue for this feature is: [#29864]

[#29864]: https://github.com/rust-lang/rust/issues/29864

------------------------

Normally, Rust keeps you from adding trait implementations that could
overlap with each other, as it would be ambiguous which to use. This
feature, however, carves out an exception to that rule: a trait can
opt-in to having overlapping implementations, at the cost that those
implementations are not allowed to override anything (and thus the
trait itself cannot have any associated items, as they're pointless
when they'd need to do the same thing for every type anyway).

```rust
#![feature(marker_trait_attr)]

use std::fmt::{Debug, Display};

#[marker] trait MyMarker {}

impl<T: Debug> MyMarker for T {}
impl<T: Display> MyMarker for T {}

fn foo<T: MyMarker>(t: T) -> T {
t
}
```

This is expected to replace the unstable `overlapping_marker_traits`
feature, which applied to all empty traits (without needing an opt-in).
2 changes: 0 additions & 2 deletions src/doc/unstable-book/src/language-features/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ of extensions. See `Registry::register_syntax_extension` and the

## Tips and tricks

Some of the [macro debugging tips](../book/first-edition/macros.html#debugging-macro-code) are applicable.

You can use `syntax::parse` to turn token trees into
higher-level syntax elements like expressions:

Expand Down
35 changes: 0 additions & 35 deletions src/doc/unstable-book/src/language-features/tool-lints.md

This file was deleted.

4 changes: 1 addition & 3 deletions src/doc/unstable-book/src/language-features/try-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ The tracking issue for this feature is: [#31436]
The `try_blocks` feature adds support for `try` blocks. A `try`
block creates a new scope one can use the `?` operator in.

```rust,ignore
// This code needs the 2018 edition
```rust,edition2018
#![feature(try_blocks)]
use std::num::ParseIntError;
Expand Down
16 changes: 12 additions & 4 deletions src/etc/gdb_rust_pretty_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,11 @@ def to_string(self):
def children(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
val = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
gdb_ptr = val.get_wrapped_value()
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
maybe_uninit_keys = leaf_node.get_child_at_index(3)
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
keys = manually_drop_keys.get_child_at_index(0)
gdb_ptr = keys.get_wrapped_value()
for index in xrange(length):
yield (str(index), gdb_ptr[index])

Expand All @@ -345,9 +348,14 @@ def to_string(self):
def children(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreemap(self.__val)
keys = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
maybe_uninit_keys = leaf_node.get_child_at_index(3)
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
keys = manually_drop_keys.get_child_at_index(0)
keys_ptr = keys.get_wrapped_value()
vals = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(4)
maybe_uninit_vals = leaf_node.get_child_at_index(4)
manually_drop_vals = maybe_uninit_vals.get_child_at_index(1)
vals = manually_drop_vals.get_child_at_index(0)
vals_ptr = vals.get_wrapped_value()
for index in xrange(length):
yield (str(index), keys_ptr[index])
Expand Down
2 changes: 1 addition & 1 deletion src/etc/generate-keyword-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"""

test_dir = os.path.abspath(
os.path.join(os.path.dirname(__file__), '../test/parse-fail')
os.path.join(os.path.dirname(__file__), '../test/ui/parser')
)

for kw in sys.argv[1:]:
Expand Down
52 changes: 27 additions & 25 deletions src/etc/htmldocck.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,65 +15,66 @@
The principle is simple: This script receives a path to generated HTML
documentation and a "template" script, which has a series of check
commands like `@has` or `@matches`. Each command can be used to check if
commands like `@has` or `@matches`. Each command is used to check if
some pattern is present or not present in the particular file or in
the particular node of HTML tree. In many cases, the template script
happens to be a source code given to rustdoc.
a particular node of the HTML tree. In many cases, the template script
happens to be the source code given to rustdoc.
While it indeed is possible to test in smaller portions, it has been
hard to construct tests in this fashion and major rendering errors were
discovered much later. This script is designed for making the black-box
and regression testing of Rustdoc easy. This does not preclude the needs
for unit testing, but can be used to complement related tests by quickly
discovered much later. This script is designed to make black-box and
regression testing of Rustdoc easy. This does not preclude the needs for
unit testing, but can be used to complement related tests by quickly
showing the expected renderings.
In order to avoid one-off dependencies for this task, this script uses
a reasonably working HTML parser and the existing XPath implementation
from Python's standard library. Hopefully we won't render
from Python's standard library. Hopefully, we won't render
non-well-formed HTML.
# Commands
Commands start with an `@` followed by a command name (letters and
hyphens), and zero or more arguments separated by one or more whitespace
and optionally delimited with single or double quotes. The `@` mark
cannot be preceded by a non-whitespace character. Other lines (including
every text up to the first `@`) are ignored, but it is recommended to
avoid the use of `@` in the template file.
characters and optionally delimited with single or double quotes. The `@`
mark cannot be preceded by a non-whitespace character. Other lines
(including every text up to the first `@`) are ignored, but it is
recommended to avoid the use of `@` in the template file.
There are a number of supported commands:
* `@has PATH` checks for the existence of given file.
* `@has PATH` checks for the existence of the given file.
`PATH` is relative to the output directory. It can be given as `-`
which repeats the most recently used `PATH`.
* `@has PATH PATTERN` and `@matches PATH PATTERN` checks for
the occurrence of given `PATTERN` in the given file. Only one
occurrence of given pattern is enough.
the occurrence of the given pattern `PATTERN` in the specified file.
Only one occurrence of the pattern is enough.
For `@has`, `PATTERN` is a whitespace-normalized (every consecutive
whitespace being replaced by one single space character) string.
The entire file is also whitespace-normalized including newlines.
For `@matches`, `PATTERN` is a Python-supported regular expression.
The file remains intact but the regexp is matched with no `MULTILINE`
and `IGNORECASE` option. You can still use a prefix `(?m)` or `(?i)`
The file remains intact but the regexp is matched without the `MULTILINE`
and `IGNORECASE` options. You can still use a prefix `(?m)` or `(?i)`
to override them, and `\A` and `\Z` for definitely matching
the beginning and end of the file.
(The same distinction goes to other variants of these commands.)
* `@has PATH XPATH PATTERN` and `@matches PATH XPATH PATTERN` checks for
the presence of given `XPATH` in the given HTML file, and also
the occurrence of given `PATTERN` in the matching node or attribute.
Only one occurrence of given pattern in the match is enough.
the presence of the given XPath `XPATH` in the specified HTML file,
and also the occurrence of the given pattern `PATTERN` in the matching
node or attribute. Only one occurrence of the pattern in the match
is enough.
`PATH` should be a valid and well-formed HTML file. It does *not*
accept arbitrary HTML5; it should have matching open and close tags
and correct entity references at least.
`XPATH` is an XPath expression to match. This is fairly limited:
`XPATH` is an XPath expression to match. The XPath is fairly limited:
`tag`, `*`, `.`, `//`, `..`, `[@attr]`, `[@attr='value']`, `[tag]`,
`[POS]` (element located in given `POS`), `[last()-POS]`, `text()`
and `@attr` (both as the last segment) are supported. Some examples:
Expand All @@ -85,19 +86,20 @@
- `//h1[@class="fqn"]/span[1]/a[last()]/@class` matches a value of
`class` attribute in the last `a` element (can be followed by more
elements that are not `a`) inside the first `span` in the `h1` with
a class of `fqn`. Note that there cannot be no additional elements
a class of `fqn`. Note that there cannot be any additional elements
between them due to the use of `/` instead of `//`.
Do not try to use non-absolute paths, it won't work due to the flawed
ElementTree implementation. The script rejects them.
For the text matches (i.e. paths not ending with `@attr`), any
subelements are flattened into one string; this is handy for ignoring
highlights for example. If you want to simply check the presence of
given node or attribute, use an empty string (`""`) as a `PATTERN`.
highlights for example. If you want to simply check for the presence of
a given node or attribute, use an empty string (`""`) as a `PATTERN`.
* `@count PATH XPATH COUNT' checks for the occurrence of given XPath
in the given file. The number of occurrences must match the given count.
* `@count PATH XPATH COUNT' checks for the occurrence of the given XPath
in the specified file. The number of occurrences must match the given
count.
* `@has-dir PATH` checks for the existence of the given directory.
Expand Down
2 changes: 1 addition & 1 deletion src/etc/lldb_rust_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def print_std_string_val(val, internal_dict):
#=--------------------------------------------------------------------------------------------------

def print_array_of_values(array_name, data_ptr_val, length, internal_dict):
"""Prints a contigous memory range, interpreting it as values of the
"""Prints a contiguous memory range, interpreting it as values of the
pointee-type of data_ptr_val."""

data_ptr_type = data_ptr_val.type
Expand Down
23 changes: 13 additions & 10 deletions src/liballoc/benches/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::mem;
use std::ptr;

use rand::{Rng, SeedableRng, XorShiftRng};
use rand::distributions::{Standard, Alphanumeric};
use test::{Bencher, black_box};

#[bench]
Expand Down Expand Up @@ -192,18 +193,20 @@ fn gen_descending(len: usize) -> Vec<u64> {
(0..len as u64).rev().collect()
}

const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

fn gen_random(len: usize) -> Vec<u64> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
rng.gen_iter::<u64>().take(len).collect()
let mut rng = XorShiftRng::from_seed(SEED);
rng.sample_iter(&Standard).take(len).collect()
}

fn gen_random_bytes(len: usize) -> Vec<u8> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
rng.gen_iter::<u8>().take(len).collect()
let mut rng = XorShiftRng::from_seed(SEED);
rng.sample_iter(&Standard).take(len).collect()
}

fn gen_mostly_ascending(len: usize) -> Vec<u64> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
let mut rng = XorShiftRng::from_seed(SEED);
let mut v = gen_ascending(len);
for _ in (0usize..).take_while(|x| x * x <= len) {
let x = rng.gen::<usize>() % len;
Expand All @@ -214,7 +217,7 @@ fn gen_mostly_ascending(len: usize) -> Vec<u64> {
}

fn gen_mostly_descending(len: usize) -> Vec<u64> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
let mut rng = XorShiftRng::from_seed(SEED);
let mut v = gen_descending(len);
for _ in (0usize..).take_while(|x| x * x <= len) {
let x = rng.gen::<usize>() % len;
Expand All @@ -225,18 +228,18 @@ fn gen_mostly_descending(len: usize) -> Vec<u64> {
}

fn gen_strings(len: usize) -> Vec<String> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
let mut rng = XorShiftRng::from_seed(SEED);
let mut v = vec![];
for _ in 0..len {
let n = rng.gen::<usize>() % 20 + 1;
v.push(rng.gen_ascii_chars().take(n).collect());
v.push(rng.sample_iter(&Alphanumeric).take(n).collect());
}
v
}

fn gen_big_random(len: usize) -> Vec<[u64; 16]> {
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
rng.gen_iter().map(|x| [x; 16]).take(len).collect()
let mut rng = XorShiftRng::from_seed(SEED);
rng.sample_iter(&Standard).map(|x| [x; 16]).take(len).collect()
}

macro_rules! sort {
Expand Down
98 changes: 34 additions & 64 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@
//!
//! # Examples
//!
//! Creating a box:
//! Move a value from the stack to the heap by creating a [`Box`]:
//!
//! ```
//! let x = Box::new(5);
//! let val: u8 = 5;
//! let boxed: Box<u8> = Box::new(val);
//! ```
//!
//! Move a value from a [`Box`] back to the stack by [dereferencing]:
//!
//! ```
//! let boxed: Box<u8> = Box::new(5);
//! let val: u8 = *boxed;
//! ```
//!
//! Creating a recursive data structure:
Expand Down Expand Up @@ -52,6 +60,9 @@
//! elements are in the list, and so we don't know how much memory to allocate
//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
//! big `Cons` needs to be.
//!
//! [dereferencing]: ../../std/ops/trait.Deref.html
//! [`Box`]: struct.Box.html

#![stable(feature = "rust1", since = "1.0.0")]

Expand All @@ -60,18 +71,17 @@ use core::borrow;
use core::cmp::Ordering;
use core::convert::From;
use core::fmt;
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
use core::future::Future;
use core::hash::{Hash, Hasher};
use core::iter::FusedIterator;
use core::marker::{Unpin, Unsize};
use core::mem;
use core::pin::PinMut;
use core::pin::Pin;
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ptr::{self, NonNull, Unique};
use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
use core::task::{LocalWaker, Poll};

use raw_vec::RawVec;
use pin::PinBox;
use str::from_boxed_utf8_unchecked;

/// A pointer type for heap allocation.
Expand All @@ -97,6 +107,12 @@ impl<T> Box<T> {
pub fn new(x: T) -> Box<T> {
box x
}

#[unstable(feature = "pin", issue = "49150")]
#[inline(always)]
pub fn pinned(x: T) -> Pin<Box<T>> {
(box x).into()
}
}

impl<T: ?Sized> Box<T> {
Expand Down Expand Up @@ -427,6 +443,16 @@ impl<T> From<T> for Box<T> {
}
}

#[unstable(feature = "pin", issue = "49150")]
impl<T> From<Box<T>> for Pin<Box<T>> {
fn from(boxed: Box<T>) -> Self {
// It's not possible to move or replace the insides of a `Pin<Box<T>>`
// when `T: !Unpin`, so it's safe to pin it directly without any
// additional requirements.
unsafe { Pin::new_unchecked(boxed) }
}
}

#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
fn from(slice: &'a [T]) -> Box<[T]> {
Expand Down Expand Up @@ -789,63 +815,7 @@ impl<T> Generator for Box<T>
impl<F: ?Sized + Future + Unpin> Future for Box<F> {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
PinMut::new(&mut **self).poll(cx)
}
}

#[unstable(feature = "futures_api", issue = "50547")]
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
where F: Future<Output = T> + 'a
{
fn into_raw(self) -> *mut () {
Box::into_raw(self) as *mut ()
}

unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
let ptr = ptr as *mut F;
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
pin.poll(cx)
}

unsafe fn drop(ptr: *mut ()) {
drop(Box::from_raw(ptr as *mut F))
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<Sp> Spawn for Box<Sp>
where Sp: Spawn + ?Sized
{
fn spawn_obj(
&mut self,
future: FutureObj<'static, ()>,
) -> Result<(), SpawnObjError> {
(**self).spawn_obj(future)
}

fn status(&self) -> Result<(), SpawnErrorKind> {
(**self).status()
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
fn from(boxed: Box<F>) -> Self {
FutureObj::new(boxed)
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
fn from(boxed: Box<F>) -> Self {
LocalFutureObj::new(boxed)
}
}

#[unstable(feature = "pin", issue = "49150")]
impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
fn from(pinned: PinBox<T>) -> Box<T> {
unsafe { PinBox::unpin(pinned) }
fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
F::poll(Pin::new(&mut *self), lw)
}
}
2 changes: 1 addition & 1 deletion src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ use self::Entry::*;
/// movie_reviews.insert("Office Space", "Deals with real issues in the workplace.");
/// movie_reviews.insert("Pulp Fiction", "Masterpiece.");
/// movie_reviews.insert("The Godfather", "Very enjoyable.");
/// movie_reviews.insert("The Blues Brothers", "Eye lyked it alot.");
/// movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot.");
///
/// // check for a specific one.
/// if !movie_reviews.contains_key("Les Misérables") {
Expand Down
Loading