diff --git a/Cargo.lock b/Cargo.lock index d22a91073394a..031c998a299ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -614,7 +614,7 @@ dependencies = [ [[package]] name = "datafrog" -version = "0.1.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -728,7 +728,7 @@ name = "error-chain" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -736,7 +736,7 @@ name = "error-chain" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -751,7 +751,7 @@ name = "failure" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1625,10 +1625,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "polonius-engine" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "datafrog 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2060,7 +2060,7 @@ name = "rustc" version = "0.0.0" dependencies = [ "arena 0.0.0", - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2071,7 +2071,7 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_apfloat 0.0.0", @@ -2518,7 +2518,7 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_apfloat 0.0.0", "rustc_data_structures 0.0.0", @@ -3380,7 +3380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782" "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a" "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" @@ -3419,7 +3419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" "checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16" "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870" -"checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142" +"checksum datafrog 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71a3eacc779bb35090718501c2de27bb679dee18f6c28e6589590e4ed8b9fa08" "checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c" "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" @@ -3529,7 +3529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201" +"checksum polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9274a1db7bffb87f7e810ef480a75b67eed0f1a3838f80c652e881f4b4970fd" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" diff --git a/README.md b/README.md index 37442661bcbc1..dc013a1ad2be6 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ standard library, and documentation. Read ["Installation"] from [The Book]. -["Installation"]: https://doc.rust-lang.org/book/second-edition/ch01-01-installation.html +["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html [The Book]: https://doc.rust-lang.org/book/index.html ## Building from Source diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 3e91c2b3e86c8..0f7b6c22e1cc5 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "bootstrap" version = "0.0.0" +edition = "2018" [lib] name = "bootstrap" diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 32f3e573d6845..26760a6edc907 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -21,20 +21,20 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use cache::{Cache, Interned, INTERNER}; -use check; -use compile; -use dist; -use doc; -use flags::Subcommand; -use install; -use native; -use test; -use tool; -use util::{add_lib_path, exe, libdir}; -use {Build, DocTests, Mode, GitRepo}; - -pub use Compiler; +use crate::cache::{Cache, Interned, INTERNER}; +use crate::check; +use crate::compile; +use crate::dist; +use crate::doc; +use crate::flags::Subcommand; +use crate::install; +use crate::native; +use crate::test; +use crate::tool; +use crate::util::{add_lib_path, exe, libdir}; +use crate::{Build, DocTests, Mode, GitRepo}; + +pub use crate::Compiler; use petgraph::graph::NodeIndex; use petgraph::Graph; @@ -1251,7 +1251,7 @@ impl<'a> Builder<'a> { #[cfg(test)] mod __test { use super::*; - use config::Config; + use crate::config::Config; use std::thread; fn configure(host: &[&str], target: &[&str]) -> Config { diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index 0b561a3523f2b..165cffa4587d3 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -23,7 +23,7 @@ use std::path::{Path, PathBuf}; use std::sync::Mutex; use std::cmp::{PartialOrd, Ord, Ordering}; -use builder::Step; +use crate::builder::Step; pub struct Interned(usize, PhantomData<*const T>); diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index d5da0cabec84a..3d2b3a2c9de49 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -39,9 +39,9 @@ use std::process::Command; use build_helper::output; use cc; -use {Build, GitRepo}; -use config::Target; -use cache::Interned; +use crate::{Build, GitRepo}; +use crate::config::Target; +use crate::cache::Interned; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, // so use some simplified logic here. First we respect the environment variable `AR`, then diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 878b6ed73a312..8756ec944c257 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -20,8 +20,8 @@ use std::process::Command; use build_helper::output; -use Build; -use config::Config; +use crate::Build; +use crate::config::Config; // The version number pub const CFG_RELEASE_NUM: &str = "1.33.0"; diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 0c6dbb06bb882..84e7c40e4559e 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -10,11 +10,12 @@ //! Implementation of compiling the compiler and standard library, in "check" mode. -use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; -use builder::{RunConfig, Builder, ShouldRun, Step}; -use tool::{prepare_tool_cargo, SourceType}; -use {Compiler, Mode}; -use cache::{INTERNER, Interned}; +use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, + add_to_sysroot}; +use crate::builder::{RunConfig, Builder, ShouldRun, Step}; +use crate::tool::{prepare_tool_cargo, SourceType}; +use crate::{Compiler, Mode}; +use crate::cache::{INTERNER, Interned}; use std::path::PathBuf; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 87f194fb7d2f8..dc42159d068b1 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -19,7 +19,7 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::Path; -use Build; +use crate::Build; pub fn clean(build: &Build, all: bool) { rm_rf("tmp".as_ref()); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c84abe42a6372..db5d8645e3323 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -29,12 +29,12 @@ use build_helper::{output, mtime, up_to_date}; use filetime::FileTime; use serde_json; -use util::{exe, libdir, is_dylib}; -use {Compiler, Mode, GitRepo}; -use native; +use crate::util::{exe, libdir, is_dylib}; +use crate::{Compiler, Mode, GitRepo}; +use crate::native; -use cache::{INTERNER, Interned}; -use builder::{Step, RunConfig, ShouldRun, Builder}; +use crate::cache::{INTERNER, Interned}; +use crate::builder::{Step, RunConfig, ShouldRun, Builder}; #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Std { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 1dafbe148afda..2ae9da9c085d4 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -22,9 +22,9 @@ use std::cmp; use num_cpus; use toml; -use cache::{INTERNER, Interned}; -use flags::Flags; -pub use flags::Subcommand; +use crate::cache::{INTERNER, Interned}; +use crate::flags::Flags; +pub use crate::flags::Subcommand; /// Global configuration for the entire build and/or bootstrap. /// diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index f03eefb7a129b..927f9bf8ddbca 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -26,13 +26,13 @@ use std::process::{Command, Stdio}; use build_helper::output; -use {Compiler, Mode, LLVM_TOOLS}; -use channel; -use util::{libdir, is_dylib, exe}; -use builder::{Builder, RunConfig, ShouldRun, Step}; -use compile; -use tool::{self, Tool}; -use cache::{INTERNER, Interned}; +use crate::{Compiler, Mode, LLVM_TOOLS}; +use crate::channel; +use crate::util::{libdir, is_dylib, exe}; +use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::compile; +use crate::tool::{self, Tool}; +use crate::cache::{INTERNER, Interned}; use time; pub fn pkgname(builder: &Builder, component: &str) -> String { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 2d0625b26dbe3..217328adfbf66 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -22,15 +22,15 @@ use std::fs; use std::io; use std::path::{PathBuf, Path}; -use Mode; +use crate::Mode; use build_helper::up_to_date; -use util::symlink_dir; -use builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; -use tool::{self, prepare_tool_cargo, Tool, SourceType}; -use compile; -use cache::{INTERNER, Interned}; -use config::Config; +use crate::util::symlink_dir; +use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; +use crate::tool::{self, prepare_tool_cargo, Tool, SourceType}; +use crate::compile; +use crate::cache::{INTERNER, Interned}; +use crate::config::Config; macro_rules! book { ($($name:ident, $path:expr, $book_name:expr;)+) => { diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index c49da8fc73489..14e2f69432dac 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -19,12 +19,12 @@ use std::process; use getopts::Options; -use builder::Builder; -use config::Config; -use metadata; -use {Build, DocTests}; +use crate::builder::Builder; +use crate::config::Config; +use crate::metadata; +use crate::{Build, DocTests}; -use cache::{Interned, INTERNER}; +use crate::cache::{Interned, INTERNER}; /// Deserialized version of all flags for this compile. pub struct Flags { diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index cb28698aa3d6d..aebcfb4519543 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -18,11 +18,11 @@ use std::fs; use std::path::{Path, PathBuf, Component}; use std::process::Command; -use dist::{self, pkgname, sanitize_sh, tmpdir}; +use crate::dist::{self, pkgname, sanitize_sh, tmpdir}; -use builder::{Builder, RunConfig, ShouldRun, Step}; -use cache::Interned; -use config::Config; +use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::cache::Interned; +use crate::config::Config; pub fn install_docs(builder: &Builder, stage: u32, host: Interned) { install_sh(builder, "docs", "rust-docs", stage, Some(host)); diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index f7b1c50f0fd67..a9da2c491da53 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -42,7 +42,7 @@ use std::env; use std::io; use std::mem; -use Build; +use crate::Build; type HANDLE = *mut u8; type BOOL = i32; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index c8792918db2e2..c5b8f19eee6fb 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -159,7 +159,7 @@ use std::os::windows::fs::symlink_file; use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime}; use filetime::FileTime; -use util::{exe, libdir, OutputFolder, CiEnv}; +use crate::util::{exe, libdir, OutputFolder, CiEnv}; mod cc_detect; mod channel; @@ -188,7 +188,7 @@ mod job; mod job { use libc; - pub unsafe fn setup(build: &mut ::Build) { + pub unsafe fn setup(build: &mut crate::Build) { if build.config.low_priority { libc::setpriority(libc::PRIO_PGRP as _, 0, 10); } @@ -197,14 +197,14 @@ mod job { #[cfg(any(target_os = "haiku", not(any(unix, windows))))] mod job { - pub unsafe fn setup(_build: &mut ::Build) { + pub unsafe fn setup(_build: &mut crate::Build) { } } -pub use config::Config; -use flags::Subcommand; -use cache::{Interned, INTERNER}; -use toolstate::ToolState; +pub use crate::config::Config; +use crate::flags::Subcommand; +use crate::cache::{Interned, INTERNER}; +use crate::toolstate::ToolState; const LLVM_TOOLS: &[&str] = &[ "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index fa0b1983510b9..bb503e8b8d3d1 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -16,8 +16,8 @@ use std::collections::HashSet; use build_helper::output; use serde_json; -use {Build, Crate}; -use cache::INTERNER; +use crate::{Build, Crate}; +use crate::cache::INTERNER; #[derive(Deserialize)] struct Output { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 8ff175b018756..2da800f19c07b 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -28,11 +28,11 @@ use build_helper::output; use cmake; use cc; -use util::{self, exe}; +use crate::util::{self, exe}; use build_helper::up_to_date; -use builder::{Builder, RunConfig, ShouldRun, Step}; -use cache::Interned; -use GitRepo; +use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::cache::Interned; +use crate::GitRepo; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Llvm { diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 7a9e6d4fd387b..f585495b0aa94 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -27,7 +27,7 @@ use std::process::Command; use build_helper::output; -use Build; +use crate::Build; struct Finder { cache: HashMap>, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index dc061fe5099a5..174f2d537cda5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -23,17 +23,17 @@ use std::process::Command; use build_helper::{self, output}; -use builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; -use cache::{Interned, INTERNER}; -use compile; -use dist; -use flags::Subcommand; -use native; -use tool::{self, Tool, SourceType}; -use toolstate::ToolState; -use util::{self, dylib_path, dylib_path_var}; -use Crate as CargoCrate; -use {DocTests, Mode, GitRepo}; +use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; +use crate::cache::{Interned, INTERNER}; +use crate::compile; +use crate::dist; +use crate::flags::Subcommand; +use crate::native; +use crate::tool::{self, Tool, SourceType}; +use crate::toolstate::ToolState; +use crate::util::{self, dylib_path, dylib_path_var}; +use crate::Crate as CargoCrate; +use crate::{DocTests, Mode, GitRepo}; const ADB_TEST_DIR: &str = "/data/tmp/work"; @@ -577,7 +577,7 @@ impl Step for RustdocJS { if let Some(ref nodejs) = builder.config.nodejs { let mut command = Command::new(nodejs); command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); - builder.ensure(::doc::Std { + builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage, }); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 1bd4403a66ffa..4335359e11589 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -15,16 +15,16 @@ use std::path::PathBuf; use std::process::{Command, exit}; use std::collections::HashSet; -use Mode; -use Compiler; -use builder::{Step, RunConfig, ShouldRun, Builder}; -use util::{exe, add_lib_path}; -use compile; -use native; -use channel::GitInfo; -use channel; -use cache::Interned; -use toolstate::ToolState; +use crate::Mode; +use crate::Compiler; +use crate::builder::{Step, RunConfig, ShouldRun, Builder}; +use crate::util::{exe, add_lib_path}; +use crate::compile; +use crate::native; +use crate::channel::GitInfo; +use crate::channel; +use crate::cache::Interned; +use crate::toolstate::ToolState; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum SourceType { diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index be24ae0ce6648..b18e38e471eff 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -21,8 +21,8 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{SystemTime, Instant}; -use config::Config; -use builder::Builder; +use crate::config::Config; +use crate::builder::Builder; /// Returns the `name` as the filename of a static library for `target`. pub fn staticlib(name: &str, target: &str) -> String { diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index c7e6af28f9d4f..4f8a3c0240e1a 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -52,8 +52,8 @@ RUN env \ CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \ bash musl.sh arm && \ env \ - CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \ - CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \ + CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \ + CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm -mfpu=vfp" \ bash musl.sh armhf && \ env \ CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \ diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md index 8620346e5b748..2e94ebe345adb 100644 --- a/src/doc/rustc/src/targets/built-in.md +++ b/src/doc/rustc/src/targets/built-in.md @@ -6,5 +6,5 @@ the team is supporting directly. To see the list of built-in targets, you can run `rustc --print target-list`, or look at [the API -docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules). +docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/index.html#modules). Each module there defines a builder for a particular target. \ No newline at end of file diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md index 07e3a79471f5b..3d63d072befe0 100644 --- a/src/doc/rustc/src/targets/index.md +++ b/src/doc/rustc/src/targets/index.md @@ -4,7 +4,7 @@ architecture. The list of *targets* are the possible architectures that you can build for. To see all the options that you can set with a target, see the docs -[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html). +[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html). To compile to a particular target, use the `--target` flag: diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md index 1165ab93a1469..edc039f896b2c 100644 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ b/src/doc/unstable-book/src/language-features/unsized-locals.md @@ -8,7 +8,7 @@ The tracking issue for this feature is: [#48055] This implements [RFC1909]. When turned on, you can have unsized arguments and locals: -[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-coercions.md +[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md ```rust #![feature(unsized_locals)] diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 2ef84dbade0fb..ba46fafaf169f 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -627,7 +627,9 @@ impl LinkedList { self.pop_front_node().map(Node::into_element) } - /// Appends an element to the back of a list + /// Appends an element to the back of a list. + /// + /// This operation should compute in O(1) time. /// /// # Examples /// @@ -647,6 +649,8 @@ impl LinkedList { /// Removes the last element from a list and returns it, or `None` if /// it is empty. /// + /// This operation should compute in O(1) time. + /// /// # Examples /// /// ``` diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index e329b45a6175d..509195cd047d4 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -79,6 +79,11 @@ fn test_reserve() { assert!(v.capacity() >= 33) } +#[test] +fn test_zst_capacity() { + assert_eq!(Vec::<()>::new().capacity(), usize::max_value()); +} + #[test] fn test_extend() { let mut v = Vec::new(); diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 0c870f9e404a2..5dee1d6dd3a39 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -33,6 +33,7 @@ use task::{Poll, LocalWaker}; /// /// When using a future, you generally won't call `poll` directly, but instead /// `await!` the value. +#[must_use] pub trait Future { /// The result of the `Future`. type Output; diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 92a4aed4e27e5..c0b83a6868b38 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -98,6 +98,7 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} message="`{Self}` is not an iterator" )] #[doc(spotlight)] +#[must_use] pub trait Iterator { /// The type of the elements being iterated over. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs index d1be724c3264e..3b356b9a1e7b4 100644 --- a/src/libcore/ops/function.rs +++ b/src/libcore/ops/function.rs @@ -72,6 +72,7 @@ label="expected an `Fn<{Args}>` closure, found `{Self}`", )] #[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use] pub trait Fn : FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -150,6 +151,7 @@ pub trait Fn : FnMut { label="expected an `FnMut<{Args}>` closure, found `{Self}`", )] #[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use] pub trait FnMut : FnOnce { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -228,6 +230,7 @@ pub trait FnMut : FnOnce { label="expected an `FnOnce<{Args}>` closure, found `{Self}`", )] #[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use] pub trait FnOnce { /// The returned type after the call operator is used. #[stable(feature = "fn_once_output", since = "1.12.0")] diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f61e582f7641b..79ca600b4a57f 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2544,7 +2544,7 @@ pub fn eq(a: *const T, b: *const T) -> bool { /// assert_eq!(actual, expected); /// ``` #[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")] -pub fn hash(hashee: *const T, into: &mut S) { +pub fn hash(hashee: *const T, into: &mut S) { use hash::Hash; hashee.hash(into); } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 060983a702f0b..d2683e31eefb8 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1072,6 +1072,15 @@ impl AtomicPtr { #[cfg(target_has_atomic = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] impl From for AtomicBool { + /// Converts a `bool` into an `AtomicBool`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicBool; + /// let atomic_bool = AtomicBool::from(true); + /// assert_eq!(format!("{:?}", atomic_bool), "true") + /// ``` #[inline] fn from(b: bool) -> Self { Self::new(b) } } @@ -1126,8 +1135,12 @@ macro_rules! atomic_int { #[$stable_from] impl From<$int_type> for $atomic_type { - #[inline] - fn from(v: $int_type) -> Self { Self::new(v) } + doc_comment! { + concat!( +"Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`."), + #[inline] + fn from(v: $int_type) -> Self { Self::new(v) } + } } #[$stable_debug] diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index a572b6bf919e1..78f58bbe99a7f 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -17,7 +17,7 @@ jobserver = "0.1" lazy_static = "1.0.0" scoped-tls = { version = "0.1.1", features = ["nightly"] } log = { version = "0.4", features = ["release_max_level_info", "std"] } -polonius-engine = "0.5.0" +polonius-engine = "0.6.1" rustc-rayon = "0.1.1" rustc-rayon-core = "0.1.1" rustc_apfloat = { path = "../librustc_apfloat" } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 7d997a0154600..d213a5c561871 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1095,7 +1095,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let sp = hir.span(id); // `sp` only covers `T`, change it so that it covers // `T:` when appropriate - let sp = if has_bounds { + let is_impl_trait = bound_kind.to_string().starts_with("impl "); + let sp = if has_bounds && !is_impl_trait { sp.to(self.tcx .sess .source_map() @@ -1103,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { sp }; - (sp, has_bounds) + (sp, has_bounds, is_impl_trait) }) } else { None @@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn binding_suggestion<'tcx, S: fmt::Display>( err: &mut DiagnosticBuilder<'tcx>, - type_param_span: Option<(Span, bool)>, + type_param_span: Option<(Span, bool, bool)>, bound_kind: GenericKind<'tcx>, sub: S, ) { - let consider = &format!( - "consider adding an explicit lifetime bound `{}: {}`...", - bound_kind, sub + let consider = format!( + "consider adding an explicit lifetime bound {}", + if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) { + format!(" `{}` to `{}`...", sub, bound_kind) + } else { + format!("`{}: {}`...", bound_kind, sub) + }, ); - if let Some((sp, has_lifetimes)) = type_param_span { - let tail = if has_lifetimes { " + " } else { "" }; - let suggestion = format!("{}: {}{}", bound_kind, sub, tail); + if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span { + let suggestion = if is_impl_trait { + format!("{} + {}", bound_kind, sub) + } else { + let tail = if has_lifetimes { " + " } else { "" }; + format!("{}: {}{}", bound_kind, sub, tail) + }; err.span_suggestion_short_with_applicability( sp, - consider, + &consider, suggestion, Applicability::MaybeIncorrect, // Issue #41966 ); } else { - err.help(consider); + err.help(&consider); } } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index b7759a8c92b07..82145f61b26b1 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -365,6 +365,13 @@ pub mod parser { } } +declare_lint! { + pub DEPRECATED_IN_FUTURE, + Allow, + "detects use of items that will be deprecated in a future version", + report_in_external_macro: true +} + /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -427,6 +434,7 @@ impl LintPass for HardwiredLints { MACRO_USE_EXTERN_CRATE, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, parser::QUESTION_MARK_MACRO_SEP, + DEPRECATED_IN_FUTURE, ) } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index e576951417f93..31a75bd106e2c 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1657,11 +1657,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn report_dead_assign(&self, hir_id: HirId, sp: Span, var: Variable, is_argument: bool) { if let Some(name) = self.should_warn(var) { if is_argument { - self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, - &format!("value passed to `{}` is never read", name)); + self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, + &format!("value passed to `{}` is never read", name)) + .help("maybe it is overwritten before being read?") + .emit(); } else { - self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, - &format!("value assigned to `{}` is never read", name)); + self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, + &format!("value assigned to `{}` is never read", name)) + .help("maybe it is overwritten before being read?") + .emit(); } } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ab379c910f776..61341cbc30ce4 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -13,7 +13,7 @@ pub use self::StabilityLevel::*; -use lint; +use lint::{self, Lint}; use hir::{self, Item, Generics, StructField, Variant, HirId}; use hir::def::Def; use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; @@ -562,18 +562,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return EvalResult::Allow; } - let lint_deprecated = |def_id: DefId, id: NodeId, note: Option| { - let path = self.item_path_str(def_id); - + let lint_deprecated = |def_id: DefId, + id: NodeId, + note: Option, + message: &str, + lint: &'static Lint| { let msg = if let Some(note) = note { - format!("use of deprecated item '{}': {}", path, note) + format!("{}: {}", message, note) } else { - format!("use of deprecated item '{}'", path) + format!("{}", message) }; - self.lint_node(lint::builtin::DEPRECATED, id, span, &msg); + self.lint_node(lint, id, span, &msg); if id == ast::DUMMY_NODE_ID { - span_bug!(span, "emitted a deprecated lint with dummy node id: {:?}", def_id); + span_bug!(span, "emitted a {} lint with dummy node id: {:?}", lint.name, def_id); } }; @@ -584,17 +586,39 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // version, then we should display no warning message. let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { let since = sym.as_str(); - !deprecation_in_effect(&since) + if !deprecation_in_effect(&since) { + Some(since) + } else { + None + } } else { - false + None }; let parent_def_id = self.hir().local_def_id(self.hir().get_parent(id)); - let skip = deprecated_in_future_version || - self.lookup_deprecation_entry(parent_def_id) + let skip = self.lookup_deprecation_entry(parent_def_id) .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); - if !skip { - lint_deprecated(def_id, id, depr_entry.attr.note); + + if let Some(since) = deprecated_in_future_version { + let path = self.item_path_str(def_id); + let message = format!("use of item '{}' \ + that will be deprecated in future version {}", + path, + since); + + lint_deprecated(def_id, + id, + depr_entry.attr.note, + &message, + lint::builtin::DEPRECATED_IN_FUTURE); + } else if !skip { + let path = self.item_path_str(def_id); + let message = format!("use of deprecated item '{}'", path); + lint_deprecated(def_id, + id, + depr_entry.attr.note, + &message, + lint::builtin::DEPRECATED); } }; } @@ -614,8 +638,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, since }), ..}) = stability { if let Some(id) = id { + let path = self.item_path_str(def_id); if deprecation_in_effect(&since.as_str()) { - lint_deprecated(def_id, id, Some(reason)); + let message = format!("use of deprecated item '{}'", path); + lint_deprecated(def_id, + id, + Some(reason), + &message, + lint::builtin::DEPRECATED); + } else { + let message = format!("use of item '{}' \ + that will be deprecated in future version {}", + path, + since); + lint_deprecated(def_id, + id, + Some(reason), + &message, + lint::builtin::DEPRECATED_IN_FUTURE); } } } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 289f693df244d..8b16aafd314d7 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -183,50 +183,14 @@ pub struct EvalError<'tcx> { impl<'tcx> EvalError<'tcx> { pub fn print_backtrace(&mut self) { if let Some(ref mut backtrace) = self.backtrace { - eprintln!("{}", print_backtrace(&mut *backtrace)); + print_backtrace(&mut *backtrace); } } } -fn print_backtrace(backtrace: &mut Backtrace) -> String { - use std::fmt::Write; - +fn print_backtrace(backtrace: &mut Backtrace) { backtrace.resolve(); - - let mut trace_text = "\n\nAn error occurred in miri:\n".to_string(); - write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap(); - 'frames: for (i, frame) in backtrace.frames().iter().enumerate() { - if frame.symbols().is_empty() { - write!(trace_text, " {}: no symbols\n", i).unwrap(); - } - let mut first = true; - for symbol in frame.symbols() { - if first { - write!(trace_text, " {}: ", i).unwrap(); - first = false; - } else { - let len = i.to_string().len(); - write!(trace_text, " {} ", " ".repeat(len)).unwrap(); - } - if let Some(name) = symbol.name() { - write!(trace_text, "{}\n", name).unwrap(); - } else { - write!(trace_text, "\n").unwrap(); - } - write!(trace_text, " at ").unwrap(); - if let Some(file_path) = symbol.filename() { - write!(trace_text, "{}", file_path.display()).unwrap(); - } else { - write!(trace_text, "").unwrap(); - } - if let Some(line) = symbol.lineno() { - write!(trace_text, ":{}\n", line).unwrap(); - } else { - write!(trace_text, "\n").unwrap(); - } - } - } - trace_text + eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace); } impl<'tcx> From> for EvalError<'tcx> { @@ -238,7 +202,7 @@ impl<'tcx> From> for EvalError<'tcx> { if val == "immediate" { // Print it now - eprintln!("{}", print_backtrace(&mut backtrace)); + print_backtrace(&mut backtrace); None } else { Some(Box::new(backtrace)) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index b1e44ea761c86..66364ff88b38d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -376,7 +376,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_removed("resolve_trait_on_defaulted_unit", "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); store.register_removed("private_no_mangle_fns", - "no longer an warning, #[no_mangle] functions always exported"); + "no longer a warning, #[no_mangle] functions always exported"); store.register_removed("private_no_mangle_statics", - "no longer an warning, #[no_mangle] statics always exported"); + "no longer a warning, #[no_mangle] statics always exported"); } diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 5044e351962ed..0f8e4104c33c6 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -15,7 +15,7 @@ either = "1.5.0" graphviz = { path = "../libgraphviz" } log = "0.4" log_settings = "0.1.1" -polonius-engine = "0.5.0" +polonius-engine = "0.6.1" rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 8af23a8813a9e..42d20e675bad9 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> { /// Visits the whole MIR and generates invalidates() facts /// Most of the code implementing this was stolen from borrow_check/mod.rs impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> { - fn visit_statement(&mut self, - block: BasicBlock, - statement: &Statement<'tcx>, - location: Location) { + fn visit_statement( + &mut self, + block: BasicBlock, + statement: &Statement<'tcx>, + location: Location, + ) { + self.check_activations(location); + match statement.kind { StatementKind::Assign(ref lhs, ref rhs) => { self.consume_rvalue( @@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> { terminator: &Terminator<'tcx>, location: Location ) { + self.check_activations(location); + match terminator.kind { TerminatorKind::SwitchInt { ref discr, @@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> { let lidx = self.location_table.start_index(l); self.all_facts.invalidates.push((lidx, b)); } + + fn check_activations( + &mut self, + location: Location, + ) { + if !self.tcx.two_phase_borrows() { + return; + } + + // Two-phase borrow support: For each activation that is newly + // generated at this statement, check if it interferes with + // another borrow. + for &borrow_index in self.borrow_set.activations_at_location(location) { + let borrow = &self.borrow_set[borrow_index]; + + // only mutable borrows should be 2-phase + assert!(match borrow.kind { + BorrowKind::Shared | BorrowKind::Shallow => false, + BorrowKind::Unique | BorrowKind::Mut { .. } => true, + }); + + self.access_place( + ContextKind::Activation.new(location), + &borrow.borrowed_place, + ( + Deep, + Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index), + ), + LocalMutationIsAllowed::No, + ); + + // We do not need to call `check_if_path_or_subpath_is_moved` + // again, as we already called it when we made the + // initial reservation. + } + } } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 42ead92783d7a..a5d2edbc5d439 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -41,7 +41,6 @@ pub mod ast_validation; pub mod rvalue_promotion; pub mod hir_stats; pub mod loops; -mod mir_stats; __build_diagnostic_array! { librustc_passes, DIAGNOSTICS } diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs deleted file mode 100644 index fb37f03a1cc41..0000000000000 --- a/src/librustc_passes/mir_stats.rs +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// The visitors in this module collect sizes and counts of the most important -// pieces of MIR. The resulting numbers are good approximations but not -// completely accurate (some things might be counted twice, others missed). - -use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData}; -use rustc::mir::{Constant, Location, Local, LocalDecl}; -use rustc::mir::{Place, PlaceElem, PlaceProjection}; -use rustc::mir::{Mir, Operand, ProjectionElem}; -use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind}; -use rustc::mir::{Terminator, TerminatorKind, SourceScope, SourceScopeData}; -use rustc::mir::interpret::EvalErrorKind; -use rustc::mir::visit as mir_visit; -use rustc::ty::{self, ClosureSubsts, TyCtxt}; -use rustc::util::nodemap::{FxHashMap}; - -struct NodeData { - count: usize, - size: usize, -} - -struct StatCollector<'a, 'tcx: 'a> { - _tcx: TyCtxt<'a, 'tcx, 'tcx>, - data: FxHashMap<&'static str, NodeData>, -} - -impl<'a, 'tcx> StatCollector<'a, 'tcx> { - - fn record_with_size(&mut self, label: &'static str, node_size: usize) { - let entry = self.data.entry(label).or_insert(NodeData { - count: 0, - size: 0, - }); - - entry.count += 1; - entry.size = node_size; - } - - fn record(&mut self, label: &'static str, node: &T) { - self.record_with_size(label, ::std::mem::size_of_val(node)); - } -} - -impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { - fn visit_mir(&mut self, mir: &Mir<'tcx>) { - self.record("Mir", mir); - - // since the `super_mir` method does not traverse the MIR of - // promoted rvalues, (but we still want to gather statistics - // on the structures represented there) we manually traverse - // the promoted rvalues here. - for promoted_mir in &mir.promoted { - self.visit_mir(promoted_mir); - } - - self.super_mir(mir); - } - - fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) { - self.record("BasicBlockData", data); - self.super_basic_block_data(block, data); - } - - fn visit_source_scope_data(&mut self, scope_data: &SourceScopeData) { - self.record("SourceScopeData", scope_data); - self.super_source_scope_data(scope_data); - } - - fn visit_statement(&mut self, - block: BasicBlock, - statement: &Statement<'tcx>, - location: Location) { - self.record("Statement", statement); - self.record(match statement.kind { - StatementKind::Assign(..) => "StatementKind::Assign", - StatementKind::FakeRead(..) => "StatementKind::FakeRead", - StatementKind::Retag { .. } => "StatementKind::Retag", - StatementKind::EscapeToRaw { .. } => "StatementKind::EscapeToRaw", - StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant", - StatementKind::StorageLive(..) => "StatementKind::StorageLive", - StatementKind::StorageDead(..) => "StatementKind::StorageDead", - StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm", - StatementKind::AscribeUserType(..) => "StatementKind::AscribeUserType", - StatementKind::Nop => "StatementKind::Nop", - }, &statement.kind); - self.super_statement(block, statement, location); - } - - fn visit_terminator(&mut self, - block: BasicBlock, - terminator: &Terminator<'tcx>, - location: Location) { - self.record("Terminator", terminator); - self.super_terminator(block, terminator, location); - } - - fn visit_terminator_kind(&mut self, - block: BasicBlock, - kind: &TerminatorKind<'tcx>, - location: Location) { - self.record("TerminatorKind", kind); - self.record(match *kind { - TerminatorKind::Goto { .. } => "TerminatorKind::Goto", - TerminatorKind::SwitchInt { .. } => "TerminatorKind::SwitchInt", - TerminatorKind::Resume => "TerminatorKind::Resume", - TerminatorKind::Abort => "TerminatorKind::Abort", - TerminatorKind::Return => "TerminatorKind::Return", - TerminatorKind::Unreachable => "TerminatorKind::Unreachable", - TerminatorKind::Drop { .. } => "TerminatorKind::Drop", - TerminatorKind::DropAndReplace { .. } => "TerminatorKind::DropAndReplace", - TerminatorKind::Call { .. } => "TerminatorKind::Call", - TerminatorKind::Assert { .. } => "TerminatorKind::Assert", - TerminatorKind::GeneratorDrop => "TerminatorKind::GeneratorDrop", - TerminatorKind::Yield { .. } => "TerminatorKind::Yield", - TerminatorKind::FalseEdges { .. } => "TerminatorKind::FalseEdges", - TerminatorKind::FalseUnwind { .. } => "TerminatorKind::FalseUnwind", - }, kind); - self.super_terminator_kind(block, kind, location); - } - - fn visit_assert_message(&mut self, msg: &AssertMessage<'tcx>, location: Location) { - self.record("AssertMessage", msg); - self.record(match *msg { - EvalErrorKind::BoundsCheck { .. } => "AssertMessage::BoundsCheck", - EvalErrorKind::Overflow(..) => "AssertMessage::Overflow", - EvalErrorKind::OverflowNeg => "AssertMessage::OverflowNeg", - EvalErrorKind::DivisionByZero => "AssertMessage::DivisionByZero", - EvalErrorKind::RemainderByZero => "AssertMessage::RemainderByZero", - EvalErrorKind::GeneratorResumedAfterReturn => { - "AssertMessage::GeneratorResumedAfterReturn" - } - EvalErrorKind::GeneratorResumedAfterPanic => { - "AssertMessage::GeneratorResumedAfterPanic" - } - _ => bug!(), - }, msg); - self.super_assert_message(msg, location); - } - - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - self.record("Rvalue", rvalue); - let rvalue_kind = match *rvalue { - Rvalue::Use(..) => "Rvalue::Use", - Rvalue::Repeat(..) => "Rvalue::Repeat", - Rvalue::Ref(..) => "Rvalue::Ref", - Rvalue::Len(..) => "Rvalue::Len", - Rvalue::Cast(..) => "Rvalue::Cast", - Rvalue::BinaryOp(..) => "Rvalue::BinaryOp", - Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp", - Rvalue::UnaryOp(..) => "Rvalue::UnaryOp", - Rvalue::Discriminant(..) => "Rvalue::Discriminant", - Rvalue::NullaryOp(..) => "Rvalue::NullaryOp", - Rvalue::Aggregate(ref kind, ref _operands) => { - // AggregateKind is not distinguished by visit API, so - // record it. (`super_rvalue` handles `_operands`.) - self.record(match **kind { - AggregateKind::Array(_) => "AggregateKind::Array", - AggregateKind::Tuple => "AggregateKind::Tuple", - AggregateKind::Adt(..) => "AggregateKind::Adt", - AggregateKind::Closure(..) => "AggregateKind::Closure", - AggregateKind::Generator(..) => "AggregateKind::Generator", - }, kind); - - "Rvalue::Aggregate" - } - }; - self.record(rvalue_kind, rvalue); - self.super_rvalue(rvalue, location); - } - - fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { - self.record("Operand", operand); - self.record(match *operand { - Operand::Copy(..) => "Operand::Copy", - Operand::Move(..) => "Operand::Move", - Operand::Constant(..) => "Operand::Constant", - }, operand); - self.super_operand(operand, location); - } - - fn visit_place(&mut self, - place: &Place<'tcx>, - context: mir_visit::PlaceContext<'tcx>, - location: Location) { - self.record("Place", place); - self.record(match *place { - Place::Local(..) => "Place::Local", - Place::Static(..) => "Place::Static", - Place::Promoted(..) => "Place::Promoted", - Place::Projection(..) => "Place::Projection", - }, place); - self.super_place(place, context, location); - } - - fn visit_projection(&mut self, - place: &PlaceProjection<'tcx>, - context: mir_visit::PlaceContext<'tcx>, - location: Location) { - self.record("PlaceProjection", place); - self.super_projection(place, context, location); - } - - fn visit_projection_elem(&mut self, - place: &PlaceElem<'tcx>, - location: Location) { - self.record("PlaceElem", place); - self.record(match *place { - ProjectionElem::Deref => "PlaceElem::Deref", - ProjectionElem::Subslice { .. } => "PlaceElem::Subslice", - ProjectionElem::Field(..) => "PlaceElem::Field", - ProjectionElem::Index(..) => "PlaceElem::Index", - ProjectionElem::ConstantIndex { .. } => "PlaceElem::ConstantIndex", - ProjectionElem::Downcast(..) => "PlaceElem::Downcast", - }, place); - self.super_projection_elem(place, location); - } - - fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { - self.record("Constant", constant); - self.super_constant(constant, location); - } - - fn visit_source_info(&mut self, source_info: &SourceInfo) { - self.record("SourceInfo", source_info); - self.super_source_info(source_info); - } - - fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, _: Location) { - self.record("ClosureSubsts", substs); - self.super_closure_substs(substs); - } - - fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) { - self.record("Const", constant); - self.super_const(constant); - } - - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - self.record("LocalDecl", local_decl); - self.super_local_decl(local, local_decl); - } - - fn visit_source_scope(&mut self, scope: &SourceScope) { - self.record("VisiblityScope", scope); - self.super_source_scope(scope); - } -} diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ebd2c87fa4642..e449fece6b474 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3010,6 +3010,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Visit all direct subpatterns of this pattern. let outer_pat_id = pat.id; pat.walk(&mut |pat| { + debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node); match pat.node { PatKind::Ident(bmode, ident, ref opt_pat) => { // First try to resolve the identifier as some existing @@ -3166,6 +3167,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { format!("not found in {}", mod_str), item_span) }; + let code = DiagnosticId::Error(code.into()); let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code); @@ -3189,11 +3191,22 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { return (err, Vec::new()); } if is_self_value(path, ns) { + debug!("smart_resolve_path_fragment E0424 source:{:?}", source); + __diagnostic_used!(E0424); err.code(DiagnosticId::Error("E0424".into())); - err.span_label(span, format!("`self` value is a keyword \ - only available in \ - methods with `self` parameter")); + err.span_label(span, match source { + PathSource::Pat => { + format!("`self` value is a keyword \ + and may not be bound to \ + variables or shadowed") + } + _ => { + format!("`self` value is a keyword \ + only available in methods \ + with `self` parameter") + } + }); return (err, Vec::new()); } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index d8e8477f3d06b..aef8770bcc69b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -68,6 +68,7 @@ mod linux_musl_base; mod openbsd_base; mod netbsd_base; mod solaris_base; +mod uefi_base; mod windows_base; mod windows_msvc_base; mod thumb_base; @@ -254,12 +255,12 @@ macro_rules! supported_targets { } } - pub fn get_targets() -> Box> { - Box::new(TARGETS.iter().filter_map(|t| -> Option { + pub fn get_targets() -> impl Iterator { + TARGETS.iter().filter_map(|t| -> Option { load_specific(t) .and(Ok(t.to_string())) .ok() - })) + }) } #[cfg(test)] @@ -419,6 +420,8 @@ supported_targets! { ("aarch64-unknown-none", aarch64_unknown_none), ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx), + + ("x86_64-unknown-uefi", x86_64_unknown_uefi), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs new file mode 100644 index 0000000000000..9b0515837600b --- /dev/null +++ b/src/librustc_target/spec/uefi_base.rs @@ -0,0 +1,74 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This defines a base target-configuration for native UEFI systems. The UEFI specification has +// quite detailed sections on the ABI of all the supported target architectures. In almost all +// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN +// documentation. +// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic +// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated +// by the loader if the pre-chosen memory location is already in use. +// UEFI forbids running code on anything but the boot-CPU. Not interrupts are allowed other than +// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all +// code runs in the same environment, no process separation is supported. + +use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; +use std::default::Default; + +pub fn opts() -> TargetOptions { + let mut pre_link_args = LinkArgs::new(); + + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![ + // Suppress the verbose logo and authorship debugging output, which would needlessly + // clog any log files. + "/NOLOGO".to_string(), + + // UEFI is fully compatible to non-executable data pages. Tell the compiler that + // non-code sections can be marked as non-executable, including stack pages. + "/NXCOMPAT".to_string(), + + // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets + // must be freestanding. + "/nodefaultlib".to_string(), + + // Non-standard subsystems have no default entry-point in PE+ files. We have to define + // one. "efi_main" seems to be a common choice amongst other implementations and the + // spec. + "/entry:efi_main".to_string(), + + // COFF images have a "Subsystem" field in their header, which defines what kind of + // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, + // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, + // which is very likely the most common option. Individual projects can override this + // with custom linker flags. + // The subsystem-type only has minor effects on the application. It defines the memory + // regions the application is loaded into (runtime-drivers need to be put into + // reserved areas), as well as whether a return from the entry-point is treated as + // exit (default for applications). + "/subsystem:efi_application".to_string(), + ]); + + TargetOptions { + dynamic_linking: false, + executables: true, + disable_redzone: true, + exe_suffix: ".efi".to_string(), + allows_weak_linkage: false, + panic_strategy: PanicStrategy::Abort, + singlethread: true, + emit_debug_gdb_scripts: false, + + linker: Some("lld-link".to_string()), + lld_flavor: LldFlavor::Link, + pre_link_args, + + .. Default::default() + } +} diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs index 07383b3d64862..5b6d8abc5ef3e 100644 --- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -49,6 +49,7 @@ pub fn target() -> Result { max_atomic_width: Some(64), panic_strategy: PanicStrategy::Abort, cpu: "x86-64".into(), + features: "+rdrnd,+rdseed".into(), position_independent_executables: true, pre_link_args: iter::once( (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect()) diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs new file mode 100644 index 0000000000000..ea68afa717335 --- /dev/null +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -0,0 +1,58 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This defines the amd64 target for UEFI systems as described in the UEFI specification. See the +// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec) +// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a +// single-CPU execution. +// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with +// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features. + +use spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::uefi_base::opts(); + base.cpu = "x86-64".to_string(); + base.max_atomic_width = Some(64); + + // We disable MMX and SSE for now. UEFI does not prevent these from being used, but there have + // been reports to GRUB that some firmware does not initialize the FP exception handlers + // properly. Therefore, using FP coprocessors will end you up at random memory locations when + // you throw FP exceptions. + // To be safe, we disable them for now and force soft-float. This can be revisited when we + // have more test coverage. Disabling FP served GRUB well so far, so it should be good for us + // as well. + base.features = "-mmx,-sse,+soft-float".to_string(); + + // UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell + // LLVM to expect code to reference any address in the address-space. The "large" code-model + // places no locality-restrictions, so it fits well here. + base.code_model = Some("large".to_string()); + + // UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means + // small structs will be returned as int. This shouldn't matter much, since the restrictions + // placed by the UEFI specifications forbid any ABI to return structures. + base.abi_return_struct_as_int = true; + + Ok(Target { + llvm_target: "x86_64-unknown-windows".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + target_os: "uefi".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + arch: "x86_64".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), + + options: base, + }) +} diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b76c9101eae02..09063579c4214 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -424,10 +424,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if !unsatisfied_predicates.is_empty() { - let bound_list = unsatisfied_predicates.iter() + let mut bound_list = unsatisfied_predicates.iter() .map(|p| format!("`{} : {}`", p.self_ty(), p)) - .collect::>() - .join("\n"); + .collect::>(); + bound_list.sort(); + bound_list.dedup(); // #35677 + let bound_list = bound_list.join("\n"); err.note(&format!("the method `{}` exists but the following trait bounds \ were not satisfied:\n{}", item_name, diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index f46c4f2938b99..7e155396b8d5e 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -72,32 +72,32 @@ //! //! * **From Rust to C:** [`CString`] represents an owned, C-friendly //! string: it is nul-terminated, and has no internal nul characters. -//! Rust code can create a `CString` out of a normal string (provided +//! Rust code can create a [`CString`] out of a normal string (provided //! that the string doesn't have nul characters in the middle), and -//! then use a variety of methods to obtain a raw `*mut u8` that can +//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can //! then be passed as an argument to functions which use the C //! conventions for strings. //! //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it -//! is what you would use to wrap a raw `*const u8` that you got from -//! a C function. A `CStr` is guaranteed to be a nul-terminated array -//! of bytes. Once you have a `CStr`, you can convert it to a Rust -//! `&str` if it's valid UTF-8, or lossily convert it by adding +//! is what you would use to wrap a raw `*const `[`u8`] that you got from +//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array +//! of bytes. Once you have a [`CStr`], you can convert it to a Rust +//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding //! replacement characters. //! //! [`OsString`] and [`OsStr`] are useful when you need to transfer //! strings to and from the operating system itself, or when capturing -//! the output of external commands. Conversions between `OsString`, -//! `OsStr` and Rust strings work similarly to those for [`CString`] +//! the output of external commands. Conversions between [`OsString`], +//! [`OsStr`] and Rust strings work similarly to those for [`CString`] //! and [`CStr`]. //! //! * [`OsString`] represents an owned string in whatever //! representation the operating system prefers. In the Rust standard //! library, various APIs that transfer strings to/from the operating -//! system use `OsString` instead of plain strings. For example, +//! system use [`OsString`] instead of plain strings. For example, //! [`env::var_os()`] is used to query environment variables; it -//! returns an `Option`. If the environment variable exists -//! you will get a `Some(os_string)`, which you can *then* try to +//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable +//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to //! convert to a Rust string. This yields a [`Result<>`], so that //! your code can detect errors in case the environment variable did //! not in fact contain valid Unicode data. @@ -105,7 +105,7 @@ //! * [`OsStr`] represents a borrowed reference to a string in a //! format that can be passed to the operating system. It can be //! converted into an UTF-8 Rust string slice in a similar way to -//! `OsString`. +//! [`OsString`]. //! //! # Conversions //! @@ -131,7 +131,7 @@ //! Additionally, on Windows [`OsString`] implements the //! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt] //! trait, which provides a [`from_wide`] method. The result of this -//! method is an `OsString` which can be round-tripped to a Windows +//! method is an [`OsString`] which can be round-tripped to a Windows //! string losslessly. //! //! [`String`]: ../string/struct.String.html @@ -160,6 +160,8 @@ //! [`collect`]: ../iter/trait.Iterator.html#method.collect //! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html //! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide +//! [`Option`]: ../option/enum.Option.html +//! [`Some`]: ../option/enum.Option.html#variant.Some #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f4e9a7e409359..03c7aa9682477 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{self, Block, Ident, NodeId, PatKind, Path}; +use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path}; use ast::{MacStmtStyle, StmtKind, ItemKind}; use attr::{self, HasAttrs}; use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan}; @@ -1535,21 +1535,65 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info); items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item))); } - Err(ref e) if e.kind() == ErrorKind::InvalidData => { - self.cx.span_err( - at.span, - &format!("{} wasn't a utf-8 file", filename.display()), - ); - } Err(e) => { - self.cx.span_err( - at.span, - &format!("couldn't read {}: {}", filename.display(), e), - ); + let lit = it + .meta_item() + .and_then(|item| item.name_value_literal()) + .unwrap(); + + if e.kind() == ErrorKind::InvalidData { + self.cx + .struct_span_err( + lit.span, + &format!("{} wasn't a utf-8 file", filename.display()), + ) + .span_label(lit.span, "contains invalid utf-8") + .emit(); + } else { + let mut err = self.cx.struct_span_err( + lit.span, + &format!("couldn't read {}: {}", filename.display(), e), + ); + err.span_label(lit.span, "couldn't read file"); + + if e.kind() == ErrorKind::NotFound { + err.help("external doc paths are relative to the crate root"); + } + + err.emit(); + } } } } else { - items.push(noop_fold_meta_list_item(it, self)); + let mut err = self.cx.struct_span_err( + it.span, + &format!("expected path to external documentation"), + ); + + // Check if the user erroneously used `doc(include(...))` syntax. + let literal = it.meta_item_list().and_then(|list| { + if list.len() == 1 { + list[0].literal().map(|literal| &literal.node) + } else { + None + } + }); + + let (path, applicability) = match &literal { + Some(LitKind::Str(path, ..)) => { + (path.to_string(), Applicability::MachineApplicable) + } + _ => (String::from(""), Applicability::HasPlaceholders), + }; + + err.span_suggestion_with_applicability( + it.span, + "provide a file path with `=`", + format!("include = \"{}\"", path), + applicability, + ); + + err.emit(); } } diff --git a/src/stdsimd b/src/stdsimd index 5e628c5120c61..3c0503db84399 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 5e628c5120c619a22799187371f057ec41e06f87 +Subproject commit 3c0503db8439928e42c1175f0009c506fc874ae9 diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs new file mode 100644 index 0000000000000..4bb5c59722ad1 --- /dev/null +++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs @@ -0,0 +1,47 @@ +#![deny(unused_must_use)] +#![feature(futures_api, pin, arbitrary_self_types)] + +use std::iter::Iterator; +use std::future::Future; + +use std::task::{Poll, LocalWaker}; +use std::pin::Pin; +use std::unimplemented; + +struct MyFuture; + +impl Future for MyFuture { + type Output = u32; + + fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { + Poll::Pending + } +} + +fn iterator() -> impl Iterator { + std::iter::empty::() +} + +fn future() -> impl Future { + MyFuture +} + +fn square_fn_once() -> impl FnOnce(u32) -> u32 { + |x| x * x +} + +fn square_fn_mut() -> impl FnMut(u32) -> u32 { + |x| x * x +} + +fn square_fn() -> impl Fn(u32) -> u32 { + |x| x * x +} + +fn main() { + iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used + future(); //~ ERROR unused implementer of `std::future::Future` that must be used + square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used + square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used + square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used +} diff --git a/src/test/run-pass/issues/issue-18804/main.rs b/src/test/run-pass/issues/issue-18804/main.rs index 2abcd4b7ba99c..23c02f18862ee 100644 --- a/src/test/run-pass/issues/issue-18804/main.rs +++ b/src/test/run-pass/issues/issue-18804/main.rs @@ -14,9 +14,14 @@ // ignore-asmjs no weak symbol support // ignore-emscripten no weak symbol support +// ignore-windows no extern_weak linkage +// ignore-macos no extern_weak linkage // aux-build:lib.rs +// rust-lang/rust#56772: nikic says we need this to be proper test. +// compile-flags: -C no-prepopulate-passes + extern crate lib; fn main() { diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs new file mode 100644 index 0000000000000..c6c60177e9d0e --- /dev/null +++ b/src/test/ui/deprecation/deprecation-in-future.rs @@ -0,0 +1,12 @@ +// ignore-tidy-linelength + +#![deny(deprecated_in_future)] + +#[deprecated(since = "99.99.99", note = "text")] +pub fn deprecated_future() {} + +fn test() { + deprecated_future(); //~ ERROR use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text +} + +fn main() {} diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr new file mode 100644 index 0000000000000..38392cf96084c --- /dev/null +++ b/src/test/ui/deprecation/deprecation-in-future.stderr @@ -0,0 +1,14 @@ +error: use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text + --> $DIR/deprecation-in-future.rs:9:5 + | +LL | deprecated_future(); //~ ERROR use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text + | ^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/deprecation-in-future.rs:3:9 + | +LL | #![deny(deprecated_in_future)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0424.rs b/src/test/ui/error-codes/E0424.rs index 445d0c5f3edc0..20d42da1c0c40 100644 --- a/src/test/ui/error-codes/E0424.rs +++ b/src/test/ui/error-codes/E0424.rs @@ -19,4 +19,5 @@ impl Foo { } fn main () { + let self = "self"; //~ ERROR E0424 } diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr index a1b7a5f65336f..5eccd7d2283fe 100644 --- a/src/test/ui/error-codes/E0424.stderr +++ b/src/test/ui/error-codes/E0424.stderr @@ -4,6 +4,12 @@ error[E0424]: expected value, found module `self` LL | self.bar(); //~ ERROR E0424 | ^^^^ `self` value is a keyword only available in methods with `self` parameter -error: aborting due to previous error +error[E0424]: expected unit struct/variant or constant, found module `self` + --> $DIR/E0424.rs:22:9 + | +LL | let self = "self"; //~ ERROR E0424 + | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0424`. diff --git a/src/test/ui/extern/auxiliary/invalid-utf8.txt b/src/test/ui/extern/auxiliary/invalid-utf8.txt new file mode 100644 index 0000000000000..dc1115b82db40 --- /dev/null +++ b/src/test/ui/extern/auxiliary/invalid-utf8.txt @@ -0,0 +1 @@ +( \ No newline at end of file diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs index 5c6f6e49b3d77..e17dda65568e9 100644 --- a/src/test/ui/extern/external-doc-error.rs +++ b/src/test/ui/extern/external-doc-error.rs @@ -2,7 +2,31 @@ #![feature(external_doc)] -#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read -pub struct SomeStruct; +#[doc(include = "not-a-file.md")] +pub struct SomeStruct; //~^ ERROR couldn't read + //~| HELP external doc paths are relative to the crate root + +#[doc(include = "auxiliary/invalid-utf8.txt")] +pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file + +#[doc(include)] +pub struct MissingPath; //~^ ERROR expected path + //~| HELP provide a file path with `=` + //~| SUGGESTION include = "" + +#[doc(include("../README.md"))] +pub struct InvalidPathSyntax; //~^ ERROR expected path + //~| HELP provide a file path with `=` + //~| SUGGESTION include = "../README.md" + +#[doc(include = 123)] +pub struct InvalidPathType; //~^ ERROR expected path + //~| HELP provide a file path with `=` + //~| SUGGESTION include = "" + +#[doc(include(123))] +pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path + //~| HELP provide a file path with `=` + //~| SUGGESTION include = "" fn main() {} diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr index 5cc7551ee03aa..a3be3277de545 100644 --- a/src/test/ui/extern/external-doc-error.stderr +++ b/src/test/ui/extern/external-doc-error.stderr @@ -1,8 +1,40 @@ error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2) - --> $DIR/external-doc-error.rs:5:1 + --> $DIR/external-doc-error.rs:5:17 | -LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[doc(include = "not-a-file.md")] + | ^^^^^^^^^^^^^^^ couldn't read file + | + = help: external doc paths are relative to the crate root + +error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file + --> $DIR/external-doc-error.rs:9:17 + | +LL | #[doc(include = "auxiliary/invalid-utf8.txt")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8 + +error: expected path to external documentation + --> $DIR/external-doc-error.rs:12:7 + | +LL | #[doc(include)] + | ^^^^^^^ help: provide a file path with `=`: `include = ""` + +error: expected path to external documentation + --> $DIR/external-doc-error.rs:17:7 + | +LL | #[doc(include("../README.md"))] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"` + +error: expected path to external documentation + --> $DIR/external-doc-error.rs:22:7 + | +LL | #[doc(include = 123)] + | ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` + +error: expected path to external documentation + --> $DIR/external-doc-error.rs:27:7 + | +LL | #[doc(include(123))] + | ^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` -error: aborting due to previous error +error: aborting due to 6 previous errors diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index e2630b5b8ce47..ed6b325a01d4d 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -14,8 +14,8 @@ LL | .collect(); //~ ERROR no method named `collect` | ^^^^^^^ | = note: the method `collect` exists but the following trait bounds were not satisfied: - `std::iter::Cloned, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator` `&mut std::iter::Cloned, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator` + `std::iter::Cloned, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-35677.rs b/src/test/ui/issues/issue-35677.rs new file mode 100644 index 0000000000000..46d3f7e4af00b --- /dev/null +++ b/src/test/ui/issues/issue-35677.rs @@ -0,0 +1,5 @@ +use std::collections::HashMap; +fn intersect_map(this: &mut HashMap, other: HashMap) -> bool { + this.drain() + //~^ ERROR no method named +} diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr new file mode 100644 index 0000000000000..dca096b93f5f3 --- /dev/null +++ b/src/test/ui/issues/issue-35677.stderr @@ -0,0 +1,18 @@ +error[E0601]: `main` function not found in crate `issue_35677` + | + = note: consider adding a `main` function to `$DIR/issue-35677.rs` + +error[E0599]: no method named `drain` found for type `&mut std::collections::HashMap` in the current scope + --> $DIR/issue-35677.rs:3:10 + | +LL | this.drain() + | ^^^^^ + | + = note: the method `drain` exists but the following trait bounds were not satisfied: + `K : std::cmp::Eq` + `K : std::hash::Hash` + +error: aborting due to 2 previous errors + +Some errors occurred: E0599, E0601. +For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index a8b0e3e4250ea..6b9e1dc70573e 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -55,6 +55,7 @@ note: lint level defined here LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ = note: #[warn(unused_assignments)] implied by #[warn(unused)] + = help: maybe it is overwritten before being read? warning: unused variable: `fire` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:32 diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr index 063915d5b5f9a..1df2d7babe91b 100644 --- a/src/test/ui/lint/lint-unexported-no-mangle.stderr +++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr @@ -1,8 +1,8 @@ -warning: lint `private_no_mangle_fns` has been removed: `no longer an warning, #[no_mangle] functions always exported` +warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported` | = note: requested on the command line with `-F private_no_mangle_fns` -warning: lint `private_no_mangle_statics` has been removed: `no longer an warning, #[no_mangle] statics always exported` +warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported` | = note: requested on the command line with `-F private_no_mangle_statics` diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr index 6709fee0abb72..6e43cccdccff2 100644 --- a/src/test/ui/liveness/liveness-dead.stderr +++ b/src/test/ui/liveness/liveness-dead.stderr @@ -9,24 +9,31 @@ note: lint level defined here | LL | #![deny(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ + = help: maybe it is overwritten before being read? error: value assigned to `x` is never read --> $DIR/liveness-dead.rs:27:5 | LL | x = 4; //~ ERROR: value assigned to `x` is never read | ^ + | + = help: maybe it is overwritten before being read? error: value passed to `x` is never read --> $DIR/liveness-dead.rs:30:11 | LL | fn f4(mut x: i32) { //~ ERROR: value passed to `x` is never read | ^ + | + = help: maybe it is overwritten before being read? error: value assigned to `x` is never read --> $DIR/liveness-dead.rs:37:5 | LL | x = 4; //~ ERROR: value assigned to `x` is never read | ^ + | + = help: maybe it is overwritten before being read? error: aborting due to 4 previous errors diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index 2846f242fbe4c..35ccc79a19ac0 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -60,6 +60,7 @@ note: lint level defined here | LL | #![deny(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ + = help: maybe it is overwritten before being read? error: variable `z` is assigned to, but never used --> $DIR/liveness-unused.rs:47:13 @@ -106,6 +107,8 @@ error: value assigned to `x` is never read | LL | x = 0; //~ ERROR value assigned to `x` is never read | ^ + | + = help: maybe it is overwritten before being read? error: aborting due to 13 previous errors diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index 86a92a70287e9..1fbac9d688140 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -5,8 +5,8 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | ^^^^^ | = note: the method `count` exists but the following trait bounds were not satisfied: - `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` `&mut std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` + `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` error[E0631]: type mismatch in closure arguments --> $DIR/issue-36053-2.rs:17:32 diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs new file mode 100644 index 0000000000000..24676fe5e5bd9 --- /dev/null +++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs @@ -0,0 +1,74 @@ +// This is a collection of examples where a function's formal +// parameter has an explicit lifetime and a closure within that +// function returns that formal parameter. The closure's return type, +// to be correctly inferred, needs to include the lifetime introduced +// by the function. +// +// This works today, which precludes changing things so that closures +// follow the same lifetime-elision rules used elsehwere. See +// rust-lang/rust#56537 + +// compile-pass +// We are already testing NLL explicitly via the revision system below. +// ignore-compare-mode-nll + +// revisions: ll nll migrate +//[ll] compile-flags:-Zborrowck=ast +//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows +//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows + +fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| { p }; // no type annotation at all + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| -> &str { p }; // type annotation on the return type + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn main() { + let world = format!("World"); + let w1: &str = { + let hello = format!("He11o"); + willy_no_annot(&world, &hello) + }; + let w2: &str = { + let hello = format!("He22o"); + willy_ret_type_annot(&world, &hello) + }; + let w3: &str = { + let hello = format!("He33o"); + willy_ret_region_annot(&world, &hello) + }; + let w4: &str = { + let hello = format!("He44o"); + willy_arg_type_ret_type_annot(&world, &hello) + }; + let w5: &str = { + let hello = format!("He55o"); + willy_arg_type_ret_region_annot(&world, &hello) + }; + assert_eq!((w1, w2, w3, w4, w5), + ("World","World","World","World","World")); +} diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed new file mode 100644 index 0000000000000..8592af1262e6f --- /dev/null +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed @@ -0,0 +1,18 @@ +// run-rustfix + +use std::fmt::Debug; + +fn foo(d: impl Debug + 'static) { +//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug` + bar(d); +//~^ ERROR the parameter type `impl Debug` may not live long enough +//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds +} + +fn bar(d: impl Debug + 'static) { + println!("{:?}", d) +} + +fn main() { + foo("hi"); +} diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs new file mode 100644 index 0000000000000..c67d78ea4c73b --- /dev/null +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs @@ -0,0 +1,18 @@ +// run-rustfix + +use std::fmt::Debug; + +fn foo(d: impl Debug) { +//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug` + bar(d); +//~^ ERROR the parameter type `impl Debug` may not live long enough +//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds +} + +fn bar(d: impl Debug + 'static) { + println!("{:?}", d) +} + +fn main() { + foo("hi"); +} diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr new file mode 100644 index 0000000000000..cba231d0e86e5 --- /dev/null +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr @@ -0,0 +1,19 @@ +error[E0310]: the parameter type `impl Debug` may not live long enough + --> $DIR/suggest-impl-trait-lifetime.rs:7:5 + | +LL | bar(d); + | ^^^ + | +note: ...so that the type `impl Debug` will meet its required lifetime bounds + --> $DIR/suggest-impl-trait-lifetime.rs:7:5 + | +LL | bar(d); + | ^^^ +help: consider adding an explicit lifetime bound `'static` to `impl Debug`... + | +LL | fn foo(d: impl Debug + 'static) { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 4ade87f5d65bd..a65d263d2e3a3 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -34,6 +34,16 @@ 'rust-by-example': '@steveklabnik @marioidival @projektir', } +EMOJI = { + 'miri': '🛰️', + 'clippy-driver': '📎', + 'rls': '💻', + 'rustfmt': '📝', + 'book': '📖', + 'nomicon': '👿', + 'reference': '📚', + 'rust-by-example': '👩‍🏫', +} def read_current_status(current_commit, path): '''Reads build status of `current_commit` from content of `history/*.tsv` @@ -63,13 +73,12 @@ def update_latest( } slug = 'rust-lang/rust' - message = textwrap.dedent('''\ - 📣 Toolstate changed by {}! - + long_message = textwrap.dedent('''\ Tested on commit {}@{}. Direct link to PR: <{}> - ''').format(relevant_pr_number, slug, current_commit, relevant_pr_url) + ''').format(slug, current_commit, relevant_pr_url) + emoji_status = [] anything_changed = False for status in latest: tool = status['tool'] @@ -81,12 +90,18 @@ def update_latest( status[os] = new if new > old: changed = True - message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ - .format(tool, os, old, new, MAINTAINERS.get(tool)) + long_message += '🎉 {} on {}: {} → {}.\n' \ + .format(tool, os, old, new) + emoji = "{}🎉".format(EMOJI.get(tool)) + if msg not in emoji_status: + emoji_status += [msg] elif new < old: changed = True - message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ + long_message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ .format(tool, os, old, new, MAINTAINERS.get(tool)) + emoji = "{}💔".format(EMOJI.get(tool)) + if msg not in emoji_status: + emoji_status += [msg] if changed: status['commit'] = current_commit @@ -96,6 +111,9 @@ def update_latest( if not anything_changed: return '' + short_message = "📣 Toolstate changed by {}! ({})" + .format(relevant_pr_number, '/'.join(emoji_status)) + message = short_message + "\n\n" + long_message f.seek(0) f.truncate(0) json.dump(latest, f, indent=4, separators=(',', ': '))