]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #49856 - varkor:no_mangle-statics-unlinted, r=michaelwoerister
authorkennytm <kennytm@gmail.com>
Wed, 11 Apr 2018 11:56:53 +0000 (19:56 +0800)
committerkennytm <kennytm@gmail.com>
Wed, 11 Apr 2018 19:23:19 +0000 (03:23 +0800)
Do not uppercase-lint #[no_mangle] statics

The reasoning being that `#[no_mangle]` expresses enough intention that there's likely a good reason for the name.

Fixes #36258.

130 files changed:
config.toml.example
src/bootstrap/bin/rustc.rs
src/bootstrap/builder.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/flags.rs
src/build_helper/lib.rs
src/liballoc/benches/lib.rs
src/liballoc/lib.rs
src/liballoc/slice.rs
src/liballoc/tests/lib.rs
src/liballoc_jemalloc/lib.rs
src/liballoc_system/lib.rs
src/libarena/lib.rs
src/libcore/benches/lib.rs
src/libcore/lib.rs
src/libcore/option.rs
src/libcore/tests/atomic.rs
src/libcore/tests/lib.rs
src/libfmt_macros/lib.rs
src/libgraphviz/lib.rs
src/libpanic_abort/lib.rs
src/libpanic_unwind/lib.rs
src/libproc_macro/lib.rs
src/librustc/benches/lib.rs
src/librustc/hir/map/mod.rs
src/librustc/infer/type_variable.rs
src/librustc/lib.rs
src/librustc/lint/mod.rs
src/librustc/middle/cstore.rs
src/librustc/mir/cache.rs
src/librustc/mir/mod.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/ty/context.rs
src/librustc/ty/layout.rs
src/librustc/ty/maps/plumbing.rs
src/librustc/ty/mod.rs
src/librustc/ty/steal.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc_allocator/lib.rs
src/librustc_apfloat/lib.rs
src/librustc_back/lib.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/lib.rs
src/librustc_const_math/lib.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/sync.rs
src/librustc_driver/lib.rs
src/librustc_driver/test.rs
src/librustc_errors/lib.rs
src/librustc_incremental/lib.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/lib.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/lib.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/util/borrowck_errors.rs
src/librustc_mir/util/collect_writes.rs [new file with mode: 0644]
src/librustc_mir/util/mod.rs
src/librustc_passes/lib.rs
src/librustc_platform_intrinsics/lib.rs
src/librustc_plugin/lib.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
src/librustc_save_analysis/lib.rs
src/librustc_traits/lib.rs
src/librustc_traits/lowering.rs
src/librustc_trans/back/write.rs
src/librustc_trans/base.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/lib.rs
src/librustc_trans_utils/lib.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/librustdoc/html/static/themes/dark.css
src/librustdoc/html/static/themes/light.css
src/librustdoc/lib.rs
src/libserialize/lib.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd_unicode/lib.rs
src/libsyntax/ext/base.rs
src/libsyntax/lib.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax_ext/lib.rs
src/libsyntax_pos/lib.rs
src/libterm/lib.rs
src/libtest/lib.rs
src/libunwind/lib.rs
src/rustc/rustc.rs
src/test/codegen/link_section.rs
src/test/compile-fail/borrowck/borrowck-issue-14498.rs
src/test/run-pass/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs [new file with mode: 0644]
src/test/run-pass/type-sizes.rs
src/test/rustdoc/all.rs [new file with mode: 0644]
src/test/ui/asm-out-assign-imm.rs
src/test/ui/asm-out-assign-imm.stderr
src/test/ui/chalkify/lower_trait.rs
src/test/ui/chalkify/lower_trait.stderr
src/test/ui/chalkify/lower_trait_higher_rank.rs [new file with mode: 0644]
src/test/ui/chalkify/lower_trait_higher_rank.stderr [new file with mode: 0644]
src/test/ui/chalkify/lower_trait_where_clause.rs [new file with mode: 0644]
src/test/ui/chalkify/lower_trait_where_clause.stderr [new file with mode: 0644]
src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs [new file with mode: 0644]
src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr [new file with mode: 0644]
src/test/ui/nll/issue-16223.rs [new file with mode: 0644]
src/test/ui/nll/issue-47388.rs [new file with mode: 0644]
src/test/ui/nll/issue-47388.stderr [new file with mode: 0644]
src/test/ui/target-feature-wrong.rs
src/test/ui/target-feature-wrong.stderr
src/tools/rustdoc/main.rs
src/tools/tidy/src/lib.rs

index 9dd3002506e41cbe333d4cc8051dcf9d62071eb7..68bc7dfe720fe11f20313c299b4dc4bc44318b5d 100644 (file)
 # rustc to execute.
 #lld = false
 
+# Whether to deny warnings in crates
+#deny-warnings = true
+
 # =============================================================================
 # Options for specific targets
 #
index 6701f58ba8e92593589679caf6772aeb6c1d9395..3dd9b6840591bf8d189b92a5bc37aba94d4b9acd 100644 (file)
@@ -279,6 +279,10 @@ fn main() {
         cmd.arg("--color=always");
     }
 
+    if env::var_os("RUSTC_DENY_WARNINGS").is_some() {
+        cmd.arg("-Dwarnings");
+    }
+
     if verbose > 1 {
         eprintln!("rustc command: {:?}", cmd);
         eprintln!("sysroot: {:?}", sysroot);
index 3f5ec4933d02b23d31469b3ea022b46fb1f0b323..7ff64af919671f977497bff7abf05dfac28e694c 100644 (file)
@@ -698,6 +698,11 @@ pub fn cargo(&self,
 
         cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
 
+        // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
+        if self.config.deny_warnings && !(mode == Mode::Libstd && stage == 0) {
+            cargo.env("RUSTC_DENY_WARNINGS", "1");
+        }
+
         // Throughout the build Cargo can execute a number of build scripts
         // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
         // obtained previously to those build scripts.
index 9cc18464fea094668f1c716c74cffe340e233827..b411b19bd53d21047bd4f93956195070b1e9779c 100644 (file)
@@ -1167,7 +1167,9 @@ pub fn stream_cargo(
     cargo.arg("--message-format").arg("json")
          .stdout(Stdio::piped());
 
-    if stderr_isatty() && build.ci_env == CiEnv::None {
+    if stderr_isatty() && build.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.
index 95baf4f8cca45d61e0c9db8b28f73acfd4867d47..239316d45c49c4067cd3ab74074452e296644f7b 100644 (file)
@@ -71,6 +71,8 @@ pub struct Config {
     pub incremental: bool,
     pub dry_run: bool,
 
+    pub deny_warnings: bool,
+
     // llvm codegen options
     pub llvm_enabled: bool,
     pub llvm_assertions: bool,
@@ -301,6 +303,7 @@ struct Rust {
     codegen_backends_dir: Option<String>,
     wasm_syscall: Option<bool>,
     lld: Option<bool>,
+    deny_warnings: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -340,6 +343,7 @@ pub fn default_opts() -> Config {
         config.test_miri = false;
         config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
         config.rust_codegen_backends_dir = "codegen-backends".to_owned();
+        config.deny_warnings = true;
 
         // set by bootstrap.py
         config.src = env::var_os("SRC").map(PathBuf::from).expect("'SRC' to be set");
@@ -366,6 +370,9 @@ pub fn parse(args: &[String]) -> Config {
         config.incremental = flags.incremental;
         config.dry_run = flags.dry_run;
         config.keep_stage = flags.keep_stage;
+        if let Some(value) = flags.warnings {
+            config.deny_warnings = value;
+        }
 
         if config.dry_run {
             let dir = config.out.join("tmp-dry-run");
@@ -511,6 +518,7 @@ pub fn parse(args: &[String]) -> Config {
             config.rustc_default_linker = rust.default_linker.clone();
             config.musl_root = rust.musl_root.clone().map(PathBuf::from);
             config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
+            set(&mut config.deny_warnings, rust.deny_warnings.or(flags.warnings));
 
             if let Some(ref backends) = rust.codegen_backends {
                 config.rust_codegen_backends = backends.iter()
index ef902c68d12d84f90a25dafb3672ba4a5501c658..3eb9dca2aa835807fc663e85e88f736e4515087d 100644 (file)
@@ -42,6 +42,9 @@ pub struct Flags {
     pub exclude: Vec<PathBuf>,
     pub rustc_error_format: Option<String>,
     pub dry_run: bool,
+
+    // true => deny
+    pub warnings: Option<bool>,
 }
 
 pub enum Subcommand {
@@ -118,6 +121,8 @@ pub fn parse(args: &[String]) -> Flags {
         opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
         opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
         opts.optflag("h", "help", "print this help message");
+        opts.optopt("", "warnings", "if value is deny, will deny warnings, otherwise use default",
+            "VALUE");
         opts.optopt("", "error-format", "rustc error format", "FORMAT");
 
         // fn usage()
@@ -374,6 +379,7 @@ pub fn parse(args: &[String]) -> Flags {
             incremental: matches.opt_present("incremental"),
             exclude: split(matches.opt_strs("exclude"))
                 .into_iter().map(|p| p.into()).collect::<Vec<_>>(),
+            warnings: matches.opt_str("warnings").map(|v| v == "deny"),
         }
     }
 }
index 5a12afd03e13b820c891aec362d9b6f3c5683f70..e5c85ddb3a9022ae1208a1112b8944a6d22d4084 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
 
 use std::fs::File;
 use std::path::{Path, PathBuf};
index 4d92fc67b2a503cee318477fdaa1503c5c5cb881..4f69aa6670b563fa9aced927148d88116446aa88 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(rand)]
 #![feature(repr_simd)]
 #![feature(slice_sort_by_cached_key)]
index da26e7c852c463caa5312f5d4b1946480f8a330f..b08bd66b47c5922533f00be05d62ac37e893527b 100644 (file)
@@ -72,7 +72,6 @@
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
 #![no_std]
 #![needs_allocator]
-#![deny(warnings)]
 #![deny(missing_debug_implementations)]
 
 #![cfg_attr(test, allow(deprecated))] // rand
index 68f2313843c313e0982ad607d9885d7b3cb4b0a5..56c53fca62cb1be2ffaf0da408e664ce1e27ab77 100644 (file)
@@ -1400,6 +1400,7 @@ macro_rules! sort_by_key {
         let sz_usize = mem::size_of::<(K, usize)>();
 
         let len = self.len();
+        if len < 2 { return }
         if sz_u8  < sz_u16   && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) }
         if sz_u16 < sz_u32   && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) }
         if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) }
index a173ef10a818ead9882a2285ad8cd9f93bd84ea1..17f1d0464a5c2d724b7a8a2c935a73622f233370 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(allocator_api)]
 #![feature(alloc_system)]
 #![feature(attr_literals)]
index 7a8d01e4ef8b88f7dddea1adc63f0e1b852baa73..df7e3f61f5f1dc3d7ae3db41839e0177ef8daaca 100644 (file)
@@ -14,7 +14,6 @@
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
             issue = "27783")]
-#![deny(warnings)]
 #![feature(alloc_system)]
 #![feature(libc)]
 #![feature(linkage)]
index d4404e564e0639960873fbacd4bf616130142a3e..cdcb732f635478bb4f105f7731694cf07b15f608 100644 (file)
@@ -10,7 +10,6 @@
 
 #![no_std]
 #![allow(unused_attributes)]
-#![deny(warnings)]
 #![unstable(feature = "alloc_system",
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
index 7eaf67e6ea66e30b991651b769f13f92d068f4a0..b319f333342c1cc11134d98d0881aca582eb7bf8 100644 (file)
@@ -22,7 +22,6 @@
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        test(no_crate_inject, attr(deny(warnings))))]
-#![deny(warnings)]
 
 #![feature(alloc)]
 #![feature(core_intrinsics)]
index c947b003ccbffaa697586bfb32b5bc528687c142..ced77d779182aaac437bb11645220e418a2741a7 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(flt2dec)]
 #![feature(test)]
 
index cf9abb26d3e1abe353a5eb9fe8b6359ab5001e03..e194b173aa718212c6e073faac006bc3dafa448e 100644 (file)
@@ -63,7 +63,6 @@
 #![no_core]
 #![deny(missing_docs)]
 #![deny(missing_debug_implementations)]
-#![deny(warnings)]
 
 #![feature(allow_internal_unstable)]
 #![feature(asm)]
index 61ef6798b2efb2062d5c874f531c86171a573c22..0dfdabee03182e18ab9553b0473a84eb27962f03 100644 (file)
@@ -628,8 +628,6 @@ pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
     /// # Examples
     ///
     /// ```rust
-    /// #![feature(option_filter)]
-    ///
     /// fn is_even(n: &i32) -> bool {
     ///     n % 2 == 0
     /// }
@@ -639,7 +637,7 @@ pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
     /// assert_eq!(Some(4).filter(is_even), Some(4));
     /// ```
     #[inline]
-    #[unstable(feature = "option_filter", issue = "45860")]
+    #[stable(feature = "option_filter", since = "1.27.0")]
     pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
         if let Some(x) = self {
             if predicate(&x) {
index f634fabe50399ebb595c00b29d57ec273f4cd6d8..a3667b3f3fee020f9ae973be79e542b1f47f584d 100644 (file)
@@ -104,8 +104,10 @@ fn int_xor() {
 
 #[test]
 fn static_init() {
-    assert!(!S_FALSE.load(SeqCst));
-    assert!(S_TRUE.load(SeqCst));
-    assert!(S_INT.load(SeqCst) == 0);
-    assert!(S_UINT.load(SeqCst) == 0);
+    // Note that we're not really testing the mutability here but it's important
+    // on Android at the moment (#49775)
+    assert!(!S_FALSE.swap(true, SeqCst));
+    assert!(S_TRUE.swap(false, SeqCst));
+    assert!(S_INT.fetch_add(1, SeqCst) == 0);
+    assert!(S_UINT.fetch_add(1, SeqCst) == 0);
 }
index 971759dcdd08dba1bcedbf12119e1ab2b3839ca5..c3162899bbd0184ffcb21391e105d9de868be915 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(ascii_ctype)]
 #![feature(box_syntax)]
 #![feature(core_float)]
index 0f45f965104cadff7b8cce5e168e73a0036cf36b..a551b1b770a68f1b7fa90cdfdf9f20812e6c86da 100644 (file)
@@ -19,7 +19,6 @@
        html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/",
        test(attr(deny(warnings))))]
-#![deny(warnings)]
 
 pub use self::Piece::*;
 pub use self::Position::*;
index d8c366d2413d9cf15975eb67bf64feb49b5de58f..158d0101515860af76c7562e987267a7818a2102 100644 (file)
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        test(attr(allow(unused_variables), deny(warnings))))]
-#![deny(warnings)]
 
 #![feature(str_escape)]
 
index 5f768ef4399e88fc12771aab5a6f892c263a66be..43c5bbbc618c2954edf7a2580102ad8932acc7ae 100644 (file)
@@ -19,7 +19,6 @@
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
-#![deny(warnings)]
 #![panic_runtime]
 #![allow(unused_features)]
 
index a5c227cb4015ca82b6e7abdebb31ac5d22031ab8..9321d6917d1566db3ef070a9c35066c0ef8b1007 100644 (file)
@@ -28,7 +28,6 @@
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
-#![deny(warnings)]
 
 #![feature(alloc)]
 #![feature(core_intrinsics)]
index 6aa5572721dbd329bd0e3c7b7d3043158a3ed507..dafdacfdd7247d02d19679d1dd99883fa5d99302 100644 (file)
@@ -24,7 +24,6 @@
 //! See [the book](../book/first-edition/procedural-macros.html) for more.
 
 #![stable(feature = "proc_macro_lib", since = "1.15.0")]
-#![deny(warnings)]
 #![deny(missing_docs)]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
index 278e0f9a26e433d032a5d2c3a4c0ee8142f3c4a9..5496df1342ff41b951b2f79b884b9bc32788de85 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(test)]
 
 extern crate test;
index e8bcbfbb77a1791cb03d6d65352566accc740c8a..1e348e3a31ce215225c4a269e5fa792e235b4439 100644 (file)
 use util::nodemap::{DefIdMap, FxHashMap};
 
 use arena::TypedArena;
-use std::cell::RefCell;
 use std::io;
 use ty::TyCtxt;
 
+use rustc_data_structures::sync::Lock;
+
 pub mod blocks;
 mod collector;
 mod def_collector;
@@ -264,7 +265,7 @@ pub struct Map<'hir> {
     definitions: &'hir Definitions,
 
     /// Bodies inlined from other crates are cached here.
-    inlined_bodies: RefCell<DefIdMap<&'hir Body>>,
+    inlined_bodies: Lock<DefIdMap<&'hir Body>>,
 
     /// The reverse mapping of `node_to_hir_id`.
     hir_to_node_id: FxHashMap<HirId, NodeId>,
@@ -927,8 +928,13 @@ pub fn get_inlined_body_untracked(&self, def_id: DefId) -> Option<&'hir Body> {
     }
 
     pub fn intern_inlined_body(&self, def_id: DefId, body: Body) -> &'hir Body {
+        let mut inlined_bodies = self.inlined_bodies.borrow_mut();
+        if let Some(&b) = inlined_bodies.get(&def_id) {
+            debug_assert_eq!(&body, b);
+            return b;
+        }
         let body = self.forest.inlined_bodies.alloc(body);
-        self.inlined_bodies.borrow_mut().insert(def_id, body);
+        inlined_bodies.insert(def_id, body);
         body
     }
 
@@ -1189,7 +1195,7 @@ pub fn map_crate<'hir>(sess: &::session::Session,
         map,
         hir_to_node_id,
         definitions,
-        inlined_bodies: RefCell::new(DefIdMap()),
+        inlined_bodies: Lock::new(DefIdMap()),
     };
 
     hir_id_validator::check_crate(&map);
index 91df6cabf3a8b88c4ae0e5a6a5b947a494638aa7..5e96f4eb576f523e5d20e79454de36ec4f1f95bd 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::ast;
+use syntax::symbol::InternedString;
 use syntax_pos::Span;
 use ty::{self, Ty};
 
@@ -53,7 +53,7 @@ pub enum TypeVariableOrigin {
     MiscVariable(Span),
     NormalizeProjectionType(Span),
     TypeInference(Span),
-    TypeParameterDefinition(Span, ast::Name),
+    TypeParameterDefinition(Span, InternedString),
 
     /// one of the upvars or closure kind parameters in a `ClosureSubsts`
     /// (before it has been determined)
index 7da664e6d0255ae825f67f23c3f53933ce2cb04c..a2cefe488c68ac53767b9ec0727a3750d1a10779 100644 (file)
@@ -39,7 +39,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
@@ -61,6 +60,7 @@
 #![feature(refcell_replace_swap)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(specialization)]
 #![feature(unboxed_closures)]
 #![feature(trace_macros)]
index 89a9f3034787b8ed61eeec8a11e54274b86cdc69..0d4fd99995f7ed2d57d4fefe61d16cb20ab4b28f 100644 (file)
@@ -31,7 +31,7 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{self, Lrc};
 
 use errors::{DiagnosticBuilder, DiagnosticId};
 use hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -287,8 +287,9 @@ fn exit_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
 }
 
 /// A lint pass boxed up as a trait object.
-pub type EarlyLintPassObject = Box<dyn EarlyLintPass + 'static>;
-pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + 'static>;
+pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>;
+pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
+                                                                           + sync::Sync + 'static>;
 
 /// Identifies a lint known to the compiler.
 #[derive(Clone, Copy, Debug)]
index add9b621596b63219db2d406dab8020c0a4bb13a..41334a37dbef65050cecff58c463f781c1f0db4e 100644 (file)
@@ -401,7 +401,7 @@ pub fn used_crates(tcx: TyCtxt, prefer: LinkagePreference)
         .collect::<Vec<_>>();
     let mut ordering = tcx.postorder_cnums(LOCAL_CRATE);
     Lrc::make_mut(&mut ordering).reverse();
-    libs.sort_by_key(|&(a, _)| {
+    libs.sort_by_cached_key(|&(a, _)| {
         ordering.iter().position(|x| *x == a)
     });
     libs
index 9b75c19a875ebc4ad83ac100ae5f1aa6a78afb92..1ed5a22257c537e53446b2013d1c2e842984c55c 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::cell::{Ref, RefCell};
 use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::sync::{RwLock, ReadGuard};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                            StableHasherResult};
 use ich::StableHashingContext;
@@ -19,7 +19,7 @@
 
 #[derive(Clone, Debug)]
 pub struct Cache {
-    predecessors: RefCell<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>>
+    predecessors: RwLock<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>>
 }
 
 
@@ -46,7 +46,7 @@ fn hash_stable<W: StableHasherResult>(&self,
 impl Cache {
     pub fn new() -> Self {
         Cache {
-            predecessors: RefCell::new(None)
+            predecessors: RwLock::new(None)
         }
     }
 
@@ -55,12 +55,12 @@ pub fn invalidate(&self) {
         *self.predecessors.borrow_mut() = None;
     }
 
-    pub fn predecessors(&self, mir: &Mir) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> {
+    pub fn predecessors(&self, mir: &Mir) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
         if self.predecessors.borrow().is_none() {
             *self.predecessors.borrow_mut() = Some(calculate_predecessors(mir));
         }
 
-        Ref::map(self.predecessors.borrow(), |p| p.as_ref().unwrap())
+        ReadGuard::map(self.predecessors.borrow(), |p| p.as_ref().unwrap())
     }
 }
 
index 9ed4e6a8e00ae5e3c7bc325362c6c9288fe1eedc..33f52ab09c85668b72c9d3a008345fe5394688e6 100644 (file)
@@ -34,7 +34,7 @@
 use std::slice;
 use hir::{self, InlineAsm};
 use std::borrow::{Cow};
-use std::cell::Ref;
+use rustc_data_structures::sync::ReadGuard;
 use std::fmt::{self, Debug, Formatter, Write};
 use std::{iter, mem, u32};
 use std::ops::{Index, IndexMut};
@@ -187,13 +187,13 @@ pub fn basic_blocks_and_local_decls_mut(&mut self) -> (
     }
 
     #[inline]
-    pub fn predecessors(&self) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> {
+    pub fn predecessors(&self) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
         self.cache.predecessors(self)
     }
 
     #[inline]
-    pub fn predecessors_for(&self, bb: BasicBlock) -> Ref<Vec<BasicBlock>> {
-        Ref::map(self.predecessors(), |p| &p[bb])
+    pub fn predecessors_for(&self, bb: BasicBlock) -> ReadGuard<Vec<BasicBlock>> {
+        ReadGuard::map(self.predecessors(), |p| &p[bb])
     }
 
     #[inline]
index d2bde14732bbcdab4eca9a21ea495311826b497d..2af4c3f9fd463ca7adfd651df4750763872a8961 100644 (file)
@@ -378,7 +378,7 @@ fn on_unimplemented_note(
         }
 
         for param in generics.types.iter() {
-            let name = param.name.as_str().to_string();
+            let name = param.name.to_string();
             let ty = trait_ref.substs.type_for_def(param);
             let ty_str = ty.to_string();
             flags.push((name.clone(),
index a1018cb946a018eb9bc9a0c41e8db854b46bd855..405dafdff2b3455a511ec6691b4e28eebf7ee728 100644 (file)
@@ -289,7 +289,7 @@ pub fn format(&self,
         let trait_str = tcx.item_path_str(trait_ref.def_id);
         let generics = tcx.generics_of(trait_ref.def_id);
         let generic_map = generics.types.iter().map(|param| {
-            (param.name.as_str().to_string(),
+            (param.name.to_string(),
              trait_ref.substs.type_for_def(param).to_string())
         }).collect::<FxHashMap<String, String>>();
 
index 69b33efdb3542c02bace3f32fb00ac3560ef3498..2713b2d11e0679e67ce3fd93cb8121862ddfe4b3 100644 (file)
@@ -58,7 +58,7 @@
                                            StableVec};
 use arena::{TypedArena, DroplessArena};
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, Lock};
 use std::any::Any;
 use std::borrow::Borrow;
 use std::cell::{Cell, RefCell};
 use std::sync::mpsc;
 use std::sync::Arc;
 use syntax::abi;
-use syntax::ast::{self, Name, NodeId};
+use syntax::ast::{self, NodeId};
 use syntax::attr;
 use syntax::codemap::MultiSpan;
 use syntax::feature_gate;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, InternedString};
 use syntax_pos::Span;
 
 use hir;
@@ -131,28 +131,28 @@ pub struct CtxtInterners<'tcx> {
 
     /// Specifically use a speedy hash algorithm for these hash sets,
     /// they're accessed quite often.
-    type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
-    type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
-    substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
-    canonical_var_infos: RefCell<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>,
-    region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>,
-    existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
-    predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
-    const_: RefCell<FxHashSet<Interned<'tcx, Const<'tcx>>>>,
+    type_: Lock<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
+    type_list: Lock<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
+    substs: Lock<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
+    canonical_var_infos: Lock<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>,
+    region: Lock<FxHashSet<Interned<'tcx, RegionKind>>>,
+    existential_predicates: Lock<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
+    predicates: Lock<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
+    const_: Lock<FxHashSet<Interned<'tcx, Const<'tcx>>>>,
 }
 
 impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
     fn new(arena: &'tcx DroplessArena) -> CtxtInterners<'tcx> {
         CtxtInterners {
-            arena,
-            type_: RefCell::new(FxHashSet()),
-            type_list: RefCell::new(FxHashSet()),
-            substs: RefCell::new(FxHashSet()),
-            region: RefCell::new(FxHashSet()),
-            existential_predicates: RefCell::new(FxHashSet()),
-            canonical_var_infos: RefCell::new(FxHashSet()),
-            predicates: RefCell::new(FxHashSet()),
-            const_: RefCell::new(FxHashSet()),
+            arena: arena,
+            type_: Lock::new(FxHashSet()),
+            type_list: Lock::new(FxHashSet()),
+            substs: Lock::new(FxHashSet()),
+            canonical_var_infos: Lock::new(FxHashSet()),
+            region: Lock::new(FxHashSet()),
+            existential_predicates: Lock::new(FxHashSet()),
+            predicates: Lock::new(FxHashSet()),
+            const_: Lock::new(FxHashSet()),
         }
     }
 
@@ -892,11 +892,11 @@ pub struct GlobalCtxt<'tcx> {
     /// by `proc-macro` crates.
     pub derive_macros: RefCell<NodeMap<Symbol>>,
 
-    stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>,
+    stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
 
     pub interpret_interner: InterpretInterner<'tcx>,
 
-    layout_interner: RefCell<FxHashSet<&'tcx LayoutDetails>>,
+    layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
 
     /// A vector of every trait accessible in the whole crate
     /// (i.e. including those from subcrates). This is used only for
@@ -910,7 +910,7 @@ pub struct GlobalCtxt<'tcx> {
     /// This is intended to only get used during the trans phase of the compiler
     /// when satisfying the query for a particular codegen unit. Internally in
     /// the query it'll send data along this channel to get processed later.
-    pub tx_to_llvm_workers: mpsc::Sender<Box<dyn Any + Send>>,
+    pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<dyn Any + Send>>>,
 
     output_filenames: Arc<OutputFilenames>,
 }
@@ -918,7 +918,7 @@ pub struct GlobalCtxt<'tcx> {
 /// Everything needed to efficiently work with interned allocations
 #[derive(Debug, Default)]
 pub struct InterpretInterner<'tcx> {
-    inner: RefCell<InterpretInternerInner<'tcx>>,
+    inner: Lock<InterpretInternerInner<'tcx>>,
 }
 
 #[derive(Debug, Default)]
@@ -1278,13 +1278,13 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
             evaluation_cache: traits::EvaluationCache::new(),
             crate_name: Symbol::intern(crate_name),
             data_layout,
-            layout_interner: RefCell::new(FxHashSet()),
+            layout_interner: Lock::new(FxHashSet()),
             layout_depth: Cell::new(0),
             derive_macros: RefCell::new(NodeMap()),
-            stability_interner: RefCell::new(FxHashSet()),
+            stability_interner: Lock::new(FxHashSet()),
             interpret_interner: Default::default(),
             all_traits: RefCell::new(None),
-            tx_to_llvm_workers: tx,
+            tx_to_llvm_workers: Lock::new(tx),
             output_filenames: Arc::new(output_filenames.clone()),
         };
 
@@ -2430,12 +2430,12 @@ pub fn mk_infer(self, it: InferTy) -> Ty<'tcx> {
 
     pub fn mk_param(self,
                     index: u32,
-                    name: Name) -> Ty<'tcx> {
+                    name: InternedString) -> Ty<'tcx> {
         self.mk_ty(TyParam(ParamTy { idx: index, name: name }))
     }
 
     pub fn mk_self_type(self) -> Ty<'tcx> {
-        self.mk_param(0, keywords::SelfType.name())
+        self.mk_param(0, keywords::SelfType.name().as_str())
     }
 
     pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
index 5f9c305d92f04ec32860e064606b3cb541e19f7d..16d28ff4266ffb391c4bfba4865ce6f3ea7a9f7f 100644 (file)
@@ -1471,10 +1471,10 @@ enum StructKind {
 
                     // Find one non-ZST variant.
                     'variants: for (v, fields) in variants.iter().enumerate() {
+                        if fields.iter().any(|f| f.abi == Abi::Uninhabited) {
+                            continue 'variants;
+                        }
                         for f in fields {
-                            if f.abi == Abi::Uninhabited {
-                                continue 'variants;
-                            }
                             if !f.is_zst() {
                                 if dataful_variant.is_none() {
                                     dataful_variant = Some(v);
index 232b300e7545d4697b24a043f5b96c4e379dc5e1..c04e580a33dedaa1c6f840b3c2cc5f33df9bfd7d 100644 (file)
@@ -671,7 +671,16 @@ fn force_with_lock(tcx: TyCtxt<'a, $tcx, 'lcx>,
                                map: LockGuard<'_, QueryMap<$tcx, Self>>,
                                dep_node: DepNode)
                                -> Result<($V, DepNodeIndex), CycleError<$tcx>> {
-                debug_assert!(!tcx.dep_graph.dep_node_exists(&dep_node));
+                // If the following assertion triggers, it can have two reasons:
+                // 1. Something is wrong with DepNode creation, either here or
+                //    in DepGraph::try_mark_green()
+                // 2. Two distinct query keys get mapped to the same DepNode
+                //    (see for example #48923)
+                assert!(!tcx.dep_graph.dep_node_exists(&dep_node),
+                        "Forcing query with already existing DepNode.\n\
+                          - query-key: {:?}\n\
+                          - dep-node: {:?}",
+                        key, dep_node);
 
                 profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
                 let res = Self::start_job(tcx,
index b920553ec369835e663256d96768b20af7446278..5b1160f142021a8ca455f860b4af7dd724e92219 100644 (file)
@@ -712,7 +712,7 @@ pub enum IntVarValue {
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct TypeParameterDef {
-    pub name: Name,
+    pub name: InternedString,
     pub def_id: DefId,
     pub index: u32,
     pub has_default: bool,
index 0b0818888812f1700db4c8d4caf8b115b1e1ba3d..842c0d6573432fb962057b3432bb4707f75f3048 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::cell::{Ref, RefCell};
+use rustc_data_structures::sync::{RwLock, ReadGuard};
 use std::mem;
 
 /// The `Steal` struct is intended to used as the value for a query.
 ///
 /// FIXME(#41710) -- what is the best way to model linear queries?
 pub struct Steal<T> {
-    value: RefCell<Option<T>>
+    value: RwLock<Option<T>>
 }
 
 impl<T> Steal<T> {
     pub fn new(value: T) -> Self {
         Steal {
-            value: RefCell::new(Some(value))
+            value: RwLock::new(Some(value))
         }
     }
 
-    pub fn borrow(&self) -> Ref<T> {
-        Ref::map(self.value.borrow(), |opt| match *opt {
+    pub fn borrow(&self) -> ReadGuard<T> {
+        ReadGuard::map(self.value.borrow(), |opt| match *opt {
             None => bug!("attempted to read from stolen value"),
             Some(ref v) => v
         })
     }
 
     pub fn steal(&self) -> T {
-        let value_ref = &mut *self.value.borrow_mut();
+        let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
         let value = mem::replace(value_ref, None);
         value.expect("attempt to read from stolen value")
     }
index ed04d41ba1457fbfddb518db98a4928884b7d4a9..7a9174cbfaf73206619e80f66ffed4ded7a94384 100644 (file)
@@ -24,7 +24,7 @@
 use std::cmp::Ordering;
 use syntax::abi;
 use syntax::ast::{self, Name};
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, InternedString};
 
 use serialize;
 
@@ -864,16 +864,16 @@ pub fn abi(&self) -> abi::Abi {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct ParamTy {
     pub idx: u32,
-    pub name: Name,
+    pub name: InternedString,
 }
 
 impl<'a, 'gcx, 'tcx> ParamTy {
-    pub fn new(index: u32, name: Name) -> ParamTy {
+    pub fn new(index: u32, name: InternedString) -> ParamTy {
         ParamTy { idx: index, name: name }
     }
 
     pub fn for_self() -> ParamTy {
-        ParamTy::new(0, keywords::SelfType.name())
+        ParamTy::new(0, keywords::SelfType.name().as_str())
     }
 
     pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy {
@@ -885,7 +885,7 @@ pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
     }
 
     pub fn is_self(&self) -> bool {
-        if self.name == keywords::SelfType.name() {
+        if self.name == keywords::SelfType.name().as_str() {
             assert_eq!(self.idx, 0);
             true
         } else {
index 22f851a908b252b5f2046949b4f4fdb74a812876..c170c2a63e82996b697b913e67141dea58fe22bd 100644 (file)
@@ -729,7 +729,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
             }
             TyParam(p) => {
                 self.hash(p.idx);
-                self.hash(p.name.as_str());
+                self.hash(p.name);
             }
             TyProjection(ref data) => {
                 self.def_id(data.item_def_id);
index e17fce5a2ec0a276d5409af7ecea393a3edd257b..0c7a9a91711b7aac81705e8d635bf6801a6638a4 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
-
 #![feature(rustc_private)]
 
 extern crate rustc;
index 276f6cd09bf7accfce96b3051206735f437e7ee6..0f051ea5981ca4eefe254c264a179b4343640ad0 100644 (file)
@@ -43,7 +43,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 #![forbid(unsafe_code)]
 
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
index 9baee26770998a4ffe92f3bb53ad7d4a303134d9..027a9c455553051b7944494b7d8bbeab2868c4f8 100644 (file)
@@ -24,7 +24,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_syntax)]
 #![feature(const_fn)]
index 93d6247eeae47733af3b4f8833bbb248ceda400c..2049a146a0f02c85bad4d846edeaf3d9e581abcc 100644 (file)
@@ -128,7 +128,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     // Note that `mir_validated` is a "stealable" result; the
     // thief, `optimized_mir()`, forces borrowck, so we know that
     // is not yet stolen.
-    tcx.mir_validated(owner_def_id).borrow();
+    ty::maps::queries::mir_validated::ensure(tcx, owner_def_id);
 
     // option dance because you can't capture an uninitialized variable
     // by mut-ref.
index 6fe2ac2b0ca25a6c90104419394101097d5b652b..52a357e1a1d3173c4d7a64327e3efd06af818eef 100644 (file)
@@ -11,7 +11,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![allow(non_camel_case_types)]
 
index c4c5886d465d8ad02f8beb1ff47240aa08d7d5a6..499c330be1da8aca6a0d32483d9d011c2a7bf559 100644 (file)
@@ -17,7 +17,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 extern crate rustc_apfloat;
 
index 1e1628936d5cac9b495b46ad730db41ff3da749a..ba1d73dc268dfa3515b12b93d0621e32910aa09a 100644 (file)
@@ -19,7 +19,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(collections_range)]
 #![feature(nonzero)]
index 184ef1369761cb181501960b2484197037a14d46..0f534f0adec4b919e3dcd5cfe5a533353a9c9462 100644 (file)
@@ -388,6 +388,18 @@ pub fn with_read_lock<F: FnOnce(&T) -> R, R>(&self, f: F) -> R {
         f(&*self.read())
     }
 
+    #[cfg(not(parallel_queries))]
+    #[inline(always)]
+    pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
+        self.0.try_borrow_mut().map_err(|_| ())
+    }
+
+    #[cfg(parallel_queries)]
+    #[inline(always)]
+    pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
+        self.0.try_write().ok_or(())
+    }
+
     #[cfg(not(parallel_queries))]
     #[inline(always)]
     pub fn write(&self) -> WriteGuard<T> {
index 6f88b0aecb6b674e935619c37aecb9b6be3ae9b5..3dec84d174dd8d922badd5cd17625b8a14987639 100644 (file)
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_syntax)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(set_stdio)]
 #![feature(rustc_stack_internals)]
 
@@ -83,7 +83,6 @@
 use serialize::json::ToJson;
 
 use std::any::Any;
-use std::cmp::Ordering::Equal;
 use std::cmp::max;
 use std::default::Default;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
@@ -1177,13 +1176,8 @@ fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins:
 
     fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
         let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
-        lints.sort_by(|x: &&Lint, y: &&Lint| {
-            match x.default_level(sess).cmp(&y.default_level(sess)) {
-                // The sort doesn't case-fold but it's doubtful we care.
-                Equal => x.name.cmp(y.name),
-                r => r,
-            }
-        });
+        // The sort doesn't case-fold but it's doubtful we care.
+        lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name));
         lints
     }
 
index 9efd8844977f905e7bf41fa15a25dee7e19b367a..971855ee2d007256b58be8846212e5ca1fd1e461 100644 (file)
@@ -303,7 +303,7 @@ pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
 
     pub fn t_param(&self, index: u32) -> Ty<'tcx> {
         let name = format!("T{}", index);
-        self.infcx.tcx.mk_param(index, Symbol::intern(&name))
+        self.infcx.tcx.mk_param(index, Symbol::intern(&name).as_str())
     }
 
     pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> {
index a723e455222047a534794da1cf9d4498a17b3244..8d5f9ac93f0b48e3d5b92f7233715e3f2c1cf7e9 100644 (file)
@@ -11,7 +11,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
index 9e72ede309d44cf9d1846ae815c799ed19119580..a5e07bcec24bb65c242de5765c68c6ad9c3792a9 100644 (file)
@@ -13,7 +13,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(fs_read_write)]
 #![feature(specialization)]
index 2cc6708bc034e1dafe570fe975f57f8aee6bac02..48e9cc498dceb8b44ceba28e9abaf0202e8b3bd8 100644 (file)
@@ -173,6 +173,12 @@ fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
                 }
                 if let PatKind::Binding(_, _, name, None) = fieldpat.node.pat.node {
                     if name.node == fieldpat.node.name {
+                        if let Some(_) = fieldpat.span.ctxt().outer().expn_info() {
+                            // Don't lint if this is a macro expansion: macro authors
+                            // shouldn't have to worry about this kind of style issue
+                            // (Issue #49588)
+                            return;
+                        }
                         let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS,
                                      fieldpat.span,
                                      &format!("the `{}:` in this pattern is redundant",
index c915181213d3859d9480495efa97072f58983954..16e8600f2d89bfec62c9bb5eeccdcec779c850fb 100644 (file)
@@ -22,7 +22,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![cfg_attr(test, feature(test))]
 #![feature(box_patterns)]
index 16bee5b987e2d0a6b333745e0289f20597cf9685..bf8a087ab556bd3e4e264dbb208609c64086cf7f 100644 (file)
@@ -16,7 +16,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_syntax)]
 #![feature(concat_idents)]
index 51088563c7b9c0d0951ef8260577f0ece00a84c9..2c995d2f5cde637be697c85cc20935ab6fb3eb47 100644 (file)
@@ -163,7 +163,7 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
     fn_arg_names => { cdata.get_fn_arg_names(def_id.index) }
     impl_parent => { cdata.get_parent_impl(def_id.index) }
     trait_of_item => { cdata.get_trait_of_item(def_id.index) }
-    item_body_nested_bodies => { cdata.item_body_nested_bodies(def_id.index) }
+    item_body_nested_bodies => { cdata.item_body_nested_bodies(tcx, def_id.index) }
     const_is_rvalue_promotable_to_static => {
         cdata.const_is_rvalue_promotable_to_static(def_id.index)
     }
index 42e208ded49fd0f1f0782836dc3d219a8e5d700c..3ea4ddc25226fffe80d39cbeba80b474ea18e2cd 100644 (file)
@@ -818,11 +818,14 @@ pub fn item_body_tables(&self,
         tcx.alloc_tables(ast.tables.decode((self, tcx)))
     }
 
-    pub fn item_body_nested_bodies(&self, id: DefIndex) -> ExternBodyNestedBodies {
+    pub fn item_body_nested_bodies(&self,
+                                   tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   id: DefIndex)
+                                   -> ExternBodyNestedBodies {
         if let Some(ref ast) = self.entry(id).ast {
-            let ast = ast.decode(self);
+            let mut ast = ast.decode(self);
             let nested_bodies: BTreeMap<_, _> = ast.nested_bodies
-                                                   .decode(self)
+                                                   .decode((self, tcx.sess))
                                                    .map(|body| (body.id(), body))
                                                    .collect();
             ExternBodyNestedBodies {
index 1b208a512e2a46c6a977b5c272aef67f8a7e95a7..e40a3057a95cf903d218b941a3edbd2a0d50d5a7 100644 (file)
@@ -1414,7 +1414,7 @@ fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
         let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
 
         // Bring everything into deterministic order for hashing
-        all_impls.sort_unstable_by_key(|&(trait_def_id, _)| {
+        all_impls.sort_by_cached_key(|&(trait_def_id, _)| {
             tcx.def_path_hash(trait_def_id)
         });
 
@@ -1422,7 +1422,7 @@ fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
             .into_iter()
             .map(|(trait_def_id, mut impls)| {
                 // Bring everything into deterministic order for hashing
-                impls.sort_unstable_by_key(|&def_index| {
+                impls.sort_by_cached_key(|&def_index| {
                     tcx.hir.definitions().def_path_hash(def_index)
                 });
 
index e89b5a7fc1b4e1dcedf550da7ad719d5d34c13be..cbbc9d74228de9e8bf9de8c7d262cec33aefd7ed 100644 (file)
@@ -11,7 +11,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_patterns)]
 #![feature(fs_read_write)]
@@ -21,6 +20,7 @@
 #![feature(macro_lifetime_matcher)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(specialization)]
 #![feature(rustc_private)]
 
index fe7aedb4127f9121a4f32e1e1af5ddf71b1f9d9c..62acdf76546248cae0733df9959bd93dfc1bd4c3 100644 (file)
@@ -42,6 +42,7 @@
 use dataflow::move_paths::{IllegalMoveOriginKind, MoveError};
 use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
 use util::borrowck_errors::{BorrowckErrors, Origin};
+use util::collect_writes::FindAssignments;
 
 use std::iter;
 
@@ -1550,6 +1551,36 @@ fn check_if_assigned_path_is_moved(
         }
     }
 
+    fn specialized_description(&self, place:&Place<'tcx>) -> Option<String>{
+        if let Some(_name) = self.describe_place(place) {
+            Some(format!("data in a `&` reference"))
+        } else {
+            None
+        }
+    }
+
+    fn get_default_err_msg(&self, place:&Place<'tcx>) -> String{
+        match self.describe_place(place) {
+            Some(name) => format!("immutable item `{}`", name),
+            None => "immutable item".to_owned(),
+        }
+    }
+
+    fn get_secondary_err_msg(&self, place:&Place<'tcx>) -> String{
+        match self.specialized_description(place) {
+            Some(_) => format!("data in a `&` reference"),
+            None => self.get_default_err_msg(place)
+        }
+    }
+
+    fn get_primary_err_msg(&self, place:&Place<'tcx>) -> String{
+        if let Some(name) = self.describe_place(place) {
+            format!("`{}` is a `&` reference, so the data it refers to cannot be written", name)
+        } else {
+            format!("cannot assign through `&`-reference")
+        }
+    }
+
     /// Check the permissions for the given place and read or write kind
     ///
     /// Returns true if an error is reported, false otherwise.
@@ -1576,43 +1607,70 @@ fn check_access_permissions(
                 self.is_mutable(place, is_local_mutation_allowed)
             {
                 error_reported = true;
-
-                let item_msg = match self.describe_place(place) {
-                    Some(name) => format!("immutable item `{}`", name),
-                    None => "immutable item".to_owned(),
-                };
-
+                let item_msg = self.get_default_err_msg(place);
                 let mut err = self.tcx
                     .cannot_borrow_path_as_mutable(span, &item_msg, Origin::Mir);
                 err.span_label(span, "cannot borrow as mutable");
 
                 if place != place_err {
                     if let Some(name) = self.describe_place(place_err) {
-                        err.note(&format!("Value not mutable causing this error: `{}`", name));
+                        err.note(&format!("the value which is causing this path not to be mutable \
+                                           is...: `{}`", name));
                     }
                 }
 
                 err.emit();
             },
             Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
+
                 if let Err(place_err) = self.is_mutable(place, is_local_mutation_allowed) {
                     error_reported = true;
+                    let mut err_info = None;
+                    match *place_err {
+
+                        Place::Projection(box Projection {
+                        ref base, elem:ProjectionElem::Deref}) => {
+                            match *base {
+                                Place::Local(local) => {
+                                    let locations = self.mir.find_assignments(local);
+                                        if locations.len() > 0 {
+                                            let item_msg = if error_reported {
+                                                self.get_secondary_err_msg(base)
+                                            } else {
+                                                self.get_default_err_msg(place)
+                                            };
+                                            err_info = Some((
+                                                self.mir.source_info(locations[0]).span,
+                                                    "consider changing this to be a \
+                                                    mutable reference: `&mut`", item_msg,
+                                                    self.get_primary_err_msg(base)));
+                                        }
+                                },
+                            _ => {},
+                            }
+                        },
+                        _ => {},
+                    }
 
-                    let item_msg = match self.describe_place(place) {
-                        Some(name) => format!("immutable item `{}`", name),
-                        None => "immutable item".to_owned(),
-                    };
-
-                    let mut err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir);
-                    err.span_label(span, "cannot mutate");
-
-                    if place != place_err {
-                        if let Some(name) = self.describe_place(place_err) {
-                            err.note(&format!("Value not mutable causing this error: `{}`", name));
+                    if let Some((err_help_span, err_help_stmt, item_msg, sec_span)) = err_info {
+                        let mut err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir);
+                        err.span_suggestion(err_help_span, err_help_stmt, format!(""));
+                        if place != place_err {
+                            err.span_label(span, sec_span);
                         }
+                        err.emit()
+                    } else {
+                        let item_msg_ = self.get_default_err_msg(place);
+                        let mut err = self.tcx.cannot_assign(span, &item_msg_, Origin::Mir);
+                        err.span_label(span, "cannot mutate");
+                        if place != place_err {
+                            if let Some(name) = self.describe_place(place_err) {
+                                err.note(&format!("the value which is causing this path not to be \
+                                                   mutable is...: `{}`", name));
+                            }
+                        }
+                        err.emit();
                     }
-
-                    err.emit();
                 }
             }
             Reservation(WriteKind::Move)
@@ -1631,9 +1689,7 @@ fn check_access_permissions(
                     );
                 }
             }
-
             Activation(..) => {} // permission checks are done at Reservation point.
-
             Read(ReadKind::Borrow(BorrowKind::Unique))
             | Read(ReadKind::Borrow(BorrowKind::Mut { .. }))
             | Read(ReadKind::Borrow(BorrowKind::Shared))
@@ -2255,3 +2311,4 @@ fn new(self, loc: Location) -> Context {
         }
     }
 }
+
index 8762e7550cdedffb11c6af54187e2c4a68ef6e48..fe440a56ea060c4a228e8d43dc9d74dd53ecaa15 100644 (file)
@@ -14,9 +14,8 @@
 
 */
 
-#![deny(warnings)]
-
 #![feature(slice_patterns)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(from_ref)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
@@ -32,6 +31,7 @@
 #![feature(rustc_diagnostic_macros)]
 #![feature(nonzero)]
 #![feature(inclusive_range_fields)]
+#![feature(crate_visibility_modifier)]
 
 extern crate arena;
 #[macro_use]
index da4cb4ec789041d219ce33d3c0084cba30b0a5b0..f29f86af4aba73e6fb31b5d13f3636a3a622f14e 100644 (file)
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use std::collections::hash_map::Entry;
+use std::cmp;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
 use rustc::mir::mono::MonoItem;
 use monomorphize::item::{MonoItemExt, InstantiationMode};
-use core::usize;
 
 pub use rustc::mir::mono::CodegenUnit;
 
@@ -189,11 +189,9 @@ fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }, item.symbol_name(tcx))
         }
 
-        let items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
-        let mut items : Vec<_> = items.iter()
-            .map(|il| (il, item_sort_key(tcx, il.0))).collect();
-        items.sort_by(|&(_, ref key1), &(_, ref key2)| key1.cmp(key2));
-        items.into_iter().map(|(&item_linkage, _)| item_linkage).collect()
+        let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
+        items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
+        items
     }
 }
 
@@ -509,7 +507,7 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
     // Merge the two smallest codegen units until the target size is reached.
     while codegen_units.len() > target_cgu_count {
         // Sort small cgus to the back
-        codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate());
+        codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
         let mut smallest = codegen_units.pop().unwrap();
         let second_smallest = codegen_units.last_mut().unwrap();
 
index 5e15348de5e718a76632bf2e11c1daeceb341e4b..d6b3e674f8f804878c727db063d25736b3f47ae2 100644 (file)
@@ -284,7 +284,8 @@ fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Orig
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx>
+    fn cannot_assign(self, span: Span, desc: &str, o: Origin)
+                     -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0594,
                                   "cannot assign to {}{OGN}",
diff --git a/src/librustc_mir/util/collect_writes.rs b/src/librustc_mir/util/collect_writes.rs
new file mode 100644 (file)
index 0000000..f04f923
--- /dev/null
@@ -0,0 +1,67 @@
+// 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.
+
+use rustc::mir::{Local, Location};
+use rustc::mir::Mir;
+use rustc::mir::visit::PlaceContext;
+use rustc::mir::visit::Visitor;
+
+crate trait FindAssignments {
+    // Finds all statements that assign directly to local (i.e., X = ...)
+    // and returns their locations.
+    fn find_assignments(&self, local: Local) -> Vec<Location>;
+}
+
+impl<'tcx> FindAssignments for Mir<'tcx>{
+    fn find_assignments(&self, local: Local) -> Vec<Location>{
+            let mut visitor = FindLocalAssignmentVisitor{ needle: local, locations: vec![]};
+            visitor.visit_mir(self);
+            visitor.locations
+    }
+}
+
+// The Visitor walks the MIR to return the assignment statements corresponding
+// to a Local.
+struct FindLocalAssignmentVisitor {
+    needle: Local,
+    locations: Vec<Location>,
+}
+
+impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
+    fn visit_local(&mut self,
+                   local: &Local,
+                   place_context: PlaceContext<'tcx>,
+                   location: Location) {
+        if self.needle != *local {
+            return;
+        }
+
+        match place_context {
+            PlaceContext::Store | PlaceContext::Call => {
+                self.locations.push(location);
+            }
+            PlaceContext::AsmOutput |
+            PlaceContext::Drop |
+            PlaceContext::Inspect |
+            PlaceContext::Borrow { .. } |
+            PlaceContext::Projection(..) |
+            PlaceContext::Copy |
+            PlaceContext::Move |
+            PlaceContext::StorageLive |
+            PlaceContext::StorageDead |
+            PlaceContext::Validate => {
+                // TO-DO
+                // self.super_local(local)
+            }
+        }
+    }
+    // TO-DO
+    // fn super_local()
+}
index eebe5a86018ea6ebb2a8eab45e6441ed48134d8a..19cd376688627de9d3fe4e79272f57b3656700e0 100644 (file)
@@ -17,6 +17,7 @@
 mod graphviz;
 pub(crate) mod pretty;
 pub mod liveness;
+pub mod collect_writes;
 
 pub use self::alignment::is_disaligned;
 pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
index 1f6cc1f71fc0876c8e198b2bb8ff6327e33ec7af..e65c9de8df1eaf1dbf3277cde693fcf5e5ca79ee 100644 (file)
@@ -17,7 +17,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(rustc_diagnostic_macros)]
 
index 4cc65ee28e89f703d3ebd261907471b7e0e1fe00..b57debdd99486bda802323fe72cbc624d136d530 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(warnings)]
 #![allow(bad_style)]
 
 pub struct Intrinsic {
index c0f830f1fbe2ec2d846f95c2bd30f8e4554e42de..622d8e51a6ca3a2cbcdfb2a960600d16ae66a934 100644 (file)
@@ -63,7 +63,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(rustc_diagnostic_macros)]
 #![feature(staged_api)]
index d951a7f1cc1cdb90835c1adc8ecafaede64e1510..ef710ff7a7e4b6447775f404c25a39ac7040900d 100644 (file)
@@ -11,7 +11,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(rustc_diagnostic_macros)]
 
index 2bf17cd1317d449d4fcc5d20200ebdda9d30a57b..d32d853c18bf5d45f1e767c1bdaaeb1e732a3d56 100644 (file)
@@ -11,9 +11,9 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 
 #[macro_use]
 extern crate log;
@@ -1150,13 +1150,9 @@ fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f:
 
     fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
         let resolutions = self.resolutions.borrow();
-        let mut resolutions = resolutions.iter().map(|(&(ident, ns), &resolution)| {
-                                                    // Pre-compute keys for sorting
-                                                    (ident.name.as_str(), ns, ident, resolution)
-                                                })
-                                                .collect::<Vec<_>>();
-        resolutions.sort_unstable_by_key(|&(str, ns, ..)| (str, ns));
-        for &(_, ns, ident, resolution) in resolutions.iter() {
+        let mut resolutions = resolutions.iter().collect::<Vec<_>>();
+        resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.name.as_str(), ns));
+        for &(&(ident, ns), &resolution) in resolutions.iter() {
             resolution.borrow().binding.map(|binding| f(ident, ns, binding));
         }
     }
@@ -3341,7 +3337,9 @@ fn resolve_path(&mut self,
                         let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
                         let mut candidates =
                             self.lookup_import_candidates(name, TypeNS, is_mod);
-                        candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string()));
+                        candidates.sort_by_cached_key(|c| {
+                            (c.path.segments.len(), c.path.to_string())
+                        });
                         if let Some(candidate) = candidates.get(0) {
                             format!("Did you mean `{}`?", candidate.path)
                         } else {
@@ -3579,7 +3577,7 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
 
         let name = path[path.len() - 1].name;
         // Make sure error reporting is deterministic.
-        names.sort_by_key(|name| name.as_str());
+        names.sort_by_cached_key(|name| name.as_str());
         match find_best_match_for_name(names.iter(), &name.as_str(), None) {
             Some(found) if found != name => Some(found),
             _ => None,
index 4f46fb3545b15833f314e6d8ae1dda38067ac28a..fefedd4e1c819112bcf1f7a749830f7976b7d4cf 100644 (file)
@@ -11,7 +11,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 #![feature(custom_attribute)]
 #![feature(macro_lifetime_matcher)]
 #![allow(unused_attributes)]
index cfa3b6912f2e47cdd803a41477cdc368f4593a70..8136f6857a5c62cc8ff1eacd8a1cb371cb9e2a70 100644 (file)
@@ -11,8 +11,6 @@
 //! New recursive solver modeled on Chalk's recursive solver. Most of
 //! the guts are broken up into modules; see the comments in those modules.
 
-#![deny(warnings)]
-
 #![feature(crate_visibility_modifier)]
 
 #[macro_use]
index 153b2e730337dadd3b1519e5ad58521e4e1e4a0b..3d24b087c595834a0af70ccf0ebf5db716fbf6a1 100644 (file)
@@ -90,6 +90,28 @@ fn lower(&self) -> PolyDomainGoal<'tcx> {
     }
 }
 
+/// Transforms an existing goal into a FromEnv goal.
+///
+/// Used for lowered where clauses (see rustc guide).
+trait IntoFromEnvGoal {
+    fn into_from_env_goal(self) -> Self;
+}
+
+impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
+    fn into_from_env_goal(self) -> DomainGoal<'tcx> {
+        use self::DomainGoal::*;
+        match self {
+            Holds(wc_atom) => FromEnv(wc_atom),
+            WellFormed(..) |
+            FromEnv(..) |
+            WellFormedTy(..) |
+            FromEnvTy(..) |
+            RegionOutlives(..) |
+            TypeOutlives(..) => self,
+        }
+    }
+}
+
 crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     -> Lrc<Vec<Clause<'tcx>>>
 {
@@ -107,9 +129,9 @@ fn lower(&self) -> PolyDomainGoal<'tcx> {
 fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     -> Lrc<Vec<Clause<'tcx>>>
 {
-    // Rule Implemented-From-Env (see rustc guide)
-    //
     // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
+
+    // Rule Implemented-From-Env (see rustc guide)
     //
     // ```
     // forall<Self, P1..Pn> {
@@ -130,11 +152,50 @@ fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
     let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));
 
     // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
-    let clause = ProgramClause {
+    let implemented_from_env = ProgramClause {
         goal: impl_trait,
         hypotheses: vec![from_env],
     };
-    Lrc::new(vec![Clause::ForAll(ty::Binder::dummy(clause))])
+    let mut clauses = vec![
+        Clause::ForAll(ty::Binder::dummy(implemented_from_env))
+    ];
+
+    // Rule Implied-Bound-From-Trait
+    //
+    // For each where clause WC:
+    // ```
+    // forall<Self, P1..Pn> {
+    //   FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn)
+    // }
+    // ```
+
+    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
+    // FIXME: Remove the [1..] slice; this is a hack because the query
+    // predicates_of currently includes the trait itself (`Self: Trait<P1..Pn>`).
+    let where_clauses = &tcx.predicates_of(def_id).predicates;
+    let implied_bound_clauses =
+        where_clauses[1..].into_iter()
+        .map(|wc| implied_bound_from_trait(trait_pred, wc));
+    clauses.extend(implied_bound_clauses);
+
+    Lrc::new(clauses)
+}
+
+/// For a given `where_clause`, returns a clause `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`.
+fn implied_bound_from_trait<'tcx>(
+    trait_pred: ty::TraitPredicate<'tcx>,
+    where_clause: &ty::Predicate<'tcx>,
+) -> Clause<'tcx> {
+    // `FromEnv(Self: Trait<P1..Pn>)`
+    let impl_trait = DomainGoal::FromEnv(WhereClauseAtom::Implemented(trait_pred));
+
+    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
+    Clause::ForAll(
+        where_clause.lower().map_bound(|goal| ProgramClause {
+            goal: goal.into_from_env_goal(),
+            hypotheses: vec![impl_trait.into()],
+        })
+    )
 }
 
 fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
index fc699f7569f1c250ce7238c023dd4946384b4ebe..6c7565764119cae8d4150178e6b4a7f2cfd856bc 100644 (file)
@@ -1035,7 +1035,7 @@ pub fn start_async_translation(tcx: TyCtxt,
         crate_info,
 
         time_graph,
-        coordinator_send: tcx.tx_to_llvm_workers.clone(),
+        coordinator_send: tcx.tx_to_llvm_workers.lock().clone(),
         trans_worker_receive,
         shared_emitter_main,
         future: coordinator_thread,
@@ -1428,7 +1428,7 @@ fn start_executing_work(tcx: TyCtxt,
                         metadata_config: Arc<ModuleConfig>,
                         allocator_config: Arc<ModuleConfig>)
                         -> thread::JoinHandle<Result<CompiledModules, ()>> {
-    let coordinator_send = tcx.tx_to_llvm_workers.clone();
+    let coordinator_send = tcx.tx_to_llvm_workers.lock().clone();
     let sess = tcx.sess;
 
     // Compute the set of symbols we need to retain when doing LTO (if we need to)
@@ -2340,7 +2340,7 @@ pub(crate) fn submit_translated_module_to_llvm(tcx: TyCtxt,
                                                mtrans: ModuleTranslation,
                                                cost: u64) {
     let llvm_work_item = WorkItem::Optimize(mtrans);
-    drop(tcx.tx_to_llvm_workers.send(Box::new(Message::TranslationDone {
+    drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::TranslationDone {
         llvm_work_item,
         cost,
     })));
index 0329264a3125f3467ad30e31e5e509fef7c11d23..09aba830d050de149bb21d02830a51d910a49495 100644 (file)
@@ -82,7 +82,8 @@
 use std::str;
 use std::sync::Arc;
 use std::time::{Instant, Duration};
-use std::{i32, usize};
+use std::i32;
+use std::cmp;
 use std::sync::mpsc;
 use syntax_pos::Span;
 use syntax_pos::symbol::InternedString;
@@ -830,7 +831,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // a bit more efficiently.
     let codegen_units = {
         let mut codegen_units = codegen_units;
-        codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate());
+        codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
         codegen_units
     };
 
index 7664c88679e0e2db53e96489e24e467617bed0c3..87d9623e4003849ae98f67628a40d12090fe155d 100644 (file)
@@ -42,7 +42,7 @@
 
 use syntax_pos::{self, Span, Pos};
 use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, InternedString};
 use rustc::ty::layout::{self, LayoutOf};
 
 pub mod gdb;
@@ -393,7 +393,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
             substs.types().zip(names).map(|(ty, name)| {
                 let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                 let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
-                let name = CString::new(name.as_str().as_bytes()).unwrap();
+                let name = CString::new(name.as_bytes()).unwrap();
                 unsafe {
                     llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -412,7 +412,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         return create_DIArray(DIB(cx), &template_params[..]);
     }
 
-    fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<ast::Name> {
+    fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<InternedString> {
         let mut names = generics.parent.map_or(vec![], |def_id| {
             get_type_parameter_names(cx, cx.tcx.generics_of(def_id))
         });
index 344f959c1414ce29ca1ac4e2bf762314463cca59..a38d51e754670dd96d8d4cb55cac1fe572d0b493 100644 (file)
@@ -17,7 +17,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
@@ -27,6 +26,7 @@
 #![feature(libc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(optin_builtin_traits)]
 #![feature(inclusive_range_fields)]
 #![feature(underscore_lifetimes)]
index cf47d9b62a94e3578942ee06a50584f1da6f88b6..b297fd9986501946f99efd2e29979133332406fd 100644 (file)
@@ -15,7 +15,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
index 0e93277983f8d9fa8400190d15d8c511cd48069b..c4ea543ab36b6d8cd33cf831b7c2db4b8ec7e0e9 100644 (file)
@@ -979,7 +979,7 @@ pub fn def_to_ty(&self,
                 let item_def_id = tcx.hir.local_def_id(item_id);
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id)];
-                tcx.mk_param(index, tcx.hir.name(node_id))
+                tcx.mk_param(index, tcx.hir.name(node_id).as_str())
             }
             Def::SelfTy(_, Some(def_id)) => {
                 // Self in impl (we know the concrete type).
index 377e3a891840f786bb36baed7aa71fdf2d6abf9c..da0d4509353b5652e3a9798e45ea3e513cca9ec6 100644 (file)
@@ -76,7 +76,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 /// and in libcore/intrinsics.rs
 pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       it: &hir::ForeignItem) {
-    let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n)));
+    let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n)).as_str());
     let name = it.name.as_str();
     let (n_tps, inputs, output) = if name.starts_with("atomic_") {
         let split : Vec<&str> = name.split('_').collect();
@@ -341,7 +341,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                it: &hir::ForeignItem) {
     let param = |n| {
-        let name = Symbol::intern(&format!("P{}", n));
+        let name = Symbol::intern(&format!("P{}", n)).as_str();
         tcx.mk_param(n, name)
     };
 
index fa2022e8cc994ea5ddff0685719f413c5cd7be15..de5709566225c54cc595f7340155edbc9264fdf7 100644 (file)
@@ -799,7 +799,7 @@ fn candidate_method_names(&self) -> Vec<ast::Name> {
             .collect();
 
         // sort them by the name so we have a stable result
-        names.sort_by_key(|n| n.as_str());
+        names.sort_by_cached_key(|n| n.as_str());
         names
     }
 
index 7dc73a1d5f01977a45aa07581030c55753b5414c..6348f3861770ff0065104b1ab6299ea7e8f41a51 100644 (file)
@@ -655,7 +655,7 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
             // local so it should be okay to just unwrap everything.
             let trait_def_id = impl_params[&method_param.name];
             let trait_decl_span = tcx.def_span(trait_def_id);
-            error_194(tcx, type_span, trait_decl_span, method_param.name);
+            error_194(tcx, type_span, trait_decl_span, &method_param.name[..]);
         }
     }
 }
@@ -759,7 +759,7 @@ fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast:
     err
 }
 
-fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
+fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: &str) {
     struct_span_err!(tcx.sess, span, E0194,
               "type parameter `{}` shadows another type parameter of the same name",
               name)
index 59156bf0dfeaa0c5a874f381fb41eeb2b8f7f884..a4f820d1fdcf9553488b85b9da013929f9307f47 100644 (file)
@@ -241,7 +241,7 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let param_owner_def_id = tcx.hir.local_def_id(param_owner);
     let generics = tcx.generics_of(param_owner_def_id);
     let index = generics.type_param_to_index[&def_id];
-    let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
+    let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id).as_str());
 
     // Don't look for bounds where the type parameter isn't in scope.
     let parent = if item_def_id == param_owner_def_id {
@@ -839,7 +839,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
                     opt_self = Some(ty::TypeParameterDef {
                         index: 0,
-                        name: keywords::SelfType.name(),
+                        name: keywords::SelfType.name().as_str(),
                         def_id: tcx.hir.local_def_id(param_id),
                         has_default: false,
                         object_lifetime_default: rl::Set1::Empty,
@@ -915,7 +915,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         ty::TypeParameterDef {
             index: type_start + i as u32,
-            name: p.name,
+            name: p.name.as_str(),
             def_id: tcx.hir.local_def_id(p.id),
             has_default: p.default.is_some(),
             object_lifetime_default:
@@ -934,7 +934,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // add a dummy parameter for the closure kind
         types.push(ty::TypeParameterDef {
             index: type_start,
-            name: Symbol::intern("<closure_kind>"),
+            name: Symbol::intern("<closure_kind>").as_str(),
             def_id,
             has_default: false,
             object_lifetime_default: rl::Set1::Empty,
@@ -945,7 +945,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // add a dummy parameter for the closure signature
         types.push(ty::TypeParameterDef {
             index: type_start + 1,
-            name: Symbol::intern("<closure_signature>"),
+            name: Symbol::intern("<closure_signature>").as_str(),
             def_id,
             has_default: false,
             object_lifetime_default: rl::Set1::Empty,
@@ -956,7 +956,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         tcx.with_freevars(node_id, |fv| {
             types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef {
                 index: type_start + i,
-                name: Symbol::intern("<upvar>"),
+                name: Symbol::intern("<upvar>").as_str(),
                 def_id,
                 has_default: false,
                 object_lifetime_default: rl::Set1::Empty,
@@ -1436,7 +1436,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T:Foo>`).
     for param in ast_generics.ty_params() {
-        let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
+        let param_ty = ty::ParamTy::new(index, param.name.as_str()).to_ty(tcx);
         index += 1;
 
         let bounds = compute_bounds(&icx,
index 6f71db998bd419e4b8513a59acec722543eb547c..3a48e1806af2cad25b83d5037b35b192576b4673 100644 (file)
@@ -68,7 +68,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![allow(non_camel_case_types)]
 
 #![feature(crate_visibility_modifier)]
 #![feature(from_ref)]
 #![feature(exhaustive_patterns)]
-#![feature(option_filter)]
 #![feature(quote)]
 #![feature(refcell_replace_swap)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(dyn_trait)]
 
 #[macro_use] extern crate log;
index a87e1df5efc2c1d8258d68557294daf518e82982..888148352c70a46a26d432213771912302c6ad7d 100644 (file)
@@ -260,7 +260,9 @@ fn ty_param_to_ty(&self, param: ty::TypeParameterDef) -> hir::Ty {
                 P(hir::Path {
                     span: DUMMY_SP,
                     def: Def::TyParam(param.def_id),
-                    segments: HirVec::from_vec(vec![hir::PathSegment::from_name(param.name)]),
+                    segments: HirVec::from_vec(vec![
+                        hir::PathSegment::from_name(Symbol::intern(&param.name))
+                    ]),
                 }),
             )),
             span: DUMMY_SP,
@@ -1435,9 +1437,7 @@ fn sort_where_lifetimes(&self, mut bounds: &mut Vec<Lifetime>) {
     // involved (impls rarely have more than a few bounds) means that it
     // shouldn't matter in practice.
     fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
-        vec.sort_unstable_by(|first, second| {
-            format!("{:?}", first).cmp(&format!("{:?}", second))
-        });
+        vec.sort_by_cached_key(|x| format!("{:?}", x))
     }
 
     fn is_fn_ty(&self, tcx: &TyCtxt, ty: &Type) -> bool {
index b57c9589afabc7792c3d1d7a782817d010fa0c53..da8085d84c3f6729d8cda184f862d1a52b20147b 100644 (file)
@@ -27,7 +27,7 @@
 use syntax::feature_gate::UnstableFeatures;
 use syntax::ptr::P;
 use syntax::symbol::keywords;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, InternedString};
 use syntax_pos::{self, DUMMY_SP, Pos, FileName};
 
 use rustc::middle::const_val::ConstVal;
@@ -1787,7 +1787,7 @@ fn clean(&self, cx: &DocContext) -> Generics {
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
         // them.
         let stripped_typarams = gens.types.iter().filter_map(|tp| {
-            if tp.name == keywords::SelfType.name() {
+            if tp.name == keywords::SelfType.name().as_str() {
                 assert_eq!(tp.index, 0);
                 None
             } else {
@@ -3367,6 +3367,12 @@ fn clean(&self, _: &DocContext) -> String {
     }
 }
 
+impl Clean<String> for InternedString {
+    fn clean(&self, _: &DocContext) -> String {
+        self.to_string()
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Typedef {
     pub type_: Type,
index 72c4c4e4495ea1b7737d722334176a6c64eed8f8..9e2c7bd7ef1ed6fc808192442760279ac88b7a76 100644 (file)
@@ -1087,7 +1087,8 @@ fn emit_source(&mut self, filename: &FileName) -> io::Result<()> {
             href.push_str(component);
             href.push('/');
         });
-        let mut fname = p.file_name().expect("source has no filename")
+        let mut fname = p.file_name()
+                         .expect("source has no filename")
                          .to_os_string();
         fname.push(".html");
         cur.push(&fname);
@@ -1373,6 +1374,135 @@ fn generics(&mut self, generics: &clean::Generics) {
     }
 }
 
+#[derive(Debug, Eq, PartialEq, Hash)]
+struct ItemEntry {
+    url: String,
+    name: String,
+}
+
+impl ItemEntry {
+    fn new(mut url: String, name: String) -> ItemEntry {
+        while url.starts_with('/') {
+            url.remove(0);
+        }
+        ItemEntry {
+            url,
+            name,
+        }
+    }
+}
+
+impl fmt::Display for ItemEntry {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "<a href='{}'>{}</a>", self.url, Escape(&self.name))
+    }
+}
+
+impl PartialOrd for ItemEntry {
+    fn partial_cmp(&self, other: &ItemEntry) -> Option<::std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for ItemEntry {
+    fn cmp(&self, other: &ItemEntry) -> ::std::cmp::Ordering {
+        self.name.cmp(&other.name)
+    }
+}
+
+#[derive(Debug)]
+struct AllTypes {
+    structs: HashSet<ItemEntry>,
+    enums: HashSet<ItemEntry>,
+    unions: HashSet<ItemEntry>,
+    primitives: HashSet<ItemEntry>,
+    traits: HashSet<ItemEntry>,
+    macros: HashSet<ItemEntry>,
+    functions: HashSet<ItemEntry>,
+    typedefs: HashSet<ItemEntry>,
+    statics: HashSet<ItemEntry>,
+    constants: HashSet<ItemEntry>,
+}
+
+impl AllTypes {
+    fn new() -> AllTypes {
+        AllTypes {
+            structs: HashSet::with_capacity(100),
+            enums: HashSet::with_capacity(100),
+            unions: HashSet::with_capacity(100),
+            primitives: HashSet::with_capacity(26),
+            traits: HashSet::with_capacity(100),
+            macros: HashSet::with_capacity(100),
+            functions: HashSet::with_capacity(100),
+            typedefs: HashSet::with_capacity(100),
+            statics: HashSet::with_capacity(100),
+            constants: HashSet::with_capacity(100),
+        }
+    }
+
+    fn append(&mut self, item_name: String, item_type: &ItemType) {
+        let mut url: Vec<_> = item_name.split("::").skip(1).collect();
+        if let Some(name) = url.pop() {
+            let new_url = format!("{}/{}.{}.html", url.join("/"), item_type, name);
+            url.push(name);
+            let name = url.join("::");
+            match *item_type {
+                ItemType::Struct => self.structs.insert(ItemEntry::new(new_url, name)),
+                ItemType::Enum => self.enums.insert(ItemEntry::new(new_url, name)),
+                ItemType::Union => self.unions.insert(ItemEntry::new(new_url, name)),
+                ItemType::Primitive => self.primitives.insert(ItemEntry::new(new_url, name)),
+                ItemType::Trait => self.traits.insert(ItemEntry::new(new_url, name)),
+                ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
+                ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
+                ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)),
+                ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
+                ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
+                _ => true,
+            };
+        }
+    }
+}
+
+fn print_entries(f: &mut fmt::Formatter, e: &HashSet<ItemEntry>, title: &str,
+                 class: &str) -> fmt::Result {
+    if !e.is_empty() {
+        let mut e: Vec<&ItemEntry> = e.iter().collect();
+        e.sort();
+        write!(f, "<h3 id='{}'>{}</h3><ul class='{} docblock'>{}</ul>",
+               title,
+               Escape(title),
+               class,
+               e.iter().map(|s| format!("<li>{}</li>", s)).collect::<String>())?;
+    }
+    Ok(())
+}
+
+impl fmt::Display for AllTypes {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f,
+"<h1 class='fqn'>\
+     <span class='in-band'>List of all items</span>\
+     <span class='out-of-band'>\
+         <span id='render-detail'>\
+             <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
+                 [<span class='inner'>&#x2212;</span>]\
+             </a>\
+         </span>
+     </span>
+</h1>")?;
+        print_entries(f, &self.structs, "Structs", "structs")?;
+        print_entries(f, &self.enums, "Enums", "enums")?;
+        print_entries(f, &self.unions, "Unions", "unions")?;
+        print_entries(f, &self.primitives, "Primitives", "primitives")?;
+        print_entries(f, &self.traits, "Traits", "traits")?;
+        print_entries(f, &self.macros, "Macros", "macros")?;
+        print_entries(f, &self.functions, "Functions", "functions")?;
+        print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
+        print_entries(f, &self.statics, "Statics", "statics")?;
+        print_entries(f, &self.constants, "Constants", "constants")
+    }
+}
+
 impl Context {
     /// String representation of how to get back to the root path of the 'doc/'
     /// folder in terms of a relative URL.
@@ -1414,16 +1544,52 @@ fn krate(self, mut krate: clean::Crate) -> Result<(), Error> {
             Some(i) => i,
             None => return Ok(()),
         };
+        let final_file = self.dst.join(&krate.name)
+                                 .join("all.html");
+        let crate_name = krate.name.clone();
         item.name = Some(krate.name);
 
-        // Render the crate documentation
-        let mut work = vec![(self, item)];
+        let mut all = AllTypes::new();
 
-        while let Some((mut cx, item)) = work.pop() {
-            cx.item(item, |cx, item| {
-                work.push((cx.clone(), item))
-            })?
+        {
+            // Render the crate documentation
+            let mut work = vec![(self.clone(), item)];
+
+            while let Some((mut cx, item)) = work.pop() {
+                cx.item(item, &mut all, |cx, item| {
+                    work.push((cx.clone(), item))
+                })?
+            }
         }
+
+        let mut w = BufWriter::new(try_err!(File::create(&final_file), &final_file));
+        let mut root_path = self.dst.to_str().expect("invalid path").to_owned();
+        if !root_path.ends_with('/') {
+            root_path.push('/');
+        }
+        let page = layout::Page {
+            title: "List of all items in this crate",
+            css_class: "mod",
+            root_path: "../",
+            description: "List of all items in this crate",
+            keywords: BASIC_KEYWORDS,
+            resource_suffix: &self.shared.resource_suffix,
+        };
+        let sidebar = if let Some(ref version) = cache().crate_version {
+            format!("<p class='location'>Crate {}</p>\
+                     <div class='block version'>\
+                         <p>Version {}</p>\
+                     </div>\
+                     <a id='all-types' href='index.html'><p>Back to index</p></a>",
+                    crate_name, version)
+        } else {
+            String::new()
+        };
+        try_err!(layout::render(&mut w, &self.shared.layout,
+                                &page, &sidebar, &all,
+                                self.shared.css_file_extension.is_some(),
+                                &self.shared.themes),
+                 &final_file);
         Ok(())
     }
 
@@ -1496,8 +1662,8 @@ fn render_item(&self,
     /// all sub-items which need to be rendered.
     ///
     /// The rendering driver uses this closure to queue up more work.
-    fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
-        F: FnMut(&mut Context, clean::Item),
+    fn item<F>(&mut self, item: clean::Item, all: &mut AllTypes, mut f: F) -> Result<(), Error>
+        where F: FnMut(&mut Context, clean::Item),
     {
         // Stripped modules survive the rustdoc passes (i.e. `strip-private`)
         // if they contain impls for public types. These modules can also
@@ -1544,7 +1710,7 @@ fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
                 }
 
                 for item in m.items {
-                    f(this,item);
+                    f(this, item);
                 }
 
                 Ok(())
@@ -1562,13 +1728,14 @@ fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
                 let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
                 try_err!(dst.write_all(&buf), &joint_dst);
 
+                all.append(full_path(self, &item), &item_type);
                 // Redirect from a sane URL using the namespace to Rustdoc's
                 // URL for the page.
                 let redir_name = format!("{}.{}.html", name, item_type.name_space());
                 let redir_dst = self.dst.join(redir_name);
                 if let Ok(redirect_out) = OpenOptions::new().create_new(true)
-                                                                .write(true)
-                                                                .open(&redir_dst) {
+                                                            .write(true)
+                                                            .open(&redir_dst) {
                     let mut redirect_out = BufWriter::new(redirect_out);
                     try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
                 }
@@ -1730,11 +1897,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                    version)?;
         }
         write!(fmt,
-               r##"<span id='render-detail'>
-                   <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
-                       [<span class='inner'>&#x2212;</span>]
-                   </a>
-               </span>"##)?;
+               "<span id='render-detail'>\
+                   <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
+                      title=\"collapse all docs\">\
+                       [<span class='inner'>&#x2212;</span>]\
+                   </a>\
+               </span>")?;
 
         // Write `src` tag
         //
@@ -3567,24 +3735,23 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
         if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
             || it.is_enum() || it.is_mod() || it.is_typedef() {
-            write!(fmt, "<p class='location'>")?;
-            match it.inner {
-                clean::StructItem(..) => write!(fmt, "Struct ")?,
-                clean::TraitItem(..) => write!(fmt, "Trait ")?,
-                clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
-                clean::UnionItem(..) => write!(fmt, "Union ")?,
-                clean::EnumItem(..) => write!(fmt, "Enum ")?,
-                clean::TypedefItem(..) => write!(fmt, "Type Definition ")?,
-                clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
-                clean::ModuleItem(..) => if it.is_crate() {
-                    write!(fmt, "Crate ")?;
-                } else {
-                    write!(fmt, "Module ")?;
+            write!(fmt, "<p class='location'>{}{}</p>",
+                match it.inner {
+                    clean::StructItem(..) => "Struct ",
+                    clean::TraitItem(..) => "Trait ",
+                    clean::PrimitiveItem(..) => "Primitive Type ",
+                    clean::UnionItem(..) => "Union ",
+                    clean::EnumItem(..) => "Enum ",
+                    clean::TypedefItem(..) => "Type Definition ",
+                    clean::ForeignTypeItem => "Foreign Type ",
+                    clean::ModuleItem(..) => if it.is_crate() {
+                        "Crate "
+                    } else {
+                        "Module "
+                    },
+                    _ => "",
                 },
-                _ => (),
-            }
-            write!(fmt, "{}", it.name.as_ref().unwrap())?;
-            write!(fmt, "</p>")?;
+                it.name.as_ref().unwrap())?;
         }
 
         if it.is_crate() {
@@ -3592,8 +3759,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                 write!(fmt,
                        "<div class='block version'>\
                         <p>Version {}</p>\
-                        </div>",
-                       version)?;
+                        </div>
+                        <a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
+                       version,
+                       it.name.as_ref().unwrap())?;
             }
         }
 
index f4918033c8e882d8838367d2ce247fe77e6166ed..4c6c8dcfddafc033ba00137fa46cb416ac7396a1 100644 (file)
@@ -1294,3 +1294,21 @@ kbd {
        font-size: 19px;
        display: block;
 }
+
+#main > ul {
+       padding-left: 10px;
+}
+#main > ul > li {
+       list-style: none;
+}
+#all-types {
+       text-align: center;
+       border: 1px solid;
+       margin: 0 10px;
+       margin-bottom: 10px;
+       display: block;
+       border-radius: 7px;
+}
+#all-types > p {
+       margin: 5px 0;
+}
\ No newline at end of file
index 09776569f80bf8cee1c4ab432fb598a9b43c44c4..93971a205bf35d71d2730370423d1950efbafd11 100644 (file)
@@ -389,3 +389,10 @@ kbd {
                background: #f0f0f0;
        }
 }
+
+#all-types {
+       background-color: #505050;
+}
+#all-types:hover {
+       background-color: #606060;
+}
index 2334a2728554ea66dd8d345264a59e1e03ce843e..e13818b4bd27867fa9bc05f2ec8651378a6f97bd 100644 (file)
@@ -383,3 +383,10 @@ kbd {
                background: #fff;
        }
 }
+
+#all-types {
+       background-color: #fff;
+}
+#all-types:hover {
+       background-color: #f9f9f9;
+}
\ No newline at end of file
index 42e87f88fd40d475b5b7143511ff3a6c47817f4e..b87777ac4b5c1b18894cf7329c8bec998ca2acee 100644 (file)
@@ -12,7 +12,6 @@
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/")]
-#![deny(warnings)]
 
 #![feature(ascii_ctype)]
 #![feature(rustc_private)]
@@ -20,6 +19,7 @@
 #![feature(box_syntax)]
 #![feature(fs_read_write)]
 #![feature(set_stdio)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(test)]
 #![feature(unicode)]
 #![feature(vec_remove_item)]
index f78eed30694786cf17d59a1291bba7fff4d3691b..22d27b6697a7c8973257ba0c4de88528971f82d4 100644 (file)
@@ -19,7 +19,6 @@
        html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/",
        test(attr(allow(unused_variables), deny(warnings))))]
-#![deny(warnings)]
 
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
index 3b8c42ddb39d89d4e390ded3268be11350147859..b02e133ee4dd72176d847361268cc3fd08005cdc 100644 (file)
@@ -1829,7 +1829,6 @@ pub fn limit(&self) -> u64 { self.limit }
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(take_set_limit)]
     /// use std::io;
     /// use std::io::prelude::*;
     /// use std::fs::File;
@@ -1845,7 +1844,7 @@ pub fn limit(&self) -> u64 { self.limit }
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "take_set_limit", issue = "42781")]
+    #[stable(feature = "take_set_limit", since = "1.27.0")]
     pub fn set_limit(&mut self, limit: u64) {
         self.limit = limit;
     }
index 3227aa9acff2358de36e85c13c377c14894b45fa..672723341eb574a2a63524bf739a41050dfd68cd 100644 (file)
 // Tell the compiler to link to either panic_abort or panic_unwind
 #![needs_panic_runtime]
 
-// Turn warnings into errors, but only after stage0, where it can be useful for
-// code to emit warnings during language transitions
-#![cfg_attr(not(stage0), deny(warnings))]
-
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 
index c22ea1671fa590131310a79241383043169d31d0..cf8c101a2f91f0dc6c781ceb457910e312eb7c7f 100644 (file)
@@ -27,7 +27,6 @@
        html_playground_url = "https://play.rust-lang.org/",
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
-#![deny(warnings)]
 #![deny(missing_debug_implementations)]
 #![no_std]
 
index a09bea25a249c55daeeca573a69cef2a7c47a542..c25a7686bead0e8296460215c42d1d199feaa8cc 100644 (file)
@@ -28,7 +28,7 @@
 use std::iter;
 use std::path::PathBuf;
 use std::rc::Rc;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{self, Lrc};
 use std::default::Default;
 use tokenstream::{self, TokenStream};
 
@@ -565,26 +565,26 @@ pub enum SyntaxExtension {
     /// `#[derive(...)]` is a `MultiItemDecorator`.
     ///
     /// Prefer ProcMacro or MultiModifier since they are more flexible.
-    MultiDecorator(Box<MultiItemDecorator>),
+    MultiDecorator(Box<MultiItemDecorator + sync::Sync + sync::Send>),
 
     /// A syntax extension that is attached to an item and modifies it
     /// in-place. Also allows decoration, i.e., creating new items.
-    MultiModifier(Box<MultiItemModifier>),
+    MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>),
 
     /// A function-like procedural macro. TokenStream -> TokenStream.
-    ProcMacro(Box<ProcMacro>),
+    ProcMacro(Box<ProcMacro + sync::Sync + sync::Send>),
 
     /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream.
     /// The first TokenSteam is the attribute, the second is the annotated item.
     /// Allows modification of the input items and adding new items, similar to
     /// MultiModifier, but uses TokenStreams, rather than AST nodes.
-    AttrProcMacro(Box<AttrProcMacro>),
+    AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>),
 
     /// A normal, function-like syntax extension.
     ///
     /// `bytes!` is a `NormalTT`.
     NormalTT {
-        expander: Box<TTMacroExpander>,
+        expander: Box<TTMacroExpander + sync::Sync + sync::Send>,
         def_info: Option<(ast::NodeId, Span)>,
         /// Whether the contents of the macro can
         /// directly use `#[unstable]` things (true == yes).
@@ -599,13 +599,15 @@ pub enum SyntaxExtension {
     /// A function-like syntax extension that has an extra ident before
     /// the block.
     ///
-    IdentTT(Box<IdentMacroExpander>, Option<Span>, bool),
+    IdentTT(Box<IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
 
     /// An attribute-like procedural macro. TokenStream -> TokenStream.
     /// The input is the annotated item.
     /// Allows generating code to implement a Trait for a given struct
     /// or enum item.
-    ProcMacroDerive(Box<MultiItemModifier>, Vec<Symbol> /* inert attribute names */),
+    ProcMacroDerive(Box<MultiItemModifier +
+                        sync::Sync +
+                        sync::Send>, Vec<Symbol> /* inert attribute names */),
 
     /// An attribute-like procedural macro that derives a builtin trait.
     BuiltinDerive(BuiltinDeriveFn),
@@ -613,7 +615,7 @@ pub enum SyntaxExtension {
     /// A declarative macro, e.g. `macro m() {}`.
     ///
     /// The second element is the definition site span.
-    DeclMacro(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>),
+    DeclMacro(Box<TTMacroExpander + sync::Sync + sync::Send>, Option<(ast::NodeId, Span)>),
 }
 
 impl SyntaxExtension {
index c456dc45d2182dd43cce74b7b29b30bd203f4f83..dbf2123fb5477a69c65c26867341ea86f527ac53 100644 (file)
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        test(attr(deny(warnings))))]
-#![deny(warnings)]
 
 #![feature(unicode)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(non_exhaustive)]
 #![feature(const_atomic_usize_new)]
 #![feature(rustc_attrs)]
 
+#![recursion_limit="256"]
+
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
 #[allow(unused_extern_crates)]
 extern crate rustc_cratesio_shim;
index 152c4c31eb3e3669ee7731958a4b6333503bae1a..39b2f77f2305e717d62216d22a8b53c3cfee0059 100644 (file)
@@ -1781,7 +1781,6 @@ mod tests {
     use errors;
     use feature_gate::UnstableFeatures;
     use parse::token;
-    use std::cell::RefCell;
     use std::collections::HashSet;
     use std::io;
     use std::path::PathBuf;
@@ -1797,12 +1796,12 @@ fn mk_sess(cm: Lrc<CodeMap>) -> ParseSess {
             span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)),
             unstable_features: UnstableFeatures::from_environment(),
             config: CrateConfig::new(),
-            included_mod_stack: RefCell::new(Vec::new()),
+            included_mod_stack: Lock::new(Vec::new()),
             code_map: cm,
-            missing_fragment_specifiers: RefCell::new(HashSet::new()),
-            raw_identifier_spans: RefCell::new(Vec::new()),
+            missing_fragment_specifiers: Lock::new(HashSet::new()),
+            raw_identifier_spans: Lock::new(Vec::new()),
             registered_diagnostics: Lock::new(ErrorMap::new()),
-            non_modrs_mods: RefCell::new(vec![]),
+            non_modrs_mods: Lock::new(vec![]),
         }
     }
 
index 428b3b136df76edb2c51a507d130db258fd9a355..ff63c9a5c6d539ac1614011b5096a6aff631cc53 100644 (file)
@@ -23,7 +23,6 @@
 use tokenstream::{TokenStream, TokenTree};
 use diagnostics::plugin::ErrorMap;
 
-use std::cell::RefCell;
 use std::collections::HashSet;
 use std::iter;
 use std::path::{Path, PathBuf};
@@ -46,17 +45,17 @@ pub struct ParseSess {
     pub span_diagnostic: Handler,
     pub unstable_features: UnstableFeatures,
     pub config: CrateConfig,
-    pub missing_fragment_specifiers: RefCell<HashSet<Span>>,
+    pub missing_fragment_specifiers: Lock<HashSet<Span>>,
     /// Places where raw identifiers were used. This is used for feature gating
     /// raw identifiers
-    pub raw_identifier_spans: RefCell<Vec<Span>>,
+    pub raw_identifier_spans: Lock<Vec<Span>>,
     /// The registered diagnostics codes
     pub registered_diagnostics: Lock<ErrorMap>,
     // Spans where a `mod foo;` statement was included in a non-mod.rs file.
     // These are used to issue errors if the non_modrs_mods feature is not enabled.
-    pub non_modrs_mods: RefCell<Vec<(ast::Ident, Span)>>,
+    pub non_modrs_mods: Lock<Vec<(ast::Ident, Span)>>,
     /// Used to determine and report recursive mod inclusions
-    included_mod_stack: RefCell<Vec<PathBuf>>,
+    included_mod_stack: Lock<Vec<PathBuf>>,
     code_map: Lrc<CodeMap>,
 }
 
@@ -75,12 +74,12 @@ pub fn with_span_handler(handler: Handler, code_map: Lrc<CodeMap>) -> ParseSess
             span_diagnostic: handler,
             unstable_features: UnstableFeatures::from_environment(),
             config: HashSet::new(),
-            missing_fragment_specifiers: RefCell::new(HashSet::new()),
-            raw_identifier_spans: RefCell::new(Vec::new()),
+            missing_fragment_specifiers: Lock::new(HashSet::new()),
+            raw_identifier_spans: Lock::new(Vec::new()),
             registered_diagnostics: Lock::new(ErrorMap::new()),
-            included_mod_stack: RefCell::new(vec![]),
+            included_mod_stack: Lock::new(vec![]),
             code_map,
-            non_modrs_mods: RefCell::new(vec![]),
+            non_modrs_mods: Lock::new(vec![]),
         }
     }
 
index e6da5bcaa3ae6cc61a8bd84b9445211274fcb2e8..027b24cbbdcd69cae1eea65576ef658fa368a4b4 100644 (file)
@@ -689,7 +689,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
                 .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
                 .chain(self.expected_tokens.iter().cloned())
                 .collect::<Vec<_>>();
-            expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
+            expected.sort_by_cached_key(|x| x.to_string());
             expected.dedup();
             let expect = tokens_to_string(&expected[..]);
             let actual = self.this_token_to_string();
@@ -2830,7 +2830,48 @@ pub fn parse_prefix_expr(&mut self,
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 (lo.to(span), ExprKind::Box(e))
             }
-            _ => return self.parse_dot_or_call_expr(Some(attrs))
+            token::Ident(..) if self.token.is_ident_named("not") => {
+                // `not` is just an ordinary identifier in Rust-the-language,
+                // but as `rustc`-the-compiler, we can issue clever diagnostics
+                // for confused users who really want to say `!`
+                let token_cannot_continue_expr = |t: &token::Token| match *t {
+                    // These tokens can start an expression after `!`, but
+                    // can't continue an expression after an ident
+                    token::Ident(ident, is_raw) => token::ident_can_begin_expr(ident, is_raw),
+                    token::Literal(..) | token::Pound => true,
+                    token::Interpolated(ref nt) => match nt.0 {
+                        token::NtIdent(..) | token::NtExpr(..) |
+                        token::NtBlock(..) | token::NtPath(..) => true,
+                        _ => false,
+                    },
+                    _ => false
+                };
+                let cannot_continue_expr = self.look_ahead(1, token_cannot_continue_expr);
+                if cannot_continue_expr {
+                    self.bump();
+                    // Emit the error ...
+                    let mut err = self.diagnostic()
+                        .struct_span_err(self.span,
+                                         &format!("unexpected {} after identifier",
+                                                  self.this_token_descr()));
+                    // span the `not` plus trailing whitespace to avoid
+                    // trailing whitespace after the `!` in our suggestion
+                    let to_replace = self.sess.codemap()
+                        .span_until_non_whitespace(lo.to(self.span));
+                    err.span_suggestion_short(to_replace,
+                                              "use `!` to perform logical negation",
+                                              "!".to_owned());
+                    err.emit();
+                    // â€”and recover! (just as if we were in the block
+                    // for the `token::Not` arm)
+                    let e = self.parse_prefix_expr(None);
+                    let (span, e) = self.interpolated_or_expr_span(e)?;
+                    (lo.to(span), self.mk_unary(UnOp::Not, e))
+                } else {
+                    return self.parse_dot_or_call_expr(Some(attrs));
+                }
+            }
+            _ => { return self.parse_dot_or_call_expr(Some(attrs)); }
         };
         return Ok(self.mk_expr(lo.to(hi), ex, attrs));
     }
@@ -4486,6 +4527,11 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
             // Which is valid in other languages, but not Rust.
             match self.parse_stmt_without_recovery(false) {
                 Ok(Some(stmt)) => {
+                    if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) {
+                        // if the next token is an open brace (e.g., `if a b {`), the place-
+                        // inside-a-block suggestion would be more likely wrong than right
+                        return Err(e);
+                    }
                     let mut stmt_span = stmt.span;
                     // expand the span to include the semicolon, if it exists
                     if self.eat(&token::Semi) {
index 6544619af9c707379e9ade92f080e3300c500ec6..8da79f92768a1c31e3658f7a6b4654301f2ebada 100644 (file)
@@ -25,9 +25,8 @@
 use tokenstream::{TokenStream, TokenTree};
 use tokenstream;
 
-use std::cell::Cell;
 use std::{cmp, fmt};
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, Lock};
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
 pub enum BinOpToken {
@@ -91,7 +90,7 @@ pub fn short_name(&self) -> &'static str {
     }
 }
 
-fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool {
+pub(crate) fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool {
     let ident_token: Token = Ident(ident, is_raw);
 
     !ident_token.is_reserved_ident() ||
@@ -348,6 +347,15 @@ pub fn is_lifetime(&self) -> bool {
         self.lifetime().is_some()
     }
 
+    /// Returns `true` if the token is a identifier whose name is the given
+    /// string slice.
+    pub fn is_ident_named(&self, name: &str) -> bool {
+        match self.ident() {
+            Some((ident, _)) => ident.name.as_str() == name,
+            None => false
+        }
+    }
+
     /// Returns `true` if the token is a documentation comment.
     pub fn is_doc_comment(&self) -> bool {
         match *self {
@@ -618,15 +626,8 @@ pub fn is_op(tok: &Token) -> bool {
     }
 }
 
-pub struct LazyTokenStream(Cell<Option<TokenStream>>);
-
-impl Clone for LazyTokenStream {
-    fn clone(&self) -> Self {
-        let opt_stream = self.0.take();
-        self.0.set(opt_stream.clone());
-        LazyTokenStream(Cell::new(opt_stream))
-    }
-}
+#[derive(Clone)]
+pub struct LazyTokenStream(Lock<Option<TokenStream>>);
 
 impl cmp::Eq for LazyTokenStream {}
 impl PartialEq for LazyTokenStream {
@@ -643,15 +644,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl LazyTokenStream {
     pub fn new() -> Self {
-        LazyTokenStream(Cell::new(None))
+        LazyTokenStream(Lock::new(None))
     }
 
     pub fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream {
-        let mut opt_stream = self.0.take();
+        let mut opt_stream = self.0.lock();
         if opt_stream.is_none() {
-            opt_stream = Some(f());
+            *opt_stream = Some(f());
         }
-        self.0.set(opt_stream.clone());
         opt_stream.clone().unwrap()
     }
 }
index 249a64b353f5912f981425e92c1b94b7c3f7e928..97e34c554d116f66fa8ab262381df5cf48f1c4b3 100644 (file)
@@ -13,7 +13,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(proc_macro_internals)]
 #![feature(decl_macro)]
index 33428eb271abd8a381bbfac32f438fab66e9cd85..9a7d1fd8ee6cb9a508579a3029cfe09d449b6860 100644 (file)
@@ -17,7 +17,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![deny(warnings)]
 
 #![feature(const_fn)]
 #![feature(custom_attribute)]
index ad0e582b1c324e4ef38ab460476c2b19e7696037..a012f4e776fb21b69ed8ddbd10ae4bad44f43372 100644 (file)
@@ -46,7 +46,6 @@
        html_playground_url = "https://play.rust-lang.org/",
        test(attr(deny(warnings))))]
 #![deny(missing_docs)]
-#![deny(warnings)]
 
 #![cfg_attr(windows, feature(libc))]
 // Handle rustfmt skips
index b8be1aeff174278244bca9fcfebc509c1fecb3f7..9291eaa910bd744d745935eb295fc6efac275f3b 100644 (file)
@@ -31,7 +31,6 @@
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
-#![deny(warnings)]
 #![feature(asm)]
 #![feature(fnbox)]
 #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
index 5347c781218ce4b947f10a3d2e11529a686abf04..2b3c19c067ed4258de5a3da04fc6ae1b754a2168 100644 (file)
@@ -10,7 +10,6 @@
 
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
-#![deny(warnings)]
 
 #![feature(cfg_target_vendor)]
 #![feature(link_cfg)]
index 9fa33f911a1686f8118a3f31bbf6dde38578d653..a888838ce432cb1fa44e8f738406961ede720674 100644 (file)
@@ -13,6 +13,7 @@
 
 // Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread
 // for the rationale.
+#[allow(unused_attributes)]
 #[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")]
 // We only build for msvc and gnu now, but we use a exhaustive condition here
 // so we can expect either the stack size to be set or the build fails.
index 9c56a316b341cba7b9c3b5d45ebdb042213f7092..415ee6eb7eab8754834de460088b0ac260935313 100644 (file)
 // CHECK: @VAR1 = constant <{ [4 x i8] }> <{ [4 x i8] c"\01\00\00\00" }>, section ".test_one"
 #[no_mangle]
 #[link_section = ".test_one"]
+#[cfg(target_endian = "little")]
 pub static VAR1: u32 = 1;
 
+#[no_mangle]
+#[link_section = ".test_one"]
+#[cfg(target_endian = "big")]
+pub static VAR1: u32 = 0x01000000;
+
 pub enum E {
     A(u32),
     B(f32)
index 8a09ab3fd06c8e1ffa7f5dce75db2ecf07dbf57e..fbdd013024db56d5663960ffada8f7ca5e4d50e7 100644 (file)
@@ -27,7 +27,7 @@ fn indirect_write_to_imm_box() {
     let y: Box<_> = box &mut x;
     let p = &y;
     ***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference
-              //[mir]~^ ERROR cannot assign to immutable item `***p`
+              //[mir]~^ ERROR cannot assign to data in a `&` reference
     drop(p);
 }
 
diff --git a/src/test/run-pass/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/src/test/run-pass/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
new file mode 100644 (file)
index 0000000..51b2b5a
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+#![deny(non_shorthand_field_patterns)]
+
+pub struct Value<A> { pub value: A }
+
+#[macro_export]
+macro_rules! pat {
+    ($a:pat) => {
+        Value { value: $a }
+    };
+}
+
+fn main() {
+    let pat!(value) = Value { value: () };
+}
index 2f50e63153ea4bf8722b3bec2458aaa40d6168be..0bb18d8729a97d048bdce4fae8fba6cebb851f45 100644 (file)
@@ -42,6 +42,12 @@ enum ReorderedEnum {
     B(u8, u16, u8),
 }
 
+enum NicheFilledEnumWithInhabitedVariant {
+    A(&'static ()),
+    B(&'static (), !),
+    C,
+}
+
 pub fn main() {
     assert_eq!(size_of::<u8>(), 1 as usize);
     assert_eq!(size_of::<u32>(), 4 as usize);
@@ -67,4 +73,5 @@ pub fn main() {
     assert_eq!(size_of::<e3>(), 4 as usize);
     assert_eq!(size_of::<ReorderedStruct>(), 4);
     assert_eq!(size_of::<ReorderedEnum>(), 6);
+    assert_eq!(size_of::<NicheFilledEnumWithInhabitedVariant>(), size_of::<&'static ()>());
 }
diff --git a/src/test/rustdoc/all.rs b/src/test/rustdoc/all.rs
new file mode 100644 (file)
index 0000000..ec39131
--- /dev/null
@@ -0,0 +1,30 @@
+// 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.
+
+#![crate_name = "foo"]
+
+// @has foo/all.html '//a[@href="struct.Struct.html"]' 'Struct'
+// @has foo/all.html '//a[@href="enum.Enum.html"]' 'Enum'
+// @has foo/all.html '//a[@href="union.Union.html"]' 'Union'
+// @has foo/all.html '//a[@href="constant.CONST.html"]' 'CONST'
+// @has foo/all.html '//a[@href="static.STATIC.html"]' 'STATIC'
+// @has foo/all.html '//a[@href="fn.function.html"]' 'function'
+
+pub struct Struct;
+pub enum Enum {
+    X,
+    Y,
+}
+pub union Union {
+    x: u32,
+}
+pub const CONST: u32 = 0;
+pub static STATIC: &str = "baguette";
+pub fn function() {}
index 49084e01a15dbb42d7583ac8e2ad6c21cdd6ebae..055a169deda74da9b934a2fd8a7a030a2f49b6a6 100644 (file)
@@ -12,6 +12,7 @@
 // ignore-emscripten
 // ignore-powerpc
 // ignore-sparc
+// ignore-mips
 
 #![feature(asm)]
 
index 4ec758b97f2d82fe9a9a014dfe2c8f41527375d8..d9fd4b26c390015f2e284ac87a94f140743c70e7 100644 (file)
@@ -1,5 +1,5 @@
 error[E0384]: cannot assign twice to immutable variable `x`
-  --> $DIR/asm-out-assign-imm.rs:29:9
+  --> $DIR/asm-out-assign-imm.rs:30:9
    |
 LL |     x = 1;
    |     ----- first assignment to `x`
index 010cb77edc3f10e87c2ad921edde77d4e93042f2..74feb0105ccf1ced50accc11a62f8a6c53180a92 100644 (file)
@@ -11,6 +11,9 @@
 #![feature(rustc_attrs)]
 
 #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
 trait Foo<S, T, U> {
     fn s(S) -> S;
     fn t(T) -> T;
index 6da1e2fd8edd8f810a1b858fc32c970536286fcd..45753c3bb90c2977a6b88e17e9fe1d1c43b8d3b2 100644 (file)
@@ -4,5 +4,23 @@ error: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
 LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
+  --> $DIR/lower_trait.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
+  --> $DIR/lower_trait.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(U: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
+  --> $DIR/lower_trait.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/chalkify/lower_trait_higher_rank.rs b/src/test/ui/chalkify/lower_trait_higher_rank.rs
new file mode 100644 (file)
index 0000000..e5eaf45
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+#![feature(rustc_attrs)]
+
+#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<F>) :-
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+trait Foo<F> where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8
+{
+    fn s(F) -> F;
+}
+
+fn main() {
+    println!("hello");
+}
diff --git a/src/test/ui/chalkify/lower_trait_higher_rank.stderr b/src/test/ui/chalkify/lower_trait_higher_rank.stderr
new file mode 100644 (file)
index 0000000..9aed0c0
--- /dev/null
@@ -0,0 +1,26 @@
+error: Implemented(Self: Foo<F>) :- FromEnv(Self: Foo<F>).
+  --> $DIR/lower_trait_higher_rank.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<F>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(F: std::marker::Sized) :- FromEnv(Self: Foo<F>).
+  --> $DIR/lower_trait_higher_rank.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<F>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(F: std::ops::Fn<(&'a (u8, u16),)>) :- FromEnv(Self: Foo<F>).
+  --> $DIR/lower_trait_higher_rank.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<F>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(<F as std::ops::FnOnce<(&'a (u8, u16),)>>::Output == &'a u8) :- FromEnv(Self: Foo<F>).
+  --> $DIR/lower_trait_higher_rank.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<F>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/chalkify/lower_trait_where_clause.rs b/src/test/ui/chalkify/lower_trait_where_clause.rs
new file mode 100644 (file)
index 0000000..b2ce3ca
--- /dev/null
@@ -0,0 +1,31 @@
+// 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.
+
+#![feature(rustc_attrs)]
+
+use std::fmt::{Debug, Display};
+use std::borrow::Borrow;
+
+#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+                              //~| ERROR FromEnv
+                              //~| ERROR RegionOutlives
+                              //~| ERROR TypeOutlives
+trait Foo<'a, 'b, S, T, U> where S: Debug, T: Borrow<U>, U: ?Sized, 'a: 'b, U: 'b {
+    fn s(S) -> S;
+    fn t(T) -> T;
+    fn u(U) -> U;
+}
+
+fn main() {
+    println!("hello");
+}
diff --git a/src/test/ui/chalkify/lower_trait_where_clause.stderr b/src/test/ui/chalkify/lower_trait_where_clause.stderr
new file mode 100644 (file)
index 0000000..a9ecaec
--- /dev/null
@@ -0,0 +1,44 @@
+error: Implemented(Self: Foo<'a, 'b, S, T, U>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(S: std::fmt::Debug) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: FromEnv(T: std::borrow::Borrow<U>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: RegionOutlives('a : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: TypeOutlives(U : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+  --> $DIR/lower_trait_where_clause.rs:16:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<'a, 'b, S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs
new file mode 100644 (file)
index 0000000..4526517
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.
+
+fn gratitude() {
+    let for_you = false;
+    if not for_you {
+        //~^ ERROR unexpected `for_you` after identifier
+        println!("I couldn't");
+    }
+}
+
+fn qualification() {
+    let the_worst = true;
+    while not the_worst {
+        //~^ ERROR unexpected `the_worst` after identifier
+        println!("still pretty bad");
+    }
+}
+
+fn should_we() {
+    let not = true;
+    if not  // lack of braces is [sic]
+        println!("Then when?");
+    //~^ ERROR expected `{`, found `;
+    //~| ERROR unexpected `println` after identifier
+}
+
+fn sleepy() {
+    let resource = not 2;
+    //~^ ERROR unexpected `2` after identifier
+}
+
+fn main() {
+    let be_smothered_out_before = true;
+    let young_souls = not be_smothered_out_before;
+    //~^ ERROR unexpected `be_smothered_out_before` after identifier
+}
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
new file mode 100644 (file)
index 0000000..db34781
--- /dev/null
@@ -0,0 +1,50 @@
+error: unexpected `for_you` after identifier
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:13:12
+   |
+LL |     if not for_you {
+   |        ----^^^^^^^
+   |        |
+   |        help: use `!` to perform logical negation
+
+error: unexpected `the_worst` after identifier
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:21:15
+   |
+LL |     while not the_worst {
+   |           ----^^^^^^^^^
+   |           |
+   |           help: use `!` to perform logical negation
+
+error: unexpected `println` after identifier
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:30:9
+   |
+LL |     if not  // lack of braces is [sic]
+   |        ----- help: use `!` to perform logical negation
+LL |         println!("Then when?");
+   |         ^^^^^^^
+
+error: expected `{`, found `;`
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:30:31
+   |
+LL |     if not  // lack of braces is [sic]
+   |     -- this `if` statement has a condition, but no block
+LL |         println!("Then when?");
+   |                               ^
+
+error: unexpected `2` after identifier
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:36:24
+   |
+LL |     let resource = not 2;
+   |                    ----^
+   |                    |
+   |                    help: use `!` to perform logical negation
+
+error: unexpected `be_smothered_out_before` after identifier
+  --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:42:27
+   |
+LL |     let young_souls = not be_smothered_out_before;
+   |                       ----^^^^^^^^^^^^^^^^^^^^^^^
+   |                       |
+   |                       help: use `!` to perform logical negation
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs
new file mode 100644 (file)
index 0000000..64fc3df
--- /dev/null
@@ -0,0 +1,63 @@
+// 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.
+
+// Regression test for #16223: without NLL the `if let` construct together with
+// the nested box-structure of `Root` causes an unwanted collateral move.
+
+// The exact error prevented here is:
+//
+// error[E0382]: use of collaterally moved value: `(root.boxed.rhs as SomeVariant::B).0`
+//   --> src/main.rs:55:29
+//    |
+// 56 |         lhs: SomeVariant::A(a),
+//    |                             - value moved here
+// 57 |         rhs: SomeVariant::B(b),
+//    |                             ^ value used here after move
+//    |
+//    = note: move occurs because the value has type `A`, which does not implement the `Copy` trait
+
+// must-compile-successfully
+
+#![feature(nll)]
+#![feature(box_patterns)]
+
+struct Root {
+    boxed: Box<SetOfVariants>,
+}
+
+struct SetOfVariants {
+    lhs: SomeVariant,
+    rhs: SomeVariant,
+}
+
+enum SomeVariant {
+    A(A),
+    B(B),
+}
+
+struct A(String);
+struct B(String);
+
+fn main() {
+    let root = Root {
+        boxed: Box::new(SetOfVariants {
+            lhs: SomeVariant::A(A(String::from("This is A"))),
+            rhs: SomeVariant::B(B(String::from("This is B"))),
+        }),
+    };
+    if let box SetOfVariants {
+        lhs: SomeVariant::A(a),
+        rhs: SomeVariant::B(b),
+    } = root.boxed
+    {
+        println!("a = {}", a.0);
+        println!("b = {}", b.0);
+    }
+}
diff --git a/src/test/ui/nll/issue-47388.rs b/src/test/ui/nll/issue-47388.rs
new file mode 100644 (file)
index 0000000..39feea0
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+#![feature(nll)]
+struct FancyNum {
+    num: u8,
+}
+
+fn main() {
+    let mut fancy = FancyNum{ num: 5 };
+    let fancy_ref = &(&mut fancy);
+    fancy_ref.num = 6; //~ ERROR E0594
+    println!("{}", fancy_ref.num);
+}
diff --git a/src/test/ui/nll/issue-47388.stderr b/src/test/ui/nll/issue-47388.stderr
new file mode 100644 (file)
index 0000000..272cb65
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0594]: cannot assign to data in a `&` reference
+  --> $DIR/issue-47388.rs:18:5
+   |
+LL |     let fancy_ref = &(&mut fancy);
+   |                     ------------- help: consider changing this to be a mutable reference: `&mut`
+LL |     fancy_ref.num = 6; //~ ERROR E0594
+   |     ^^^^^^^^^^^^^^^^^ `fancy_ref` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
index 56acbed47210a5632cb9ed8eaf9b7c72a7d471ba..eb83ee724c785804d5f6332164ae28cdcbc57d39 100644 (file)
@@ -12,6 +12,9 @@
 // ignore-aarch64
 // ignore-wasm
 // ignore-emscripten
+// ignore-mips
+// ignore-powerpc
+// ignore-s390x
 
 #![feature(target_feature)]
 
index 8773f8504cb01e7983e84b20c26d438296522dfa..b5e650eaf9ac4373acd8cb2284fa1c5665ef261b 100644 (file)
@@ -1,35 +1,35 @@
 warning: #[target_feature = ".."] is deprecated and will eventually be removed, use #[target_feature(enable = "..")] instead
-  --> $DIR/target-feature-wrong.rs:18:1
+  --> $DIR/target-feature-wrong.rs:21:1
    |
 LL | #[target_feature = "+sse2"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the feature named `foo` is not valid for this target
-  --> $DIR/target-feature-wrong.rs:20:18
+  --> $DIR/target-feature-wrong.rs:23:18
    |
 LL | #[target_feature(enable = "foo")]
    |                  ^^^^^^^^^^^^^^
 
 error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:22:18
+  --> $DIR/target-feature-wrong.rs:25:18
    |
 LL | #[target_feature(bar)]
    |                  ^^^
 
 error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:24:18
+  --> $DIR/target-feature-wrong.rs:27:18
    |
 LL | #[target_feature(disable = "baz")]
    |                  ^^^^^^^^^^^^^^^
 
 error: #[target_feature(..)] can only be applied to `unsafe` function
-  --> $DIR/target-feature-wrong.rs:28:1
+  --> $DIR/target-feature-wrong.rs:31:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: attribute should be applied to a function
-  --> $DIR/target-feature-wrong.rs:32:1
+  --> $DIR/target-feature-wrong.rs:35:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL | mod another {}
    | -------------- not a function
 
 error: cannot use #[inline(always)] with #[target_feature]
-  --> $DIR/target-feature-wrong.rs:36:1
+  --> $DIR/target-feature-wrong.rs:39:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
index e726dea84f103d65d97e0f8503abde4a0111e1ab..7aca765cead8c48f8794901cf33813ba199e9fca 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 #![feature(link_args)]
+
+#[allow(unused_attributes)]
 // Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread
 // for the rationale.
 #[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")]
index 06eb055f68e060e179014984c78e68bcaa011bbf..fa2274366401445737932941c876e0df8b26232d 100644 (file)
@@ -13,8 +13,6 @@
 //! This library contains the tidy lints and exposes it
 //! to be used by tools.
 
-#![deny(warnings)]
-
 extern crate serde;
 extern crate serde_json;
 #[macro_use]