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 88b6925b2b1e7..61ddc8aa9498b 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.32.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/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index a376c8593f4c0..f02c7d87590ac 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -9,6 +9,7 @@ # except according to those terms. import gdb +import re import sys import debugger_pretty_printers_common as rustpp @@ -20,6 +21,16 @@ rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True) +# The btree pretty-printers fail in a confusing way unless +# https://sourceware.org/bugzilla/show_bug.cgi?id=21763 is fixed. +# This fix went in 8.1, so check for that. +# See https://github.com/rust-lang/rust/issues/56730 +gdb_81 = False +_match = re.match('([0-9]+)\\.([0-9]+)', gdb.VERSION) +if _match: + if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1): + gdb_81 = True + #=============================================================================== # GDB Pretty Printing Module for Rust #=============================================================================== @@ -110,10 +121,10 @@ def rust_pretty_printer_lookup_function(gdb_val): if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE: return RustStdVecDequePrinter(val) - if type_kind == rustpp.TYPE_KIND_STD_BTREESET: + if type_kind == rustpp.TYPE_KIND_STD_BTREESET and gdb_81: return RustStdBTreeSetPrinter(val) - if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP: + if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP and gdb_81: return RustStdBTreeMapPrinter(val) if type_kind == rustpp.TYPE_KIND_STD_STRING: 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/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/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 8d2b1d74c554b..43bc9d88895d7 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -36,6 +36,7 @@ use traits::{Obligation, ObligationCause, PredicateObligation}; use ty::fold::TypeFoldable; use ty::subst::{Kind, UnpackedKind}; use ty::{self, BoundVar, Lift, Ty, TyCtxt}; +use util::captures::Captures; impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> { /// The "main method" for a canonicalized trait query. Given the @@ -527,32 +528,30 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>], result_subst: &'a CanonicalVarValues<'tcx>, - ) -> impl Iterator> + 'a { - Box::new( - unsubstituted_region_constraints - .iter() - .map(move |constraint| { - let constraint = substitute_value(self.tcx, result_subst, constraint); - let &ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below - - Obligation::new( - cause.clone(), - param_env, - match k1.unpack() { - UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives( - ty::Binder::bind( - ty::OutlivesPredicate(r1, r2) - ) - ), - UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives( - ty::Binder::bind( - ty::OutlivesPredicate(t1, r2) - ) - ), - } - ) - }) - ) as Box> + ) -> impl Iterator> + 'a + Captures<'gcx> { + unsubstituted_region_constraints + .iter() + .map(move |constraint| { + let constraint = substitute_value(self.tcx, result_subst, constraint); + let &ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below + + Obligation::new( + cause.clone(), + param_env, + match k1.unpack() { + UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives( + ty::Binder::bind( + ty::OutlivesPredicate(r1, r2) + ) + ), + UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives( + ty::Binder::bind( + ty::OutlivesPredicate(t1, r2) + ) + ), + } + ) + }) } /// Given two sets of values for the same set of canonical variables, unify them. 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 a09d167f2173c..df3defc2c5cba 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/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 22221e0a3d93d..b0ca2f6cecc0b 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -132,10 +132,12 @@ impl<'a, 'gcx, 'tcx> Children { simplified_self, ); - for possible_sibling in match simplified_self { - Some(sty) => self.filtered(sty), - None => self.iter(), - } { + let possible_siblings = match simplified_self { + Some(sty) => PotentialSiblings::Filtered(self.filtered(sty)), + None => PotentialSiblings::Unfiltered(self.iter()), + }; + + for possible_sibling in possible_siblings { debug!( "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}", impl_def_id, @@ -222,14 +224,37 @@ impl<'a, 'gcx, 'tcx> Children { Ok(Inserted::BecameNewSibling(last_lint)) } - fn iter(&mut self) -> Box + '_> { + fn iter(&mut self) -> impl Iterator + '_ { let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter()); - Box::new(self.blanket_impls.iter().chain(nonblanket).cloned()) + self.blanket_impls.iter().chain(nonblanket).cloned() } - fn filtered(&mut self, sty: SimplifiedType) -> Box + '_> { + fn filtered(&mut self, sty: SimplifiedType) -> impl Iterator + '_ { let nonblanket = self.nonblanket_impls.entry(sty).or_default().iter(); - Box::new(self.blanket_impls.iter().chain(nonblanket).cloned()) + self.blanket_impls.iter().chain(nonblanket).cloned() + } +} + +// A custom iterator used by Children::insert +enum PotentialSiblings + where I: Iterator, + J: Iterator +{ + Unfiltered(I), + Filtered(J) +} + +impl Iterator for PotentialSiblings + where I: Iterator, + J: Iterator +{ + type Item = DefId; + + fn next(&mut self) -> Option { + match *self { + PotentialSiblings::Unfiltered(ref mut iter) => iter.next(), + PotentialSiblings::Filtered(ref mut iter) => iter.next() + } } } diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index 1e648c4581733..c2bfa62cf9d06 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -62,11 +62,15 @@ macro_rules! define_categories { } fn print(&self, lock: &mut StderrLock<'_>) { - writeln!(lock, "| Phase | Time (ms) | Queries | Hits (%) |") + writeln!(lock, "| Phase | Time (ms) \ + | Time (%) | Queries | Hits (%)") .unwrap(); - writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |") + writeln!(lock, "| ---------------- | -------------- \ + | -------- | -------------- | --------") .unwrap(); + let total_time = ($(self.times.$name + )* 0) as f32; + $( let (hits, total) = self.query_counts.$name; let (hits, total) = if total > 0 { @@ -78,11 +82,12 @@ macro_rules! define_categories { writeln!( lock, - "| {0: <16} | {1: <14} | {2: <14} | {3: <8} |", + "| {0: <16} | {1: <14} | {2: <8.2} | {3: <14} | {4: <8}", stringify!($name), self.times.$name / 1_000_000, + ((self.times.$name as f32) / total_time) * 100.0, total, - hits + hits, ).unwrap(); )* } diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 30edc4744ecd4..48e0a3a12c963 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -18,6 +18,7 @@ use rustc::session::config::Sanitizer; use rustc::ty::{self, TyCtxt, PolyFnSig}; use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; +use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::FxHashMap; use rustc_target::spec::PanicStrategy; @@ -130,8 +131,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { } pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { - let cpu = llvm_util::target_cpu(cx.tcx.sess); - let target_cpu = CString::new(cpu).unwrap(); + let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess)); llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, @@ -231,11 +231,7 @@ pub fn from_fn_attrs( // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated // functions (because Clang annotates functions this way too). - // NOTE: For now we just apply this if -Zcross-lang-lto is specified, since - // it introduce a little overhead and isn't really necessary otherwise. - if cx.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() { - apply_target_cpu_attr(cx, llfn); - } + apply_target_cpu_attr(cx, llfn); let features = llvm_target_features(cx.tcx.sess) .map(|s| s.to_string()) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 2b82ebe0bc25c..8b26ada157606 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1171,6 +1171,27 @@ fn generic_simd_intrinsic( ); let arg_tys = sig.inputs(); + if name == "simd_select_bitmask" { + let in_ty = arg_tys[0]; + let m_len = match in_ty.sty { + // Note that this `.unwrap()` crashes for isize/usize, that's sort + // of intentional as there's not currently a use case for that. + ty::Int(i) => i.bit_width().unwrap(), + ty::Uint(i) => i.bit_width().unwrap(), + _ => return_error!("`{}` is not an integral type", in_ty), + }; + require_simd!(arg_tys[1], "argument"); + let v_len = arg_tys[1].simd_size(tcx); + require!(m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, v_len + ); + let i1 = bx.type_i1(); + let i1xn = bx.type_vector(i1, m_len as u64); + let m_i1s = bx.bitcast(args[0].immediate(), i1xn); + return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); + } + // every intrinsic takes a SIMD vector as its first argument require_simd!(arg_tys[0], "input"); let in_ty = arg_tys[0]; diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index fdb6373bea1fe..12109ae1662ff 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -124,6 +124,7 @@ const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[ ]; const X86_WHITELIST: &[(&str, Option<&str>)] = &[ + ("adx", Some("adx_target_feature")), ("aes", None), ("avx", None), ("avx2", None), diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 7b1c7cfb56f4c..50994497c2843 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -16,7 +16,7 @@ num_cpus = "1.0" rustc-demangle = "0.1.4" memmap = "0.6" log = "0.4.5" -libc = "0.2.43" +libc = "0.2.44" jobserver = "0.1.11" serialize = { path = "../libserialize" } 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_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index cfea357334fa8..328b330f762dc 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -26,6 +26,10 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::matches::{Ascription, Binding, MatchPair, Candidate}; use hair::*; use rustc::mir::*; +use rustc::ty; +use rustc::ty::layout::{Integer, IntegerExt, Size}; +use syntax::attr::{SignedInt, UnsignedInt}; +use rustc::hir::RangeEnd; use std::mem; @@ -62,6 +66,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match_pair: MatchPair<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>) -> Result<(), MatchPair<'pat, 'tcx>> { + let tcx = self.hir.tcx(); match *match_pair.pattern.kind { PatternKind::AscribeUserType { ref subpattern, ref user_ty, user_ty_span } => { candidate.ascriptions.push(Ascription { @@ -104,7 +109,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Err(match_pair) } - PatternKind::Range { .. } => { + PatternKind::Range { lo, hi, ty, end } => { + let range = match ty.sty { + ty::Char => { + Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))) + } + ty::Int(ity) => { + // FIXME(49937): refactor these bit manipulations into interpret. + let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); + let min = 1u128 << (size.bits() - 1); + let max = (1u128 << (size.bits() - 1)) - 1; + Some((min, max, size)) + } + ty::Uint(uty) => { + // FIXME(49937): refactor these bit manipulations into interpret. + let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); + let max = !0u128 >> (128 - size.bits()); + Some((0, max, size)) + } + _ => None, + }; + if let Some((min, max, sz)) = range { + if let (Some(lo), Some(hi)) = (lo.val.try_to_bits(sz), hi.val.try_to_bits(sz)) { + if lo <= min && (hi > max || hi == max && end == RangeEnd::Included) { + // Irrefutable pattern match. + return Ok(()); + } + } + } Err(match_pair) } 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_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/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 5c0eef5b1f332..a40e56d68ae8b 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -435,7 +435,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), - "simd_select" => (2, vec![param(0), param(1), param(1)], param(1)), + "simd_select" | + "simd_select_bitmask" => (2, vec![param(0), param(1), param(1)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), "simd_reduce_add_ordered" | "simd_reduce_mul_ordered" => (2, vec![param(0), param(1)], param(1)), 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/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 00ca4fed2f4a0..536ea39d29805 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -806,6 +806,10 @@ impl<'a> fmt::Display for MarkdownSummaryLine<'a> { } pub fn plain_summary_line(md: &str) -> String { + plain_summary_line_full(md, false) +} + +pub fn plain_summary_line_full(md: &str, limit_length: bool) -> String { struct ParserWrapper<'a> { inner: Parser<'a>, is_in: isize, @@ -852,7 +856,21 @@ pub fn plain_summary_line(md: &str) -> String { s.push_str(&t); } } - s + if limit_length && s.chars().count() > 60 { + let mut len = 0; + let mut ret = s.split_whitespace() + .take_while(|p| { + // + 1 for the added character after the word. + len += p.chars().count() + 1; + len < 60 + }) + .collect::>() + .join(" "); + ret.push('…'); + ret + } else { + s + } } pub fn markdown_links(md: &str) -> Vec<(String, Option>)> { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 8d7942a14669c..1e28dbea5fd65 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -698,7 +698,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { ty: item.type_(), name: item.name.clone().unwrap(), path: fqp[..fqp.len() - 1].join("::"), - desc: plain_summary_line(item.doc_value()), + desc: plain_summary_line_short(item.doc_value()), parent: Some(did), parent_idx: None, search_type: get_index_search_type(&item), @@ -736,7 +736,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { } let crate_doc = krate.module.as_ref().map(|module| { - plain_summary_line(module.doc_value()) + plain_summary_line_short(module.doc_value()) }).unwrap_or(String::new()); let mut crate_data = BTreeMap::new(); @@ -1481,7 +1481,7 @@ impl DocFolder for Cache { ty: item.type_(), name: s.to_string(), path: path.join("::"), - desc: plain_summary_line(item.doc_value()), + desc: plain_summary_line_short(item.doc_value()), parent, parent_idx: None, search_type: get_index_search_type(&item), @@ -1673,7 +1673,7 @@ impl<'a> Cache { ty: item.type_(), name: item_name.to_string(), path: path.clone(), - desc: plain_summary_line(item.doc_value()), + desc: plain_summary_line_short(item.doc_value()), parent: None, parent_idx: None, search_type: get_index_search_type(&item), @@ -2388,7 +2388,13 @@ fn shorter<'a>(s: Option<&'a str>) -> String { #[inline] fn plain_summary_line(s: Option<&str>) -> String { let line = shorter(s).replace("\n", " "); - markdown::plain_summary_line(&line[..]) + markdown::plain_summary_line_full(&line[..], false) +} + +#[inline] +fn plain_summary_line_short(s: Option<&str>) -> String { + let line = shorter(s).replace("\n", " "); + markdown::plain_summary_line_full(&line[..], true) } fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result { diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 99da73adc63e9..d1692e6cde1b1 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/libstd/io/lazy.rs b/src/libstd/io/lazy.rs index c2aaeb9890745..24965ff693184 100644 --- a/src/libstd/io/lazy.rs +++ b/src/libstd/io/lazy.rs @@ -26,7 +26,6 @@ const fn done() -> *mut Arc { 1_usize as *mut _ } unsafe impl Sync for Lazy {} impl Lazy { - #[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Lazy { Lazy { lock: Mutex::new(), diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 90c8eaf0f7cbc..a69ec76376aab 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -271,6 +271,7 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index ccf848a9be420..3229d98624e17 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -13,7 +13,7 @@ use mem; use sync::atomic::{AtomicU32, Ordering}; use sys::cloudabi::abi; use sys::mutex::{self, Mutex}; -use sys::time::dur2intervals; +use sys::time::checked_dur2intervals; use time::Duration; extern "C" { @@ -114,6 +114,8 @@ impl Condvar { // Call into the kernel to wait on the condition variable. let condvar = self.condvar.get(); + let timeout = checked_dur2intervals(&dur) + .expect("overflow converting duration to nanoseconds"); let subscriptions = [ abi::subscription { type_: abi::eventtype::CONDVAR, @@ -132,7 +134,7 @@ impl Condvar { union: abi::subscription_union { clock: abi::subscription_clock { clock_id: abi::clockid::MONOTONIC, - timeout: dur2intervals(&dur), + timeout, ..mem::zeroed() }, }, diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index a76e1fa3345cd..177321439d83c 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -16,7 +16,7 @@ use libc; use mem; use ptr; use sys::cloudabi::abi; -use sys::time::dur2intervals; +use sys::time::checked_dur2intervals; use sys_common::thread::*; use time::Duration; @@ -70,13 +70,15 @@ impl Thread { } pub fn sleep(dur: Duration) { + let timeout = checked_dur2intervals(&dur) + .expect("overflow converting duration to nanoseconds"); unsafe { let subscription = abi::subscription { type_: abi::eventtype::CLOCK, union: abi::subscription_union { clock: abi::subscription_clock { clock_id: abi::clockid::MONOTONIC, - timeout: dur2intervals(&dur), + timeout, ..mem::zeroed() }, }, diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index a442d1e4ad7b7..c9fea18fda6ec 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -19,15 +19,10 @@ pub struct Instant { t: abi::timestamp, } -fn checked_dur2intervals(dur: &Duration) -> Option { +pub fn checked_dur2intervals(dur: &Duration) -> Option { dur.as_secs() - .checked_mul(NSEC_PER_SEC) - .and_then(|nanos| nanos.checked_add(dur.subsec_nanos() as abi::timestamp)) -} - -pub fn dur2intervals(dur: &Duration) -> abi::timestamp { - checked_dur2intervals(dur) - .expect("overflow converting duration to nanoseconds") + .checked_mul(NSEC_PER_SEC)? + .checked_add(dur.subsec_nanos() as abi::timestamp) } impl Instant { @@ -47,20 +42,16 @@ impl Instant { Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32) } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant { - t: self.t - .checked_add(dur2intervals(other)) - .expect("overflow when adding duration to instant"), - } + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant { + t: self.t.checked_add(checked_dur2intervals(other)?)?, + }) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant { - t: self.t - .checked_sub(dur2intervals(other)) - .expect("overflow when subtracting duration from instant"), - } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant { + t: self.t.checked_sub(checked_dur2intervals(other)?)?, + }) } } @@ -95,23 +86,16 @@ impl SystemTime { } } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - self.checked_add_duration(other) - .expect("overflow when adding duration to instant") - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - checked_dur2intervals(other) - .and_then(|d| self.t.checked_add(d)) - .map(|t| SystemTime {t}) + Some(SystemTime { + t: self.t.checked_add(checked_dur2intervals(other)?)?, + }) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime { - t: self.t - .checked_sub(dur2intervals(other)) - .expect("overflow when subtracting duration from instant"), - } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime { + t: self.t.checked_sub(checked_dur2intervals(other)?)?, + }) } } diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs index beff8d287e7c4..cb2eab5221181 100644 --- a/src/libstd/sys/redox/time.rs +++ b/src/libstd/sys/redox/time.rs @@ -41,10 +41,6 @@ impl Timespec { } } - fn add_duration(&self, other: &Duration) -> Timespec { - self.checked_add_duration(other).expect("overflow when adding duration to time") - } - fn checked_add_duration(&self, other: &Duration) -> Option { let mut secs = other .as_secs() @@ -67,27 +63,25 @@ impl Timespec { }) } - fn sub_duration(&self, other: &Duration) -> Timespec { + fn checked_sub_duration(&self, other: &Duration) -> Option { let mut secs = other .as_secs() .try_into() // <- target type would be `i64` .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs)) - .expect("overflow when subtracting duration from time"); + .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; // Similar to above, nanos can't overflow. let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; if nsec < 0 { nsec += NSEC_PER_SEC as i32; - secs = secs.checked_sub(1).expect("overflow when subtracting \ - duration from time"); + secs = secs.checked_sub(1)?; } - Timespec { + Some(Timespec { t: syscall::TimeSpec { tv_sec: secs, tv_nsec: nsec as i32, }, - } + }) } } @@ -150,12 +144,12 @@ impl Instant { }) } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant { t: self.t.add_duration(other) } + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_add_duration(other)? }) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant { t: self.t.sub_duration(other) } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_sub_duration(other)? }) } } @@ -178,16 +172,12 @@ impl SystemTime { self.t.sub_timespec(&other.t) } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.add_duration(other) } - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - self.t.checked_add_duration(other).map(|t| SystemTime { t }) + Some(SystemTime { t: self.t.checked_add_duration(other)? }) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.sub_duration(other) } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime { t: self.t.checked_sub_duration(other)? }) } } diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs index 508f2ff4d4fa5..bf32c712216bc 100644 --- a/src/libstd/sys/sgx/abi/mem.rs +++ b/src/libstd/sys/sgx/abi/mem.rs @@ -34,13 +34,6 @@ fn image_base() -> u64 { base } -pub fn is_enclave_range(p: *const u8, len: usize) -> bool { - let start=p as u64; - let end=start + (len as u64); - start >= image_base() && - end <= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant -} - pub fn is_user_range(p: *const u8, len: usize) -> bool { let start=p as u64; let end=start + (len as u64); diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index 2bc32c9fefbb7..d1d180e48251f 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -33,14 +33,6 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult { } } -pub fn read_alloc(fd: Fd) -> IoResult> { - unsafe { - let mut userbuf = alloc::User::::uninitialized(); - raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?; - Ok(copy_user_buffer(&userbuf)) - } -} - pub fn write(fd: Fd, buf: &[u8]) -> IoResult { unsafe { let userbuf = alloc::User::new_from_enclave(buf); diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs index d3e8165f3dfe7..940f50f25b81a 100644 --- a/src/libstd/sys/sgx/condvar.rs +++ b/src/libstd/sys/sgx/condvar.rs @@ -18,7 +18,6 @@ pub struct Condvar { } impl Condvar { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Condvar { Condvar { inner: SpinMutex::new(WaitVariable::new(())) } } diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs index 663361162bc6b..994cf91eea0cd 100644 --- a/src/libstd/sys/sgx/mutex.rs +++ b/src/libstd/sys/sgx/mutex.rs @@ -20,7 +20,6 @@ pub struct Mutex { // Implementation according to β€œOperating Systems: Three Easy Pieces”, chapter 28 impl Mutex { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Mutex { Mutex { inner: SpinMutex::new(WaitVariable::new(false)) } } @@ -79,7 +78,6 @@ pub struct ReentrantMutex { } impl ReentrantMutex { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn uninitialized() -> ReentrantMutex { ReentrantMutex { inner: SpinMutex::new(WaitVariable::new(ReentrantLock { owner: None, count: 0 })) diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 7b6970b825f93..a1551dbb53b2d 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -21,7 +21,6 @@ pub struct RWLock { //unsafe impl Sync for RWLock {} // FIXME impl RWLock { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> RWLock { RWLock { readers: SpinMutex::new(WaitVariable::new(None)), diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs index b01c992768e71..196e1a97fc44f 100644 --- a/src/libstd/sys/sgx/time.rs +++ b/src/libstd/sys/sgx/time.rs @@ -28,12 +28,12 @@ impl Instant { self.0 - other.0 } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant(self.0 + *other) + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_add(*other)?)) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant(self.0 - *other) + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_sub(*other)?)) } } @@ -47,15 +47,11 @@ impl SystemTime { self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime(self.0 + *other) - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - self.0.checked_add(*other).map(|d| SystemTime(d)) + Some(SystemTime(self.0.checked_add(*other)?)) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime(self.0 - *other) + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index ec1135ba30c4b..ef0def13eee88 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -50,7 +50,6 @@ pub struct WaitVariable { } impl WaitVariable { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new(var: T) -> Self { WaitVariable { queue: WaitQueue::new(), @@ -137,7 +136,6 @@ impl<'a, T> Drop for WaitGuard<'a, T> { } impl WaitQueue { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Self { WaitQueue { inner: UnsafeList::new() @@ -255,7 +253,6 @@ mod unsafe_list { } impl UnsafeList { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Self { unsafe { UnsafeList { diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 1f9539c36e02e..8f8aaa88b2265 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -42,10 +42,6 @@ impl Timespec { } } - fn add_duration(&self, other: &Duration) -> Timespec { - self.checked_add_duration(other).expect("overflow when adding duration to time") - } - fn checked_add_duration(&self, other: &Duration) -> Option { let mut secs = other .as_secs() @@ -68,27 +64,25 @@ impl Timespec { }) } - fn sub_duration(&self, other: &Duration) -> Timespec { + fn checked_sub_duration(&self, other: &Duration) -> Option { let mut secs = other .as_secs() .try_into() // <- target type would be `libc::time_t` .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs)) - .expect("overflow when subtracting duration from time"); + .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; // Similar to above, nanos can't overflow. let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; if nsec < 0 { nsec += NSEC_PER_SEC as i32; - secs = secs.checked_sub(1).expect("overflow when subtracting \ - duration from time"); + secs = secs.checked_sub(1)?; } - Timespec { + Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _, }, - } + }) } } @@ -165,18 +159,16 @@ mod inner { Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32) } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant { - t: self.t.checked_add(dur2intervals(other)) - .expect("overflow when adding duration to instant"), - } + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant { + t: self.t.checked_add(checked_dur2intervals(other)?)?, + }) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant { - t: self.t.checked_sub(dur2intervals(other)) - .expect("overflow when subtracting duration from instant"), - } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant { + t: self.t.checked_sub(checked_dur2intervals(other)?)?, + }) } } @@ -199,16 +191,12 @@ mod inner { self.t.sub_timespec(&other.t) } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.add_duration(other) } - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - self.t.checked_add_duration(other).map(|t| SystemTime { t }) + Some(SystemTime { t: self.t.checked_add_duration(other)? }) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.sub_duration(other) } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime { t: self.t.checked_sub_duration(other)? }) } } @@ -236,12 +224,12 @@ mod inner { } } - fn dur2intervals(dur: &Duration) -> u64 { + fn checked_dur2intervals(dur: &Duration) -> Option { + let nanos = dur.as_secs() + .checked_mul(NSEC_PER_SEC)? + .checked_add(dur.subsec_nanos() as u64)?; let info = info(); - let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| { - nanos.checked_add(dur.subsec_nanos() as u64) - }).expect("overflow converting duration to nanoseconds"); - mul_div_u64(nanos, info.denom as u64, info.numer as u64) + Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64)) } fn info() -> &'static libc::mach_timebase_info { @@ -299,12 +287,12 @@ mod inner { }) } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant { t: self.t.add_duration(other) } + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_add_duration(other)? }) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant { t: self.t.sub_duration(other) } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_sub_duration(other)? }) } } @@ -327,16 +315,12 @@ mod inner { self.t.sub_timespec(&other.t) } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.add_duration(other) } - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - self.t.checked_add_duration(other).map(|t| SystemTime { t }) + Some(SystemTime { t: self.t.checked_add_duration(other)? }) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime { t: self.t.sub_duration(other) } + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime { t: self.t.checked_sub_duration(other)? }) } } diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs index 991e8176edf6d..cc56773e0ea8e 100644 --- a/src/libstd/sys/wasm/time.rs +++ b/src/libstd/sys/wasm/time.rs @@ -28,12 +28,12 @@ impl Instant { self.0 - other.0 } - pub fn add_duration(&self, other: &Duration) -> Instant { - Instant(self.0 + *other) + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_add(*other)?)) } - pub fn sub_duration(&self, other: &Duration) -> Instant { - Instant(self.0 - *other) + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_sub(*other)?)) } } @@ -47,15 +47,11 @@ impl SystemTime { self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime(self.0 + *other) - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - self.0.checked_add(*other).map(|d| SystemTime(d)) + Some(SystemTime(self.0.checked_add(*other)?)) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - SystemTime(self.0 - *other) + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index c809a0b98ac94..bb2c97ea149d2 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -68,30 +68,27 @@ impl Instant { Duration::new(nanos / NANOS_PER_SEC, (nanos % NANOS_PER_SEC) as u32) } - pub fn add_duration(&self, other: &Duration) -> Instant { + pub fn checked_add_duration(&self, other: &Duration) -> Option { let freq = frequency() as u64; - let t = other.as_secs().checked_mul(freq).and_then(|i| { - (self.t as u64).checked_add(i) - }).and_then(|i| { - i.checked_add(mul_div_u64(other.subsec_nanos() as u64, freq, - NANOS_PER_SEC)) - }).expect("overflow when adding duration to time"); - Instant { + let t = other.as_secs() + .checked_mul(freq)? + .checked_add(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC))? + .checked_add(self.t as u64)?; + Some(Instant { t: t as c::LARGE_INTEGER, - } + }) } - pub fn sub_duration(&self, other: &Duration) -> Instant { + pub fn checked_sub_duration(&self, other: &Duration) -> Option { let freq = frequency() as u64; let t = other.as_secs().checked_mul(freq).and_then(|i| { (self.t as u64).checked_sub(i) }).and_then(|i| { - i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq, - NANOS_PER_SEC)) - }).expect("overflow when subtracting duration from time"); - Instant { + i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC)) + })?; + Some(Instant { t: t as c::LARGE_INTEGER, - } + }) } } @@ -127,20 +124,14 @@ impl SystemTime { } } - pub fn add_duration(&self, other: &Duration) -> SystemTime { - self.checked_add_duration(other).expect("overflow when adding duration to time") - } - pub fn checked_add_duration(&self, other: &Duration) -> Option { - checked_dur2intervals(other) - .and_then(|d| self.intervals().checked_add(d)) - .map(|i| SystemTime::from_intervals(i)) + let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?; + Some(SystemTime::from_intervals(intervals)) } - pub fn sub_duration(&self, other: &Duration) -> SystemTime { - let intervals = self.intervals().checked_sub(dur2intervals(other)) - .expect("overflow when subtracting from time"); - SystemTime::from_intervals(intervals) + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?; + Some(SystemTime::from_intervals(intervals)) } } @@ -184,16 +175,12 @@ impl Hash for SystemTime { } } -fn checked_dur2intervals(d: &Duration) -> Option { - d.as_secs() - .checked_mul(INTERVALS_PER_SEC) - .and_then(|i| i.checked_add(d.subsec_nanos() as u64 / 100)) - .and_then(|i| i.try_into().ok()) -} - -fn dur2intervals(d: &Duration) -> i64 { - checked_dur2intervals(d) - .expect("overflow when converting duration to intervals") +fn checked_dur2intervals(dur: &Duration) -> Option { + dur.as_secs() + .checked_mul(INTERVALS_PER_SEC)? + .checked_add(dur.subsec_nanos() as u64 / 100)? + .try_into() + .ok() } fn intervals2dur(intervals: u64) -> Duration { diff --git a/src/libstd/sys_common/condvar.rs b/src/libstd/sys_common/condvar.rs index 16bf0803a8dfe..b6f29dd5fc3d3 100644 --- a/src/libstd/sys_common/condvar.rs +++ b/src/libstd/sys_common/condvar.rs @@ -25,7 +25,6 @@ impl Condvar { /// /// Behavior is undefined if the condition variable is moved after it is /// first used with any of the functions below. - #[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Condvar { Condvar(imp::Condvar::new()) } /// Prepares the condition variable for use. diff --git a/src/libstd/sys_common/mutex.rs b/src/libstd/sys_common/mutex.rs index 8768423763898..c6d531c7a1ac5 100644 --- a/src/libstd/sys_common/mutex.rs +++ b/src/libstd/sys_common/mutex.rs @@ -27,7 +27,6 @@ impl Mutex { /// Also, until `init` is called, behavior is undefined if this /// mutex is ever used reentrantly, i.e., `raw_lock` or `try_lock` /// are called by the thread currently holding the lock. - #[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Mutex { Mutex(imp::Mutex::new()) } /// Prepare the mutex for use. diff --git a/src/libstd/sys_common/rwlock.rs b/src/libstd/sys_common/rwlock.rs index a430c254d3c58..71a4f01ec4cab 100644 --- a/src/libstd/sys_common/rwlock.rs +++ b/src/libstd/sys_common/rwlock.rs @@ -22,7 +22,6 @@ impl RWLock { /// /// Behavior is undefined if the reader-writer lock is moved after it is /// first used with any of the functions below. - #[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> RWLock { RWLock(imp::RWLock::new()) } /// Acquires shared access to the underlying lock, blocking the current diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 667810485ee39..63cede79e4843 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -208,6 +208,22 @@ impl Instant { pub fn elapsed(&self) -> Duration { Instant::now() - *self } + + /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as + /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` + /// otherwise. + #[unstable(feature = "time_checked_add", issue = "55940")] + pub fn checked_add(&self, duration: Duration) -> Option { + self.0.checked_add_duration(&duration).map(|t| Instant(t)) + } + + /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as + /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` + /// otherwise. + #[unstable(feature = "time_checked_add", issue = "55940")] + pub fn checked_sub(&self, duration: Duration) -> Option { + self.0.checked_sub_duration(&duration).map(|t| Instant(t)) + } } #[stable(feature = "time2", since = "1.8.0")] @@ -215,7 +231,8 @@ impl Add for Instant { type Output = Instant; fn add(self, other: Duration) -> Instant { - Instant(self.0.add_duration(&other)) + self.checked_add(other) + .expect("overflow when adding duration to instant") } } @@ -231,7 +248,8 @@ impl Sub for Instant { type Output = Instant; fn sub(self, other: Duration) -> Instant { - Instant(self.0.sub_duration(&other)) + self.checked_sub(other) + .expect("overflow when subtracting duration from instant") } } @@ -365,6 +383,14 @@ impl SystemTime { pub fn checked_add(&self, duration: Duration) -> Option { self.0.checked_add_duration(&duration).map(|t| SystemTime(t)) } + + /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as + /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` + /// otherwise. + #[unstable(feature = "time_checked_add", issue = "55940")] + pub fn checked_sub(&self, duration: Duration) -> Option { + self.0.checked_sub_duration(&duration).map(|t| SystemTime(t)) + } } #[stable(feature = "time2", since = "1.8.0")] @@ -372,7 +398,8 @@ impl Add for SystemTime { type Output = SystemTime; fn add(self, dur: Duration) -> SystemTime { - SystemTime(self.0.add_duration(&dur)) + self.checked_add(dur) + .expect("overflow when adding duration to instant") } } @@ -388,7 +415,8 @@ impl Sub for SystemTime { type Output = SystemTime; fn sub(self, dur: Duration) -> SystemTime { - SystemTime(self.0.sub_duration(&dur)) + self.checked_sub(dur) + .expect("overflow when subtracting duration from instant") } } @@ -521,6 +549,20 @@ mod tests { let second = Duration::new(1, 0); assert_almost_eq!(a - second + second, a); + assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); + + // checked_add_duration will not panic on overflow + let mut maybe_t = Some(Instant::now()); + let max_duration = Duration::from_secs(u64::max_value()); + // in case `Instant` can store `>= now + max_duration`. + for _ in 0..2 { + maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); + } + assert_eq!(maybe_t, None); + + // checked_add_duration calculates the right time and will work for another year + let year = Duration::from_secs(60 * 60 * 24 * 365); + assert_eq!(a + year, a.checked_add(year).unwrap()); } #[test] @@ -557,6 +599,7 @@ mod tests { .duration(), second); assert_almost_eq!(a - second + second, a); + assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); // A difference of 80 and 800 years cannot fit inside a 32-bit time_t if !(cfg!(unix) && ::mem::size_of::<::libc::time_t>() <= 4) { 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/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index eb71003d3d0cf..10c451e1f8199 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId}; use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId}; use source_map::{SourceMap, FilePathMapping}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; -use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; +use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; use feature_gate::UnstableFeatures; use parse::parser::Parser; use ptr::P; @@ -192,6 +192,14 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> source_file_to_parser(sess, file_to_source_file(sess, path, None)) } +/// Create a new parser, returning buffered diagnostics if the file doesn't +/// exist or from lexing the initial token stream. +pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) + -> Result, Vec> { + let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?; + maybe_source_file_to_parser(sess, file) +} + /// Given a session, a crate config, a path, and a span, add /// the file at the given path to the source_map, and return a parser. /// On an error, use the given span as the source of the problem. @@ -236,18 +244,31 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec) -> Parser { // base abstractions +/// Given a session and a path and an optional span (for error reporting), +/// add the path to the session's source_map and return the new source_file or +/// error when a file can't be read. +fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) + -> Result, Diagnostic> { + sess.source_map().load_file(path) + .map_err(|e| { + let msg = format!("couldn't read {}: {}", path.display(), e); + let mut diag = Diagnostic::new(Level::Fatal, &msg); + if let Some(sp) = spanopt { + diag.set_span(sp); + } + diag + }) +} + /// Given a session and a path and an optional span (for error reporting), /// add the path to the session's source_map and return the new source_file. fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) -> Lrc { - match sess.source_map().load_file(path) { + match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, - Err(e) => { - let msg = format!("couldn't read {}: {}", path.display(), e); - match spanopt { - Some(sp) => sess.span_diagnostic.span_fatal(sp, &msg).raise(), - None => sess.span_diagnostic.fatal(&msg).raise() - } + Err(d) => { + DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit(); + FatalError.raise(); } } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 8e4d3c0166bb2..ed7466574596f 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -207,6 +207,10 @@ pub enum Token { Eof, } +// `Token` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::() == 16); + impl Token { pub fn interpolated(nt: Nonterminal) -> Token { Token::Interpolated(Lrc::new((nt, LazyTokenStream::new()))) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 8b7ffa499cd71..9aafb9fc549fc 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -24,10 +24,13 @@ #![feature(nll)] #![feature(non_exhaustive)] #![feature(optin_builtin_traits)] +#![feature(rustc_attrs)] #![feature(specialization)] +#![feature(step_trait)] #![cfg_attr(not(stage0), feature(stdsimd))] extern crate arena; +#[macro_use] extern crate rustc_data_structures; #[macro_use] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 05c53878e7004..3d87134511e72 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -14,6 +14,7 @@ use arena::DroplessArena; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::indexed_vec::Idx; use serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; @@ -143,9 +144,18 @@ impl Decodable for Ident { } } -/// A symbol is an interned or gensymed string. +/// A symbol is an interned or gensymed string. The use of newtype_index! means +/// that Option only takes up 4 bytes, because newtype_index! reserves +/// the last 256 values for tagging purposes. +/// +/// Note that Symbol cannot be a newtype_index! directly because it implements +/// fmt::Debug, Encodable, and Decodable in special ways. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Symbol(u32); +pub struct Symbol(SymbolIndex); + +newtype_index! { + pub struct SymbolIndex { .. } +} // The interner is pointed to by a thread local value which is only set on the main thread // with parallelization is disabled. So we don't allow `Symbol` to transfer between threads @@ -156,6 +166,10 @@ impl !Send for Symbol { } impl !Sync for Symbol { } impl Symbol { + const fn new(n: u32) -> Self { + Symbol(SymbolIndex::from_u32_const(n)) + } + /// Maps a string to its interned representation. pub fn intern(string: &str) -> Self { with_interner(|interner| interner.intern(string)) @@ -189,7 +203,7 @@ impl Symbol { } pub fn as_u32(self) -> u32 { - self.0 + self.0.as_u32() } } @@ -197,7 +211,7 @@ impl fmt::Debug for Symbol { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let is_gensymed = with_interner(|interner| interner.is_gensymed(*self)); if is_gensymed { - write!(f, "{}({})", self, self.0) + write!(f, "{}({:?})", self, self.0) } else { write!(f, "{}", self) } @@ -229,6 +243,9 @@ impl> PartialEq for Symbol { } // The `&'static str`s in this type actually point into the arena. +// +// Note that normal symbols are indexed upward from 0, and gensyms are indexed +// downward from SymbolIndex::MAX_AS_U32. #[derive(Default)] pub struct Interner { arena: DroplessArena, @@ -243,7 +260,7 @@ impl Interner { for &string in init { if string == "" { // We can't allocate empty strings in the arena, so handle this here. - let name = Symbol(this.strings.len() as u32); + let name = Symbol::new(this.strings.len() as u32); this.names.insert("", name); this.strings.push(""); } else { @@ -258,7 +275,7 @@ impl Interner { return name; } - let name = Symbol(self.strings.len() as u32); + let name = Symbol::new(self.strings.len() as u32); // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be // UTF-8. @@ -276,10 +293,10 @@ impl Interner { } pub fn interned(&self, symbol: Symbol) -> Symbol { - if (symbol.0 as usize) < self.strings.len() { + if (symbol.0.as_usize()) < self.strings.len() { symbol } else { - self.interned(self.gensyms[(!0 - symbol.0) as usize]) + self.interned(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]) } } @@ -290,17 +307,17 @@ impl Interner { fn gensymed(&mut self, symbol: Symbol) -> Symbol { self.gensyms.push(symbol); - Symbol(!0 - self.gensyms.len() as u32 + 1) + Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1) } fn is_gensymed(&mut self, symbol: Symbol) -> bool { - symbol.0 as usize >= self.strings.len() + symbol.0.as_usize() >= self.strings.len() } pub fn get(&self, symbol: Symbol) -> &str { - match self.strings.get(symbol.0 as usize) { + match self.strings.get(symbol.0.as_usize()) { Some(string) => string, - None => self.get(self.gensyms[(!0 - symbol.0) as usize]), + None => self.get(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]), } } } @@ -324,7 +341,7 @@ macro_rules! declare_keywords {( $( #[allow(non_upper_case_globals)] pub const $konst: Keyword = Keyword { - ident: Ident::with_empty_ctxt(super::Symbol($index)) + ident: Ident::with_empty_ctxt(super::Symbol::new($index)) }; )* @@ -709,19 +726,19 @@ mod tests { fn interner_tests() { let mut i: Interner = Interner::default(); // first one is zero: - assert_eq!(i.intern("dog"), Symbol(0)); + assert_eq!(i.intern("dog"), Symbol::new(0)); // re-use gets the same entry: - assert_eq!(i.intern("dog"), Symbol(0)); + assert_eq!(i.intern("dog"), Symbol::new(0)); // different string gets a different #: - assert_eq!(i.intern("cat"), Symbol(1)); - assert_eq!(i.intern("cat"), Symbol(1)); + assert_eq!(i.intern("cat"), Symbol::new(1)); + assert_eq!(i.intern("cat"), Symbol::new(1)); // dog is still at zero - assert_eq!(i.intern("dog"), Symbol(0)); - assert_eq!(i.gensym("zebra"), Symbol(4294967295)); - // gensym of same string gets new number : - assert_eq!(i.gensym("zebra"), Symbol(4294967294)); + assert_eq!(i.intern("dog"), Symbol::new(0)); + assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32)); + // gensym of same string gets new number: + assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32 - 1)); // gensym of *existing* string gets new number: - assert_eq!(i.gensym("dog"), Symbol(4294967293)); + assert_eq!(i.gensym("dog"), Symbol::new(SymbolIndex::MAX_AS_U32 - 2)); } #[test] diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs index 8a64d7437d84d..24a4b2b1b054f 100644 --- a/src/test/codegen/simd-intrinsic-generic-select.rs +++ b/src/test/codegen/simd-intrinsic-generic-select.rs @@ -19,12 +19,17 @@ #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x4(pub f32, pub f32, pub f32, pub f32); +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct b8x4(pub i8, pub i8, pub i8, pub i8); extern "platform-intrinsic" { fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(x: T, a: U, b: U) -> U; } // CHECK-LABEL: @select @@ -33,3 +38,10 @@ pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { // CHECK: select <4 x i1> simd_select(m, a, b) } + +// CHECK-LABEL: @select_bitmask +#[no_mangle] +pub unsafe fn select_bitmask(m: i8, a: f32x8, b: f32x8) -> f32x8 { + // CHECK: select <8 x i1> + simd_select_bitmask(m, a, b) +} 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/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index a51be370aa44b..350b30d2cc1cd 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -13,7 +13,11 @@ // ignore-freebsd: gdb package too new // ignore-android: FIXME(#10381) // compile-flags:-g -// min-gdb-version 7.7 + +// The pretty printers being tested here require the patch from +// https://sourceware.org/bugzilla/show_bug.cgi?id=21763 +// min-gdb-version 8.1 + // min-lldb-version: 310 // === GDB TESTS =================================================================================== diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs index 590a2990270dc..74b99ca495081 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs +++ b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs @@ -26,6 +26,10 @@ struct i32x4(pub i32, pub i32, pub i32, pub i32); #[derive(Copy, Clone, PartialEq, Debug)] struct u32x4(pub u32, pub u32, pub u32, pub u32); +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32); + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] struct f32x4(pub f32, pub f32, pub f32, pub f32); @@ -36,6 +40,7 @@ struct b8x4(pub i8, pub i8, pub i8, pub i8); extern "platform-intrinsic" { fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(x: T, a: U, b: U) -> U; } fn main() { @@ -146,4 +151,29 @@ fn main() { let e = b8x4(t, f, t, t); assert_eq!(r, e); } + + unsafe { + let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7); + let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15); + + let r: u32x8 = simd_select_bitmask(0u8, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0xffu8, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b); + let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15); + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b); + let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7); + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b); + let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7); + assert_eq!(r, e); + } } 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/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/pattern/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs new file mode 100644 index 0000000000000..ff065882d96e2 --- /dev/null +++ b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + let -2147483648..=2147483647 = 1; + let 0..=255 = 0u8; + let -128..=127 = 0i8; + let '\u{0000}'..='\u{10FFFF}' = 'v'; +} 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/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs index d74d6815d5f5e..2a2d35e7bd922 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -33,6 +33,7 @@ struct b8x8(pub i8, pub i8, pub i8, pub i8, extern "platform-intrinsic" { fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(x: T, a: U, b: U) -> U; } fn main() { @@ -52,5 +53,14 @@ fn main() { simd_select(z, z, z); //~^ ERROR mask element type is `f32`, expected `i_` + + simd_select_bitmask(0u8, x, x); + //~^ ERROR mask length `8` != other vector length `4` + + simd_select_bitmask(0.0f32, x, x); + //~^ ERROR `f32` is not an integral type + + simd_select_bitmask("x", x, x); + //~^ ERROR `&str` is not an integral type } } diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr index 61e42027039dd..584f3d539213b 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr @@ -1,21 +1,39 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4` - --> $DIR/simd-intrinsic-generic-select.rs:47:9 + --> $DIR/simd-intrinsic-generic-select.rs:48:9 | LL | simd_select(m8, x, x); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_` - --> $DIR/simd-intrinsic-generic-select.rs:50:9 + --> $DIR/simd-intrinsic-generic-select.rs:51:9 | LL | simd_select(x, x, x); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_` - --> $DIR/simd-intrinsic-generic-select.rs:53:9 + --> $DIR/simd-intrinsic-generic-select.rs:54:9 | LL | simd_select(z, z, z); | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4` + --> $DIR/simd-intrinsic-generic-select.rs:57:9 + | +LL | simd_select_bitmask(0u8, x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type + --> $DIR/simd-intrinsic-generic-select.rs:60:9 + | +LL | simd_select_bitmask(0.0f32, x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type + --> $DIR/simd-intrinsic-generic-select.rs:63:9 + | +LL | simd_select_bitmask("x", x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0511`. 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=(',', ': '))