From 9942012f41620e097d37a6d737584a3790f6b88b Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 27 Mar 2018 13:49:06 -0700 Subject: [PATCH 01/20] Run make tests for file resolution --- .../run-make-fulldeps/resolve-rename/Makefile | 7 +++++++ src/test/run-make-fulldeps/resolve-rename/bar.rs | 15 +++++++++++++++ src/test/run-make-fulldeps/resolve-rename/baz.rs | 15 +++++++++++++++ src/test/run-make-fulldeps/resolve-rename/foo.rs | 13 +++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 src/test/run-make-fulldeps/resolve-rename/Makefile create mode 100644 src/test/run-make-fulldeps/resolve-rename/bar.rs create mode 100644 src/test/run-make-fulldeps/resolve-rename/baz.rs create mode 100644 src/test/run-make-fulldeps/resolve-rename/foo.rs diff --git a/src/test/run-make-fulldeps/resolve-rename/Makefile b/src/test/run-make-fulldeps/resolve-rename/Makefile new file mode 100644 index 0000000000000..4b0c36d01b7a8 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) -C extra-filename=-hash foo.rs + $(RUSTC) bar.rs + mv $(TMPDIR)/libfoo-hash.rlib $(TMPDIR)/libfoo-another-hash.rlib + $(RUSTC) baz.rs diff --git a/src/test/run-make-fulldeps/resolve-rename/bar.rs b/src/test/run-make-fulldeps/resolve-rename/bar.rs new file mode 100644 index 0000000000000..1552b45f2fc16 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/bar.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +extern crate foo; + +pub fn bar() { foo::foo() } diff --git a/src/test/run-make-fulldeps/resolve-rename/baz.rs b/src/test/run-make-fulldeps/resolve-rename/baz.rs new file mode 100644 index 0000000000000..27d801490e425 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/baz.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +extern crate bar; + +pub fn baz() { bar::bar() } diff --git a/src/test/run-make-fulldeps/resolve-rename/foo.rs b/src/test/run-make-fulldeps/resolve-rename/foo.rs new file mode 100644 index 0000000000000..830c289b65f11 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/foo.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +pub fn foo() {} From bd8154784ea205d78c30c18a5908e97718f7a489 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 13 Mar 2018 11:58:53 -0700 Subject: [PATCH 02/20] Take the original extra-filename passed to a crate into account when resolving it as a dependency. Fixes #46816 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/config.rs | 6 ++++++ src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_metadata/creader.rs | 22 +++++++++++++------- src/librustc_metadata/cstore_impl.rs | 3 +++ src/librustc_metadata/encoder.rs | 2 ++ src/librustc_metadata/locator.rs | 30 ++++++++++++++++++++++------ src/librustc_metadata/schema.rs | 5 ++++- 9 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 42cda6a05a1a7..d1f3736556c5d 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -589,6 +589,7 @@ define_dep_nodes!( <'tcx> [input] CrateDisambiguator(CrateNum), [input] CrateHash(CrateNum), [input] OriginalCrateName(CrateNum), + [input] ExtraFileName(CrateNum), [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId }, [] AllTraitImplementations(CrateNum), diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index bb9467305e335..a08cd57b1f7e2 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -466,6 +466,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("looking up the extra filename for a crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> { fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String { format!("looking up implementations of a trait in a crate") diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2bfb687032923..8651619705b42 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -328,6 +328,7 @@ define_maps! { <'tcx> [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, [] fn crate_hash: CrateHash(CrateNum) -> Svh, [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol, + [] fn extra_filename: ExtraFileName(CrateNum) -> String, [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId)) -> Lrc>, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 50a19526ba8c4..fa69eb8e5bc66 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -881,6 +881,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); } DepKind::CrateHash => { force!(crate_hash, krate!()); } DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); } + DepKind::ExtraFileName => { force!(extra_filename, krate!()); } DepKind::AllTraitImplementations => { force!(all_trait_implementations, krate!()); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 13ebb5f61660f..86f495c5fac3a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -262,6 +262,7 @@ impl<'a> CrateLoader<'a> { ident: Symbol, name: Symbol, hash: Option<&Svh>, + extra_filename: Option<&str>, span: Span, path_kind: PathKind, mut dep_kind: DepKind) @@ -277,6 +278,7 @@ impl<'a> CrateLoader<'a> { ident, crate_name: name, hash: hash.map(|a| &*a), + extra_filename: extra_filename, filesearch: self.sess.target_filesearch(path_kind), target: &self.sess.target.target, triple: &self.sess.opts.target_triple, @@ -409,7 +411,8 @@ impl<'a> CrateLoader<'a> { ::std::iter::once(krate).chain(crate_root.crate_deps .decode(metadata) .map(|dep| { - debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash); + info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash, + dep.extra_filename); if dep.kind == DepKind::UnexportedMacrosOnly { return krate; } @@ -418,7 +421,8 @@ impl<'a> CrateLoader<'a> { _ => dep.kind, }; let (local_cnum, ..) = self.resolve_crate( - root, dep.name, dep.name, Some(&dep.hash), span, PathKind::Dependency, dep_kind, + root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span, + PathKind::Dependency, dep_kind, ); local_cnum })).collect() @@ -437,6 +441,7 @@ impl<'a> CrateLoader<'a> { ident: orig_name, crate_name: rename, hash: None, + extra_filename: None, filesearch: self.sess.host_filesearch(PathKind::Crate), target: &self.sess.host, triple: &host_triple, @@ -664,7 +669,7 @@ impl<'a> CrateLoader<'a> { let dep_kind = DepKind::Implicit; let (cnum, data) = - self.resolve_crate(&None, name, name, None, DUMMY_SP, PathKind::Crate, dep_kind); + self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a panic runtime // and the panic strategy is indeed what we thought it was. @@ -771,7 +776,7 @@ impl<'a> CrateLoader<'a> { let symbol = Symbol::intern(name); let dep_kind = DepKind::Explicit; let (_, data) = - self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime @@ -794,7 +799,7 @@ impl<'a> CrateLoader<'a> { let symbol = Symbol::intern("profiler_builtins"); let dep_kind = DepKind::Implicit; let (_, data) = - self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -909,6 +914,7 @@ impl<'a> CrateLoader<'a> { name, name, None, + None, DUMMY_SP, PathKind::Crate, DepKind::Implicit); @@ -1059,7 +1065,8 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { }; let (cnum, ..) = self.resolve_crate( - &None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind, + &None, item.ident.name, orig_name, None, None, + item.span, PathKind::Crate, dep_kind, ); let def_id = definitions.opt_local_def_id(item.id).unwrap(); @@ -1074,6 +1081,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { } fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum { - self.resolve_crate(&None, name, name, None, span, PathKind::Crate, DepKind::Explicit).0 + self.resolve_crate(&None, name, name, None, None, span, PathKind::Crate, + DepKind::Explicit).0 } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5fd8ebaa9b4a6..f63edf07fa8ba 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -213,6 +213,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, crate_hash => { cdata.hash() } original_crate_name => { cdata.name() } + extra_filename => { cdata.root.extra_filename.clone() } + + implementations_of_trait => { let mut result = vec![]; let filter = Some(other); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 39de1ec852ec4..0da6fc5b9eda1 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -462,6 +462,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let has_global_allocator = tcx.sess.has_global_allocator.get(); let root = self.lazy(&CrateRoot { name: tcx.crate_name(LOCAL_CRATE), + extra_filename: tcx.sess.opts.cg.extra_filename.clone(), triple: tcx.sess.opts.target_triple.clone(), hash: link_meta.crate_hash, disambiguator: tcx.sess.local_crate_disambiguator(), @@ -1357,6 +1358,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { name: self.tcx.original_crate_name(cnum), hash: self.tcx.crate_hash(cnum), kind: self.tcx.dep_kind(cnum), + extra_filename: self.tcx.extra_filename(cnum), }; (cnum, dep) }) diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 41e10b4755d01..f553c55ae56fa 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -83,7 +83,10 @@ //! 1. Does the filename match an rlib/dylib pattern? That is to say, does the //! filename have the right prefix/suffix? //! 2. Does the filename have the right prefix for the crate name being queried? -//! This is filtering for files like `libfoo*.rlib` and such. +//! This is filtering for files like `libfoo*.rlib` and such. If the crate +//! we're looking for was originally compiled with -C extra-filename, the +//! extra filename will be included in this prefix to reduce reading +//! metadata from crates that would otherwise share our prefix. //! 3. Is the file an actual rust library? This is done by loading the metadata //! from the library and making sure it's actually there. //! 4. Does the name in the metadata agree with the name of the library? @@ -236,6 +239,7 @@ use syntax_pos::Span; use rustc_back::target::{Target, TargetTriple}; use std::cmp; +use std::collections::HashSet; use std::fmt; use std::fs; use std::io::{self, Read}; @@ -256,6 +260,7 @@ pub struct Context<'a> { pub ident: Symbol, pub crate_name: Symbol, pub hash: Option<&'a Svh>, + pub extra_filename: Option<&'a str>, // points to either self.sess.target.target or self.sess.host, must match triple pub target: &'a Target, pub triple: &'a TargetTriple, @@ -303,7 +308,12 @@ impl CratePaths { impl<'a> Context<'a> { pub fn maybe_load_library_crate(&mut self) -> Option { - self.find_library_crate() + let mut seen_paths = HashSet::new(); + match self.extra_filename { + Some(s) => self.find_library_crate(s, &mut seen_paths) + .or_else(|| self.find_library_crate("", &mut seen_paths)), + None => self.find_library_crate("", &mut seen_paths) + } } pub fn report_errs(&mut self) -> ! { @@ -419,7 +429,10 @@ impl<'a> Context<'a> { unreachable!(); } - fn find_library_crate(&mut self) -> Option { + fn find_library_crate(&mut self, + extra_prefix: &str, + seen_paths: &mut HashSet) + -> Option { // If an SVH is specified, then this is a transitive dependency that // must be loaded via -L plus some filtering. if self.hash.is_none() { @@ -434,9 +447,9 @@ impl<'a> Context<'a> { let staticpair = self.staticlibname(); // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" - let dylib_prefix = format!("{}{}", dypair.0, self.crate_name); - let rlib_prefix = format!("lib{}", self.crate_name); - let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name); + let dylib_prefix = format!("{}{}{}", dypair.0, self.crate_name, extra_prefix); + let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix); + let staticlib_prefix = format!("{}{}{}", staticpair.0, self.crate_name, extra_prefix); let mut candidates = FxHashMap(); let mut staticlibs = vec![]; @@ -476,6 +489,7 @@ impl<'a> Context<'a> { } return FileDoesntMatch; }; + info!("lib candidate: {}", path.display()); let hash_str = hash.to_string(); @@ -484,6 +498,10 @@ impl<'a> Context<'a> { let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot; fs::canonicalize(path) .map(|p| { + if seen_paths.contains(&p) { + return FileDoesntMatch + }; + seen_paths.insert(p.clone()); match found_kind { CrateFlavor::Rlib => { rlibs.insert(p, kind); } CrateFlavor::Rmeta => { rmetas.insert(p, kind); } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index d04a4001c5023..a7ee0e7e9a961 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -188,6 +188,7 @@ pub enum LazyState { pub struct CrateRoot { pub name: Symbol, pub triple: TargetTriple, + pub extra_filename: String, pub hash: hir::svh::Svh, pub disambiguator: CrateDisambiguator, pub panic_strategy: PanicStrategy, @@ -216,12 +217,14 @@ pub struct CrateDep { pub name: ast::Name, pub hash: hir::svh::Svh, pub kind: DepKind, + pub extra_filename: String, } impl_stable_hash_for!(struct CrateDep { name, hash, - kind + kind, + extra_filename }); #[derive(RustcEncodable, RustcDecodable)] From cd09c2b2abf2c03b80d0d48c9828004ade64a8f8 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Tue, 27 Mar 2018 23:09:35 +0200 Subject: [PATCH 03/20] Flush executables to disk after linkage A problem caused by not doing so in Chrome has been reported here: https://randomascii.wordpress.com/2018/02/25/compiler-bug-linker-bug-windows-kernel-bug/amp/ File::sync_all() calls FlushFileBuffers() down the line, causing potentially unflushed buffers on high I/O-load systems to flush and prevent nasty non-reproducible bugs. The force-flush is only done on Windows and if the linker exited successfully Closes #48545 --- src/librustc_trans/back/link.rs | 36 ++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 75ba83a7c620a..33f6ce9975e53 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -692,7 +692,7 @@ fn link_natively(sess: &Session, loop { i += 1; prog = time(sess, "running linker", || { - exec_linker(sess, &mut cmd, tmpdir) + exec_linker(sess, &mut cmd, out_filename, tmpdir) }); let output = match prog { Ok(ref output) => output, @@ -819,7 +819,7 @@ fn link_natively(sess: &Session, } } -fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) +fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &Path) -> io::Result { // When attempting to spawn the linker we run a risk of blowing out the @@ -867,7 +867,37 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) fs::write(&file, &bytes)?; cmd2.arg(format!("@{}", file.display())); info!("invoking linker {:?}", cmd2); - return cmd2.output(); + let output = cmd2.output(); + flush_linked_file(&output, out_filename)?; + return output; + + #[cfg(unix)] + fn flush_linked_file(_: &io::Result, _: &Path) -> io::Result<()> { + Ok(()) + } + + #[cfg(windows)] + fn flush_linked_file(command_output: &io::Result, out_filename: &Path) + -> io::Result<()> + { + // On Windows, under high I/O load, output buffers are sometimes not flushed, + // even long after process exit, causing nasty, non-reproducible output bugs. + // + // File::sync_all() calls FlushFileBuffers() down the line, which solves the problem. + // + // А full writeup of the original Chrome bug can be found at + // randomascii.wordpress.com/2018/02/25/compiler-bug-linker-bug-windows-kernel-bug/amp + + if let &Ok(ref out) = command_output { + if out.status.success() { + if let Ok(of) = fs::File::open(out_filename) { + of.sync_all()?; + } + } + } + + Ok(()) + } #[cfg(unix)] fn command_line_too_big(err: &io::Error) -> bool { From 3787106be6e3a9be377aecc8600a2e57aa1afb58 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Thu, 29 Mar 2018 17:50:57 +0200 Subject: [PATCH 04/20] Also protect first attempt --- src/librustc_trans/back/link.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 33f6ce9975e53..46defb9e73343 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -833,7 +833,11 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: & // there instead of looking at the command line. if !cmd.very_likely_to_exceed_some_spawn_limit() { match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { - Ok(child) => return child.wait_with_output(), + Ok(child) => { + let output = child.wait_with_output(); + flush_linked_file(&output, out_filename)?; + return output; + } Err(ref e) if command_line_too_big(e) => { info!("command line to linker was too big: {}", e); } From 0f5e4191632de4bbc1ef4ef2be26b517861cbff0 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Fri, 2 Mar 2018 06:52:27 +0100 Subject: [PATCH 05/20] Add a generic CAS loop to std::sync::Atomic* This adds a new method to all numeric `Atomic*` types with a safe compare-and-set loop, so users will no longer need to write their own, except in *very* strange circumstances. This solves #48384 with `x.fetch_max(_)`/`x.fetch_min(_)`. It also relates to #48655 (which I misuse as tracking issue for now). *note* This *might* need a crater run because the functions could clash with third party extension traits. --- src/libcore/sync/atomic.rs | 185 +++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index fe5ed5d494224..3d5f63f41b4df 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -949,6 +949,7 @@ macro_rules! atomic_int { $stable_nand:meta, $s_int_type:expr, $int_ref:expr, $extra_feature:expr, + $min_fn:ident, $max_fn:ident, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. /// @@ -1418,6 +1419,128 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); unsafe { atomic_xor(self.v.get(), val, order) } } } + + doc_comment! { + concat!("Fetches the value, and applies a function to it that returns an optional +new value. Returns a `Result` (`Ok(_)` if the function returned `Some(_)`, else `Err(_)`) of the +previous value. + +Note: This may call the function multiple times if the value has been changed from other threads in +the meantime, as long as the function returns `Some(_)`, but the function will have been applied +but once to the stored value. + +# Examples + +```rust +#![feature(no_more_cas)] +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let x = ", stringify!($atomic_type), "::new(7); +assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7)); +assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7)); +assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8)); +assert_eq!(x.load(Ordering::SeqCst), 9); +```"), + #[inline] + #[unstable(feature = "no_more_cas", + reason = "no more CAS loops in user code", + issue = "48655")] + pub fn fetch_update(&self, + mut f: F, + fetch_order: Ordering, + set_order: Ordering) -> Result<$int_type, $int_type> + where F: FnMut($int_type) -> Option<$int_type> { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev + } + } + Err(prev) + } + } + + doc_comment! { + concat!("Maximum with the current value. + +Finds the maximum of the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +#![feature(atomic_min_max)] +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23); +assert_eq!(foo.load(Ordering::SeqCst), 42); +``` + +If you want to obtain the maximum value in one step, you can use the following: + +``` +#![feature(atomic_min_max)] +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +let bar = 42; +let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar); +assert!(max_foo == 42); +```"), + #[inline] + #[unstable(feature = "atomic_min_max", + reason = "easier and faster min/max than writing manual CAS loop", + issue = "48655")] + pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { $max_fn(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Minimum with the current value. + +Finds the minimum of the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +#![feature(atomic_min_max)] +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23); +assert_eq!(foo.load(Ordering::Relaxed), 23); +assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23); +assert_eq!(foo.load(Ordering::Relaxed), 22); +``` + +If you want to obtain the minimum value in one step, you can use the following: + +``` +#![feature(atomic_min_max)] +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(23); +let bar = 12; +let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar); +assert_eq!(min_foo, 12); +```"), + #[inline] + #[unstable(feature = "atomic_min_max", + reason = "easier and faster min/max than writing manual CAS loop", + issue = "48655")] + pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { $min_fn(self.v.get(), val, order) } + } + } + } } } @@ -1432,6 +1555,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "i8", "../../../std/primitive.i8.html", "#![feature(integer_atomics)]\n\n", + atomic_min, atomic_max, i8 AtomicI8 ATOMIC_I8_INIT } #[cfg(target_has_atomic = "8")] @@ -1444,6 +1568,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "u8", "../../../std/primitive.u8.html", "#![feature(integer_atomics)]\n\n", + atomic_umin, atomic_umax, u8 AtomicU8 ATOMIC_U8_INIT } #[cfg(target_has_atomic = "16")] @@ -1456,6 +1581,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "i16", "../../../std/primitive.i16.html", "#![feature(integer_atomics)]\n\n", + atomic_min, atomic_max, i16 AtomicI16 ATOMIC_I16_INIT } #[cfg(target_has_atomic = "16")] @@ -1468,6 +1594,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "u16", "../../../std/primitive.u16.html", "#![feature(integer_atomics)]\n\n", + atomic_umin, atomic_umax, u16 AtomicU16 ATOMIC_U16_INIT } #[cfg(target_has_atomic = "32")] @@ -1480,6 +1607,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "i32", "../../../std/primitive.i32.html", "#![feature(integer_atomics)]\n\n", + atomic_min, atomic_max, i32 AtomicI32 ATOMIC_I32_INIT } #[cfg(target_has_atomic = "32")] @@ -1492,6 +1620,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "u32", "../../../std/primitive.u32.html", "#![feature(integer_atomics)]\n\n", + atomic_umin, atomic_umax, u32 AtomicU32 ATOMIC_U32_INIT } #[cfg(target_has_atomic = "64")] @@ -1504,6 +1633,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "i64", "../../../std/primitive.i64.html", "#![feature(integer_atomics)]\n\n", + atomic_min, atomic_max, i64 AtomicI64 ATOMIC_I64_INIT } #[cfg(target_has_atomic = "64")] @@ -1516,6 +1646,7 @@ atomic_int! { unstable(feature = "atomic_nand", issue = "13226"), "u64", "../../../std/primitive.u64.html", "#![feature(integer_atomics)]\n\n", + atomic_umin, atomic_umax, u64 AtomicU64 ATOMIC_U64_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1528,6 +1659,7 @@ atomic_int!{ unstable(feature = "atomic_nand", issue = "13226"), "isize", "../../../std/primitive.isize.html", "", + atomic_min, atomic_max, isize AtomicIsize ATOMIC_ISIZE_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1540,6 +1672,7 @@ atomic_int!{ unstable(feature = "atomic_nand", issue = "13226"), "usize", "../../../std/primitive.usize.html", "", + atomic_umin, atomic_umax, usize AtomicUsize ATOMIC_USIZE_INIT } @@ -1717,6 +1850,58 @@ unsafe fn atomic_xor(dst: *mut T, val: T, order: Ordering) -> T { } } +/// returns the max value (signed comparison) +#[inline] +unsafe fn atomic_max(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_max_acq(dst, val), + Release => intrinsics::atomic_max_rel(dst, val), + AcqRel => intrinsics::atomic_max_acqrel(dst, val), + Relaxed => intrinsics::atomic_max_relaxed(dst, val), + SeqCst => intrinsics::atomic_max(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + +/// returns the min value (signed comparison) +#[inline] +unsafe fn atomic_min(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_min_acq(dst, val), + Release => intrinsics::atomic_min_rel(dst, val), + AcqRel => intrinsics::atomic_min_acqrel(dst, val), + Relaxed => intrinsics::atomic_min_relaxed(dst, val), + SeqCst => intrinsics::atomic_min(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + +/// returns the max value (signed comparison) +#[inline] +unsafe fn atomic_umax(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_umax_acq(dst, val), + Release => intrinsics::atomic_umax_rel(dst, val), + AcqRel => intrinsics::atomic_umax_acqrel(dst, val), + Relaxed => intrinsics::atomic_umax_relaxed(dst, val), + SeqCst => intrinsics::atomic_umax(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + +/// returns the min value (signed comparison) +#[inline] +unsafe fn atomic_umin(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_umin_acq(dst, val), + Release => intrinsics::atomic_umin_rel(dst, val), + AcqRel => intrinsics::atomic_umin_acqrel(dst, val), + Relaxed => intrinsics::atomic_umin_relaxed(dst, val), + SeqCst => intrinsics::atomic_umin(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + /// An atomic fence. /// /// Depending on the specified order, a fence prevents the compiler and CPU from From e1d3c471d75bbc4360eee17178ccb32dce348542 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Sat, 31 Mar 2018 19:12:29 +0200 Subject: [PATCH 06/20] Open the file as write before trying to flush it This should be enough and shouldn't require append(true) since we're not explicitly writing anything so we're not flushing it so we've no risk of overwriting it --- src/librustc_trans/back/link.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 46defb9e73343..5da4667af910c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -894,7 +894,7 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: & if let &Ok(ref out) = command_output { if out.status.success() { - if let Ok(of) = fs::File::open(out_filename) { + if let Ok(of) = fs::OpenOptions::new().write(true).open(out_filename) { of.sync_all()?; } } From 68b54a5f4368ba1a66ae7d330bb95a8d6eb08c3c Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sun, 1 Apr 2018 18:50:21 +0200 Subject: [PATCH 07/20] add a dist-thumb builder to build rust-std for the THUMB targets the rust-std component only contains the core and compiler-builtins (+c +mem) crates cc #49382 --- src/bootstrap/compile.rs | 75 +++++++++++---------- src/bootstrap/config.rs | 1 + src/bootstrap/dist.rs | 7 +- src/bootstrap/lib.rs | 6 ++ src/bootstrap/sanity.rs | 13 ++++ src/ci/docker/dist-various-3/Dockerfile | 19 ++++++ src/rustc/compiler_builtins_shim/Cargo.toml | 1 + 7 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 src/ci/docker/dist-various-3/Dockerfile diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9f33935b6e933..eaf4ab272c68e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -140,48 +140,55 @@ pub fn std_cargo(build: &Builder, compiler: &Compiler, target: Interned, cargo: &mut Command) { - let mut features = build.std_features(); - if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } - // When doing a local rebuild we tell cargo that we're stage1 rather than - // stage0. This works fine if the local rust and being-built rust have the - // same view of what the default allocator is, but fails otherwise. Since - // we don't have a way to express an allocator preference yet, work - // around the issue in the case of a local rebuild with jemalloc disabled. - if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc { - features.push_str(" force_alloc_system"); - } + if build.no_std(target) == Some(true) { + // for no-std targets we only compile core and compiler-builtins + cargo.arg("--features").arg("c mem") + .arg("--manifest-path") + .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); + } else { + let mut features = build.std_features(); + + // When doing a local rebuild we tell cargo that we're stage1 rather than + // stage0. This works fine if the local rust and being-built rust have the + // same view of what the default allocator is, but fails otherwise. Since + // we don't have a way to express an allocator preference yet, work + // around the issue in the case of a local rebuild with jemalloc disabled. + if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc { + features.push_str(" force_alloc_system"); + } - if compiler.stage != 0 && build.config.sanitizers { - // This variable is used by the sanitizer runtime crates, e.g. - // rustc_lsan, to build the sanitizer runtime from C code - // When this variable is missing, those crates won't compile the C code, - // so we don't set this variable during stage0 where llvm-config is - // missing - // We also only build the runtimes when --enable-sanitizers (or its - // config.toml equivalent) is used - let llvm_config = build.ensure(native::Llvm { - target: build.config.build, - emscripten: false, - }); - cargo.env("LLVM_CONFIG", llvm_config); - } + if compiler.stage != 0 && build.config.sanitizers { + // This variable is used by the sanitizer runtime crates, e.g. + // rustc_lsan, to build the sanitizer runtime from C code + // When this variable is missing, those crates won't compile the C code, + // so we don't set this variable during stage0 where llvm-config is + // missing + // We also only build the runtimes when --enable-sanitizers (or its + // config.toml equivalent) is used + let llvm_config = build.ensure(native::Llvm { + target: build.config.build, + emscripten: false, + }); + cargo.env("LLVM_CONFIG", llvm_config); + } - cargo.arg("--features").arg(features) - .arg("--manifest-path") - .arg(build.src.join("src/libstd/Cargo.toml")); + cargo.arg("--features").arg(features) + .arg("--manifest-path") + .arg(build.src.join("src/libstd/Cargo.toml")); - if let Some(target) = build.config.target_config.get(&target) { - if let Some(ref jemalloc) = target.jemalloc { - cargo.env("JEMALLOC_OVERRIDE", jemalloc); + if let Some(target) = build.config.target_config.get(&target) { + if let Some(ref jemalloc) = target.jemalloc { + cargo.env("JEMALLOC_OVERRIDE", jemalloc); + } } - } - if target.contains("musl") { - if let Some(p) = build.musl_root(target) { - cargo.env("MUSL_ROOT", p); + if target.contains("musl") { + if let Some(p) = build.musl_root(target) { + cargo.env("MUSL_ROOT", p); + } } } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 33850debd3bdb..81b60364ebba1 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -159,6 +159,7 @@ pub struct Target { pub crt_static: Option, pub musl_root: Option, pub qemu_rootfs: Option, + pub no_std: bool, } /// Structure of the `config.toml` file that configuration is read from. diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 23b7b265a94be..32257fefbf97b 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -649,7 +649,12 @@ impl Step for Std { if build.hosts.iter().any(|t| t == target) { builder.ensure(compile::Rustc { compiler, target }); } else { - builder.ensure(compile::Test { compiler, target }); + if build.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 }); + } } let image = tmpdir(build).join(format!("{}-{}-image", name, target)); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 833faf3618d67..d1765b3def998 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -709,6 +709,12 @@ impl Build { .map(|p| &**p) } + /// Returns true if this is a no-std `target`, if defined + fn no_std(&self, target: Interned) -> Option { + self.config.target_config.get(&target) + .map(|t| t.no_std) + } + /// Returns whether the target will be tested using the `remote-test-client` /// and `remote-test-server` binaries. fn remote_tested(&self, target: Interned) -> bool { diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 5184cca653c4b..cd67f1eb46414 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -169,6 +169,19 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on macOS"); } + if target.starts_with("thumbv") { + if build.no_std(*target).is_none() { + let target = build.config.target_config.entry(target.clone()) + .or_insert(Default::default()); + + target.no_std = true; + } + + if build.no_std(*target) == Some(false) { + panic!("All the THUMB targets are no-std targets") + } + } + // Make sure musl-root is valid if target.contains("musl") { // If this is a native target (host is also musl) and no musl-root is given, diff --git a/src/ci/docker/dist-various-3/Dockerfile b/src/ci/docker/dist-various-3/Dockerfile new file mode 100644 index 0000000000000..06c80982f3cd2 --- /dev/null +++ b/src/ci/docker/dist-various-3/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:17.10 + +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +RUN apt-get build-dep -y clang llvm && apt-get install -y --no-install-recommends \ + gcc-arm-none-eabi \ + libnewlib-arm-none-eabi + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV TARGETS=thumbv6m-none-eabi +ENV TARGETS=$TARGETS,thumbv7m-none-eabi +ENV TARGETS=$TARGETS,thumbv7em-none-eabi +ENV TARGETS=$TARGETS,thumbv7em-none-eabihf + +ENV RUST_CONFIGURE_ARGS --disable-docs +ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml index 608e5f5f36d02..7d8423ca84eb4 100644 --- a/src/rustc/compiler_builtins_shim/Cargo.toml +++ b/src/rustc/compiler_builtins_shim/Cargo.toml @@ -35,5 +35,6 @@ cc = "1.0.1" [features] c = [] default = ["c", "rustbuild", "compiler-builtins"] +mem = [] rustbuild = [] compiler-builtins = [] From 2a99c027eb95c471daf50815ec30504c42179300 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sun, 1 Apr 2018 18:56:13 +0200 Subject: [PATCH 08/20] add new image to .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 091a5abdaa216..a67c6c79bbdf8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -116,6 +116,8 @@ matrix: if: branch = auto - env: IMAGE=dist-various-2 DEPLOY=1 if: branch = auto + - env: IMAGE=dist-various-3 DEPLOY=1 + if: branch = auto - env: IMAGE=dist-aarch64-linux DEPLOY=1 if: branch = auto - env: IMAGE=dist-android DEPLOY=1 From cc939ac345091327b23f807b7d1f6a7c75c03f36 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 30 Mar 2018 16:10:47 +0900 Subject: [PATCH 09/20] Add vec![ptr::null{,_mut}(); n] optimization, like vec![0; n] vec![0; n], via implementations of SpecFromElem, has an optimization that uses with_capacity_zeroed instead of with_capacity, which will use calloc instead of malloc, and avoid an extra memset. This adds the same optimization for vec![ptr::null(); n] and vec![ptr::null_mut(); n], assuming their bit value is 0 (which is true on all currently supported platforms). This does so by adding an intermediate trait IsZero, which looks very much like nonzero::Zeroable, but that one is on the way out, and doesn't apply to pointers anyways. Adding such a trait allows to avoid repeating the logic using with_capacity_zeroed or with_capacity, or making the macro more complex to support generics. --- src/liballoc/vec.rs | 79 ++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 2eedb964f88ba..512c74d9d7704 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1567,40 +1567,67 @@ impl SpecFromElem for u8 { } } -macro_rules! impl_spec_from_elem { +impl SpecFromElem for T { + #[inline] + fn from_elem(elem: T, n: usize) -> Vec { + if elem.is_zero() { + return Vec { + buf: RawVec::with_capacity_zeroed(n), + len: n, + } + } + let mut v = Vec::with_capacity(n); + v.extend_with(n, ExtendElement(elem)); + v + } +} + +unsafe trait IsZero { + /// Whether this value is zero + fn is_zero(&self) -> bool; +} + +macro_rules! impl_is_zero { ($t: ty, $is_zero: expr) => { - impl SpecFromElem for $t { + unsafe impl IsZero for $t { #[inline] - fn from_elem(elem: $t, n: usize) -> Vec<$t> { - if $is_zero(elem) { - return Vec { - buf: RawVec::with_capacity_zeroed(n), - len: n, - } - } - let mut v = Vec::with_capacity(n); - v.extend_with(n, ExtendElement(elem)); - v + fn is_zero(&self) -> bool { + $is_zero(*self) } } - }; + } } -impl_spec_from_elem!(i8, |x| x == 0); -impl_spec_from_elem!(i16, |x| x == 0); -impl_spec_from_elem!(i32, |x| x == 0); -impl_spec_from_elem!(i64, |x| x == 0); -impl_spec_from_elem!(i128, |x| x == 0); -impl_spec_from_elem!(isize, |x| x == 0); +impl_is_zero!(i8, |x| x == 0); +impl_is_zero!(i16, |x| x == 0); +impl_is_zero!(i32, |x| x == 0); +impl_is_zero!(i64, |x| x == 0); +impl_is_zero!(i128, |x| x == 0); +impl_is_zero!(isize, |x| x == 0); -impl_spec_from_elem!(u16, |x| x == 0); -impl_spec_from_elem!(u32, |x| x == 0); -impl_spec_from_elem!(u64, |x| x == 0); -impl_spec_from_elem!(u128, |x| x == 0); -impl_spec_from_elem!(usize, |x| x == 0); +impl_is_zero!(u16, |x| x == 0); +impl_is_zero!(u32, |x| x == 0); +impl_is_zero!(u64, |x| x == 0); +impl_is_zero!(u128, |x| x == 0); +impl_is_zero!(usize, |x| x == 0); + +impl_is_zero!(f32, |x: f32| x.to_bits() == 0); +impl_is_zero!(f64, |x: f64| x.to_bits() == 0); + +unsafe impl IsZero for *const T { + #[inline] + fn is_zero(&self) -> bool { + (*self).is_null() + } +} + +unsafe impl IsZero for *mut T { + #[inline] + fn is_zero(&self) -> bool { + (*self).is_null() + } +} -impl_spec_from_elem!(f32, |x: f32| x.to_bits() == 0); -impl_spec_from_elem!(f64, |x: f64| x.to_bits() == 0); //////////////////////////////////////////////////////////////////////////////// // Common trait implementations for Vec From 0df837f79289819f9b671b67d4e63dfe5c80d419 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Mon, 2 Apr 2018 10:44:38 +0900 Subject: [PATCH 10/20] Add vec!['\0'; n] optimization, like vec![0; n] Similarly to vec![ptr::null{,_mut}(); n] in previous change, this adds the optimization for vec!['\0'; n]. --- src/liballoc/vec.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 512c74d9d7704..515b79e5acdc7 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1611,6 +1611,8 @@ impl_is_zero!(u64, |x| x == 0); impl_is_zero!(u128, |x| x == 0); impl_is_zero!(usize, |x| x == 0); +impl_is_zero!(char, |x| x == '\0'); + impl_is_zero!(f32, |x: f32| x.to_bits() == 0); impl_is_zero!(f64, |x: f64| x.to_bits() == 0); From 138472bdc6b428eafc755dbc97b2706fa13a268c Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 24 Mar 2018 18:07:18 +0000 Subject: [PATCH 11/20] Checking location and syntax of non_exhaustive attribute. --- src/librustc/diagnostics.rs | 27 ++++++++++++++++++ src/librustc/hir/check_attr.rs | 27 ++++++++++++++++++ .../invalid-attribute.rs | 28 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index c74ae2343b866..2662e70999196 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2058,6 +2058,33 @@ where 'x: 'y ``` "##, +E0910: r##" +This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed +on something other than a struct or enum. + +Examples of erroneous code: + +```compile_fail,E0910 +# #![feature(non_exhaustive)] + +#[non_exhaustive] +trait Foo { } +``` +"##, + +E0911: r##" +This error indicates that a `#[non_exhaustive]` attribute had a value. The +`#[non_exhaustive]` should be empty. + +Examples of erroneous code: + +```compile_fail,E0911 +# #![feature(non_exhaustive)] + +#[non_exhaustive(anything)] +struct Foo; +``` +"##, } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 316ed07ca05d9..956cd17f38f21 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -66,6 +66,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { for attr in &item.attrs { if attr.check_name("inline") { self.check_inline(attr, &item.span, target) + } else if attr.check_name("non_exhaustive") { + self.check_non_exhaustive(attr, item, target) } else if attr.check_name("wasm_import_module") { has_wasm_import_module = true; if attr.value_str().is_none() { @@ -113,6 +115,31 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } + /// Check if the `#[non_exhaustive]` attribute on an `item` is valid. + fn check_non_exhaustive(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { + match target { + Target::Struct | Target::Enum => { /* Valid */ }, + _ => { + struct_span_err!(self.tcx.sess, + attr.span, + E0910, + "attribute can only be applied to a struct or enum") + .span_label(item.span, "not a struct or enum") + .emit(); + return; + } + } + + if attr.meta_item_list().is_some() || attr.value_str().is_some() { + struct_span_err!(self.tcx.sess, + attr.span, + E0911, + "attribute should be empty") + .span_label(item.span, "not empty") + .emit(); + } + } + /// Check if the `#[repr]` attributes on `item` are valid. fn check_repr(&self, item: &hir::Item, target: Target) { // Extract the names of all repr hints, e.g., [foo, bar, align] for: diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs new file mode 100644 index 0000000000000..e48d989c01d61 --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs @@ -0,0 +1,28 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive(anything)] +//~^ ERROR attribute should be empty [E0911] +struct Foo; + +#[non_exhaustive] +//~^ ERROR attribute can only be applied to a struct or enum [E0910] +trait Bar { } + +#[non_exhaustive] +//~^ ERROR attribute can only be applied to a struct or enum [E0910] +union Baz { + f1: u16, + f2: u16 +} + +fn main() { } From d0693548cdb4fe9e380f7c607c53a2e16821ebc2 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 3 Apr 2018 08:26:24 +0200 Subject: [PATCH 12/20] merge dist-various-3 into dist-various-1 --- .travis.yml | 2 -- src/ci/docker/dist-various-1/Dockerfile | 8 +++++++- src/ci/docker/dist-various-3/Dockerfile | 19 ------------------- 3 files changed, 7 insertions(+), 22 deletions(-) delete mode 100644 src/ci/docker/dist-various-3/Dockerfile diff --git a/.travis.yml b/.travis.yml index a67c6c79bbdf8..091a5abdaa216 100644 --- a/.travis.yml +++ b/.travis.yml @@ -116,8 +116,6 @@ matrix: if: branch = auto - env: IMAGE=dist-various-2 DEPLOY=1 if: branch = auto - - env: IMAGE=dist-various-3 DEPLOY=1 - if: branch = auto - env: IMAGE=dist-aarch64-linux DEPLOY=1 if: branch = auto - env: IMAGE=dist-android DEPLOY=1 diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index b398e9a3c92ef..e61757ff5eea9 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -20,7 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ bzip2 \ patch \ libssl-dev \ - pkg-config + pkg-config \ + gcc-arm-none-eabi \ + libnewlib-arm-none-eabi WORKDIR /build @@ -78,6 +80,10 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu 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 +ENV TARGETS=$TARGETS,thumbv7em-none-eabihf # FIXME: remove armv5te vars after https://github.com/alexcrichton/cc-rs/issues/271 # get fixed and cc update diff --git a/src/ci/docker/dist-various-3/Dockerfile b/src/ci/docker/dist-various-3/Dockerfile deleted file mode 100644 index 06c80982f3cd2..0000000000000 --- a/src/ci/docker/dist-various-3/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM ubuntu:17.10 - -COPY scripts/cross-apt-packages.sh /scripts/ -RUN sh /scripts/cross-apt-packages.sh - -RUN apt-get build-dep -y clang llvm && apt-get install -y --no-install-recommends \ - gcc-arm-none-eabi \ - libnewlib-arm-none-eabi - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV TARGETS=thumbv6m-none-eabi -ENV TARGETS=$TARGETS,thumbv7m-none-eabi -ENV TARGETS=$TARGETS,thumbv7em-none-eabi -ENV TARGETS=$TARGETS,thumbv7em-none-eabihf - -ENV RUST_CONFIGURE_ARGS --disable-docs -ENV SCRIPT python2.7 ../x.py dist --target $TARGETS From 862c839fb9e0ad5615443b7e8fa21b421e2e74eb Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 3 Apr 2018 08:29:09 +0200 Subject: [PATCH 13/20] extend no-std-ness check to all *-none-* targets --- src/bootstrap/sanity.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index cd67f1eb46414..1b1cec5f18c07 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -169,7 +169,7 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on macOS"); } - if target.starts_with("thumbv") { + if target.contains("-none-") { if build.no_std(*target).is_none() { let target = build.config.target_config.entry(target.clone()) .or_insert(Default::default()); @@ -178,7 +178,7 @@ pub fn check(build: &mut Build) { } if build.no_std(*target) == Some(false) { - panic!("All the THUMB targets are no-std targets") + panic!("All the *-none-* targets are no-std targets") } } From 9e9a987a0214609d6a1da4ce8b1dfd7870b40044 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 4 Apr 2018 16:09:01 +0100 Subject: [PATCH 14/20] Documenting private items in compiler docs. --- src/bootstrap/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 44073a5b07572..06340a4e98a47 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -696,6 +696,7 @@ impl Step for Rustc { t!(symlink_dir_force(&out, &out_dir)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); + cargo.env("RUSTDOCFLAGS", "--document-private-items"); compile::rustc_cargo(build, &mut cargo); // Only include compiler crates, no dependencies of those, such as `libc`. From 809d01c62ef25814abf8e490eb80128989985014 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 4 Apr 2018 16:09:58 +0100 Subject: [PATCH 15/20] Updated codeblocks to specify language where required. --- src/librustc/middle/region.rs | 4 ++-- src/librustc/traits/select.rs | 2 ++ src/librustc_resolve/lib.rs | 6 +++--- src/librustc_typeck/check/regionck.rs | 2 ++ src/librustc_typeck/impl_wf_check.rs | 12 ++++++------ 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index c7396b34c4689..7e1b7c08c3dad 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -353,8 +353,8 @@ pub struct ScopeTree { /// the result of `g()` occurs after the yield (and therefore /// doesn't). If we want to infer that, we can look at the /// postorder traversal: - /// ``` - /// `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0 + /// ```plain,ignore + /// `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0 /// ``` /// /// In which we can easily see that `Call#1` occurs before the yield, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 93ae101eb1426..548296b77f9cf 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -362,7 +362,9 @@ enum EvaluationResult { /// When checking `foo`, we have to prove `T: Trait`. This basically /// translates into this: /// + /// ```plain,ignore /// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait + /// ``` /// /// When we try to prove it, we first go the first option, which /// recurses. This shows us that the impl is "useless" - it won't diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 97dcf081f8c8d..3a97d2767444b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -427,14 +427,14 @@ fn generate_fn_name_span(cm: &CodeMap, span: Span) -> Option { /// a new local type parameter. /// /// For instance: -/// ``` +/// ```rust,ignore (pseudo-Rust) /// // Given span /// fn my_function(param: T) -/// ^ Original span +/// // ^ Original span /// /// // Result /// fn my_function(param: T) -/// ^^^^^^^^^^^ Generated span with snippet `my_function` +/// // ^^^^^^^^^^^ Generated span with snippet `my_function` /// ``` /// /// Attention: The method used is very fragile since it essentially duplicates the work of the diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 9ed4ab45a1ba7..b5e862fac958a 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1164,10 +1164,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// constraint that `'z <= 'a`. Given this setup, let's clarify the /// parameters in (roughly) terms of the example: /// + /// ```plain,ignore (pseudo-Rust) /// A borrow of: `& 'z bk * r` where `r` has type `& 'a bk T` /// borrow_region ^~ ref_region ^~ /// borrow_kind ^~ ref_kind ^~ /// ref_cmt ^ + /// ``` /// /// Here `bk` stands for some borrow-kind (e.g., `mut`, `uniq`, etc). /// diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 1eed1bf4b71fb..faf3ccb1133ad 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -42,21 +42,21 @@ use syntax_pos::Span; /// /// Example: /// -/// ``` +/// ```rust,ignore (pseudo-Rust) /// impl Trait for Bar { ... } -/// ^ T does not appear in `Foo` or `Bar`, error! +/// // ^ T does not appear in `Foo` or `Bar`, error! /// /// impl Trait> for Bar { ... } -/// ^ T appears in `Foo`, ok. +/// // ^ T appears in `Foo`, ok. /// /// impl Trait for Bar where Bar: Iterator { ... } -/// ^ T is bound to `::Item`, ok. +/// // ^ T is bound to `::Item`, ok. /// /// impl<'a> Trait for Bar { } -/// ^ 'a is unused, but for back-compat we allow it +/// // ^ 'a is unused, but for back-compat we allow it /// /// impl<'a> Trait for Bar { type X = &'a i32; } -/// ^ 'a is unused and appears in assoc type, error +/// // ^ 'a is unused and appears in assoc type, error /// ``` pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, From 14768f9b636ef345320ded41da5e9f3da7af3a81 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 19:24:57 +0200 Subject: [PATCH 16/20] create a nostd crate the goal is to build, in a single Cargo invocation, several no-std crates that we want to put in the rust-std component of no-std targets. The nostd crate builds these crates: - core - compiler-builtin (with the "c" and "mem" features enabled) - alloc - std_unicode --- src/Cargo.lock | 10 ++++++++++ src/Cargo.toml | 1 + src/bootstrap/compile.rs | 8 ++++---- src/libnostd/Cargo.toml | 17 +++++++++++++++++ src/libnostd/lib.rs | 3 +++ 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/libnostd/Cargo.toml create mode 100644 src/libnostd/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 1f7cf84cedbda..42ac9b3c49dee 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1081,6 +1081,16 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nostd" +version = "0.0.0" +dependencies = [ + "alloc 0.0.0", + "compiler_builtins 0.0.0", + "core 0.0.0", + "std_unicode 0.0.0", +] + [[package]] name = "num" version = "0.1.42" diff --git a/src/Cargo.toml b/src/Cargo.toml index 814c054c51e41..babf35d570b51 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,6 +2,7 @@ members = [ "bootstrap", "rustc", + "libnostd", "libstd", "libtest", "librustc_trans", diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index eaf4ab272c68e..a93b26ac2bae0 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,10 +145,10 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we only compile core and compiler-builtins - cargo.arg("--features").arg("c mem") - .arg("--manifest-path") - .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); + // for no-std targets we compile a minimal nostd crate that only depends on crates that work + // without an OS + cargo.arg("--manifest-path") + .arg(build.src.join("src/libnostd/Cargo.toml")); } else { let mut features = build.std_features(); diff --git a/src/libnostd/Cargo.toml b/src/libnostd/Cargo.toml new file mode 100644 index 0000000000000..6919390d3e2a7 --- /dev/null +++ b/src/libnostd/Cargo.toml @@ -0,0 +1,17 @@ +[package] +authors = ["The Rust Project Developers"] +name = "nostd" +version = "0.0.0" +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-lang/rust.git" +description = "(not) The Rust Standard Library" + +[lib] +name = "nostd" +path = "lib.rs" + +[dependencies] +alloc = { path = "../liballoc" } +compiler_builtins = { path = "../rustc/compiler_builtins_shim", features = ["c", "mem"] } +core = { path = "../libcore" } +std_unicode = { path = "../libstd_unicode" } \ No newline at end of file diff --git a/src/libnostd/lib.rs b/src/libnostd/lib.rs new file mode 100644 index 0000000000000..d28afe2838e28 --- /dev/null +++ b/src/libnostd/lib.rs @@ -0,0 +1,3 @@ +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "nostd", issue = "0")] From bca569f57c53e219270be72ed5976b8167fcd246 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 22:23:33 +0200 Subject: [PATCH 17/20] Revert "create a nostd crate" This reverts commit 14768f9b636ef345320ded41da5e9f3da7af3a81. --- src/Cargo.lock | 10 ---------- src/Cargo.toml | 1 - src/bootstrap/compile.rs | 8 ++++---- src/libnostd/Cargo.toml | 17 ----------------- src/libnostd/lib.rs | 3 --- 5 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 src/libnostd/Cargo.toml delete mode 100644 src/libnostd/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 42ac9b3c49dee..1f7cf84cedbda 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1081,16 +1081,6 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "nostd" -version = "0.0.0" -dependencies = [ - "alloc 0.0.0", - "compiler_builtins 0.0.0", - "core 0.0.0", - "std_unicode 0.0.0", -] - [[package]] name = "num" version = "0.1.42" diff --git a/src/Cargo.toml b/src/Cargo.toml index babf35d570b51..814c054c51e41 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,7 +2,6 @@ members = [ "bootstrap", "rustc", - "libnostd", "libstd", "libtest", "librustc_trans", diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index a93b26ac2bae0..eaf4ab272c68e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,10 +145,10 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we compile a minimal nostd crate that only depends on crates that work - // without an OS - cargo.arg("--manifest-path") - .arg(build.src.join("src/libnostd/Cargo.toml")); + // for no-std targets we only compile core and compiler-builtins + cargo.arg("--features").arg("c mem") + .arg("--manifest-path") + .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); } else { let mut features = build.std_features(); diff --git a/src/libnostd/Cargo.toml b/src/libnostd/Cargo.toml deleted file mode 100644 index 6919390d3e2a7..0000000000000 --- a/src/libnostd/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "nostd" -version = "0.0.0" -license = "MIT/Apache-2.0" -repository = "https://github.com/rust-lang/rust.git" -description = "(not) The Rust Standard Library" - -[lib] -name = "nostd" -path = "lib.rs" - -[dependencies] -alloc = { path = "../liballoc" } -compiler_builtins = { path = "../rustc/compiler_builtins_shim", features = ["c", "mem"] } -core = { path = "../libcore" } -std_unicode = { path = "../libstd_unicode" } \ No newline at end of file diff --git a/src/libnostd/lib.rs b/src/libnostd/lib.rs deleted file mode 100644 index d28afe2838e28..0000000000000 --- a/src/libnostd/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![feature(staged_api)] -#![no_std] -#![unstable(feature = "nostd", issue = "0")] From b1015f5c5a4dcd6118b86ef5361371f04a7bce8b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 22:42:56 +0200 Subject: [PATCH 18/20] compile other no-std crates --- src/bootstrap/compile.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index eaf4ab272c68e..51e7a78831585 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,8 +145,11 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we only compile core and compiler-builtins + // for no-std targets we only compile a few no_std crates cargo.arg("--features").arg("c mem") + .args(&["-p", "alloc"]) + .args(&["-p", "compiler_builtins"]) + .args(&["-p", "std_unicode"]) .arg("--manifest-path") .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); } else { From 323795534f27e08b7adc9342d7ba66cd21e044a9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 4 Apr 2018 13:58:38 -0700 Subject: [PATCH 19/20] Add more features to rust_2018_preview --- src/libsyntax/feature_gate.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e734a4e373534..1f4ad2dc86391 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -193,7 +193,7 @@ declare_features! ( (active, rustc_attrs, "1.0.0", Some(29642), None), // Allows the use of non lexical lifetimes; RFC 2094 - (active, nll, "1.0.0", Some(43234), None), + (active, nll, "1.0.0", Some(43234), Some(Edition::Edition2018)), // Allows the use of #[allow_internal_unstable]. This is an // attribute on macro_rules! and can't use the attribute handling @@ -391,7 +391,7 @@ declare_features! ( (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), // `crate` as visibility modifier, synonymous to `pub(crate)` - (active, crate_visibility_modifier, "1.23.0", Some(45388), None), + (active, crate_visibility_modifier, "1.23.0", Some(45388), Some(Edition::Edition2018)), // extern types (active, extern_types, "1.23.0", Some(43467), None), @@ -400,10 +400,10 @@ declare_features! ( (active, arbitrary_self_types, "1.23.0", Some(44874), None), // `crate` in paths - (active, crate_in_paths, "1.23.0", Some(45477), None), + (active, crate_in_paths, "1.23.0", Some(45477), Some(Edition::Edition2018)), // In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`) - (active, in_band_lifetimes, "1.23.0", Some(44524), None), + (active, in_band_lifetimes, "1.23.0", Some(44524), Some(Edition::Edition2018)), // generic associated types (RFC 1598) (active, generic_associated_types, "1.23.0", Some(44265), None), @@ -412,10 +412,10 @@ declare_features! ( (active, extern_absolute_paths, "1.24.0", Some(44660), None), // `foo.rs` as an alternative to `foo/mod.rs` - (active, non_modrs_mods, "1.24.0", Some(44660), None), + (active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)), // Termination trait in tests (RFC 1937) - (active, termination_trait_test, "1.24.0", Some(48854), None), + (active, termination_trait_test, "1.24.0", Some(48854), Some(Edition::Edition2018)), // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), From 621ccf8917b25d66aff3beb45c540afbda29e980 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 4 Apr 2018 17:35:42 -0700 Subject: [PATCH 20/20] ci: Remove x86_64-gnu-incremental builder This builder is starting to time out frequently causing PRs to bounce and otherwise doesn't seem to be catching too many bugs, so this commit removes it entirely. We've had a number of timeouts in the last few weeks related to this builder: * https://travis-ci.org/rust-lang/rust/jobs/360947582 * https://travis-ci.org/rust-lang/rust/jobs/360464190 * https://travis-ci.org/rust-lang/rust/jobs/359946975 * https://travis-ci.org/rust-lang/rust/jobs/361213241 * https://travis-ci.org/rust-lang/rust/jobs/362346279 * https://travis-ci.org/rust-lang/rust/jobs/362072331 On a good run this builder takes about 2h15m, which is already too long for Travis and the variable build times end up pushing it beyond the 3h limit occasionally. The timeouts here are somewhat expected in that an incrementally compiled rustc compiler isn't optimized like a normal rustc, disallowing inlining between codegen units and losing lots of optimization opportunities. --- .travis.yml | 2 -- .../docker/x86_64-gnu-incremental/Dockerfile | 22 ------------------- 2 files changed, 24 deletions(-) delete mode 100644 src/ci/docker/x86_64-gnu-incremental/Dockerfile diff --git a/.travis.yml b/.travis.yml index f465ba4228174..36329ab91143c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -171,8 +171,6 @@ matrix: if: branch = auto - env: IMAGE=x86_64-gnu-distcheck if: branch = auto - - env: IMAGE=x86_64-gnu-incremental - if: branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/ci/docker/x86_64-gnu-incremental/Dockerfile b/src/ci/docker/x86_64-gnu-incremental/Dockerfile deleted file mode 100644 index 7304ed6015cc9..0000000000000 --- a/src/ci/docker/x86_64-gnu-incremental/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM ubuntu:16.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ - ca-certificates \ - python2.7 \ - git \ - cmake \ - sudo \ - gdb \ - xz-utils - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu -ENV RUSTFLAGS -Zincremental=/tmp/rust-incr-cache -ENV RUST_CHECK_TARGET check -ENV CARGO_INCREMENTAL 0