diff --git a/Cargo.lock b/Cargo.lock index 39ecc880097e3..27f7f59165b1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,7 +251,7 @@ dependencies = [ "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1009,7 +1009,7 @@ dependencies = [ [[package]] name = "glob" -version = "0.2.11" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4083,7 +4083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" diff --git a/RELEASES.md b/RELEASES.md index 4cda02c5c2ebe..a49e072e9eaa7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -110,8 +110,11 @@ Compatibility Notes methods instead. - The `Error::cause` method has been deprecated in favor of `Error::source` which supports downcasting. +- [Libtest no longer creates a new thread for each test when + `--test-threads=1`. It also runs the tests in deterministic order][56243] [55982]: https://github.com/rust-lang/rust/pull/55982/ +[56243]: https://github.com/rust-lang/rust/pull/56243 [56303]: https://github.com/rust-lang/rust/pull/56303/ [56351]: https://github.com/rust-lang/rust/pull/56351/ [56362]: https://github.com/rust-lang/rust/pull/56362 diff --git a/appveyor.yml b/appveyor.yml index d70ad54b1c812..2abf723de496e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,7 @@ environment: + # This is required for at least an AArch64 compiler in one image, and is also + # going to soon be required for compiling LLVM. + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview # By default schannel checks revocation of certificates unlike some other SSL # backends, but we've historically had problems on CI where a revocation @@ -81,7 +84,6 @@ environment: DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 CI_JOB_NAME: dist-x86_64-msvc - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview - RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 36beec3a944a0..085f243785cbe 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -35,7 +35,7 @@ fn main() { .arg("--cfg") .arg("dox") .arg("--sysroot") - .arg(sysroot) + .arg(&sysroot) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); @@ -72,7 +72,13 @@ fn main() { } if verbose > 1 { - eprintln!("rustdoc command: {:?}", cmd); + eprintln!( + "rustdoc command: {:?}={:?} {:?}", + bootstrap::util::dylib_path_var(), + env::join_paths(&dylib_path).unwrap(), + cmd, + ); + eprintln!("sysroot: {:?}", sysroot); eprintln!("libdir: {:?}", libdir); } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1a36cb45d269f..fd5038ccb9528 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -374,6 +374,7 @@ impl<'a> Builder<'a> { test::MirOpt, test::Codegen, test::CodegenUnits, + test::Assembly, test::Incremental, test::Debuginfo, test::UiFullDeps, @@ -408,12 +409,11 @@ impl<'a> Builder<'a> { test::RustdocJSStd, test::RustdocJSNotStd, test::RustdocTheme, + test::RustdocUi, // Run bootstrap close to the end as it's unlikely to fail test::Bootstrap, // Run run-make last, since these won't pass without make on Windows test::RunMake, - test::RustdocUi, - test::Assembly, ), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!( diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 9317a40545eac..976b30a55c94b 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -241,6 +241,8 @@ pub struct Build { clippy_info: channel::GitInfo, miri_info: channel::GitInfo, rustfmt_info: channel::GitInfo, + in_tree_llvm_info: channel::GitInfo, + emscripten_llvm_info: channel::GitInfo, local_rebuild: bool, fail_fast: bool, doc_tests: DocTests, @@ -363,6 +365,8 @@ impl Build { let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy")); let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri")); let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt")); + let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project")); + let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten")); let mut build = Build { initial_rustc: config.initial_rustc.clone(), @@ -386,6 +390,8 @@ impl Build { clippy_info, miri_info, rustfmt_info, + in_tree_llvm_info, + emscripten_llvm_info, cc: HashMap::new(), cxx: HashMap::new(), ar: HashMap::new(), diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 1c27cf3909b1a..07be27c2f5a02 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -48,7 +48,6 @@ check: $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) check-aux: $(Q)$(BOOTSTRAP) test \ - src/test/pretty \ src/test/run-pass/pretty \ src/test/run-fail/pretty \ src/test/run-pass-valgrind/pretty \ diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d78670cfe515a..3babbc9e10231 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -18,6 +18,7 @@ use build_helper::output; use cmake; use cc; +use crate::channel; use crate::util::{self, exe}; use build_helper::up_to_date; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -231,7 +232,26 @@ impl Step for Llvm { } if let Some(ref suffix) = builder.config.llvm_version_suffix { - cfg.define("LLVM_VERSION_SUFFIX", suffix); + // Allow version-suffix="" to not define a version suffix at all. + if !suffix.is_empty() { + cfg.define("LLVM_VERSION_SUFFIX", suffix); + } + } else { + let mut default_suffix = format!( + "-rust-{}-{}", + channel::CFG_RELEASE_NUM, + builder.config.channel, + ); + let llvm_info = if self.emscripten { + &builder.emscripten_llvm_info + } else { + &builder.in_tree_llvm_info + }; + if let Some(sha) = llvm_info.sha_short() { + default_suffix.push_str("-"); + default_suffix.push_str(sha); + } + cfg.define("LLVM_VERSION_SUFFIX", default_suffix); } if let Some(ref linker) = builder.config.llvm_use_linker { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index cb66eb238b340..b348ed980f425 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -897,12 +897,10 @@ host_test!(Rustdoc { suite: "rustdoc" }); -test!(Pretty { +host_test!(Pretty { path: "src/test/pretty", mode: "pretty", - suite: "pretty", - default: false, - host: true + suite: "pretty" }); test!(RunPassPretty { path: "src/test/run-pass/pretty", @@ -999,11 +997,7 @@ impl Step for Compiletest { }); } - if suite.ends_with("fulldeps") || - // FIXME: Does pretty need librustc compiled? Note that there are - // fulldeps test suites with mode = pretty as well. - mode == "pretty" - { + if suite.ends_with("fulldeps") { builder.ensure(compile::Rustc { compiler, target }); } diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 06f8a2fbba836..560df2f3a5700 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ make \ file \ + wget \ curl \ ca-certificates \ python2.7 \ @@ -18,19 +19,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ WORKDIR /build/ -COPY scripts/musl.sh /build/ +COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well -RUN CC=gcc \ - CFLAGS="-Wa,-mrelax-relocations=no" \ - CXX=g++ \ +RUN CFLAGS="-Wa,-mrelax-relocations=no" \ CXXFLAGS="-Wa,-mrelax-relocations=no" \ - bash musl.sh x86_64 && rm -rf /build + bash musl-toolchain.sh x86_64 && rm -rf build COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ - --musl-root-x86_64=/musl-x86_64 \ + --musl-root-x86_64=/usr/local/x86_64-linux-musl \ --enable-extended \ --disable-docs @@ -41,6 +40,12 @@ ENV RUST_CONFIGURE_ARGS \ # See: https://github.com/rust-lang/rust/issues/34978 ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no -ENV SCRIPT \ - python2.7 ../x.py test --target x86_64-unknown-linux-musl && \ - python2.7 ../x.py dist --target x86_64-unknown-linux-musl +ENV HOSTS=x86_64-unknown-linux-musl \ + CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ + CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ + +# Musl defaults to static libs but we need them to be dynamic for host toolchain. +# The toolchain will produce static libs by default. +ENV RUSTFLAGS="-C target-feature=-crt-static" + +ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh new file mode 100644 index 0000000000000..95b7c2869c91f --- /dev/null +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -0,0 +1,70 @@ +# This script runs `musl-cross-make` to prepare C toolchain (Binutils, GCC, musl itself) +# and builds static libunwind that we distribute for static target. +# +# Versions of the toolchain components are configurable in `musl-cross-make/Makefile` and +# musl unlike GLIBC is forward compatible so upgrading it shouldn't break old distributions. +# Right now we have: Binutils 2.27, GCC 6.3.0, musl 1.1.18 +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + rm /tmp/build.log + set -x +} + +ARCH=$1 +TARGET=$ARCH-linux-musl + +OUTPUT=/usr/local +shift + +git clone https://github.com/richfelker/musl-cross-make -b v0.9.7 +cd musl-cross-make + +hide_output make -j$(nproc) TARGET=$TARGET +hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT + +cd - + +# Install musl library to make binaries executable +ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1 +echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path + + +export CC=$TARGET-gcc +export CXX=$TARGET-g++ + +LLVM=70 + +# may have been downloaded in a previous run +if [ ! -d libunwind-release_$LLVM ]; then + curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf - + curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf - +fi + +# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089 +mkdir libunwind-build +cd libunwind-build +cmake ../libunwind-release_$LLVM \ + -DLLVM_PATH=/build/llvm-release_$LLVM \ + -DLIBUNWIND_ENABLE_SHARED=0 \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_C_FLAGS="$CFLAGS" \ + -DCMAKE_CXX_FLAGS="$CXXFLAGS" + +hide_output make -j$(nproc) +cp lib/libunwind.a $OUTPUT/$TARGET/lib +cd - && rm -rf libunwind-build + diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index 7891e9f625a6a..611a24a69bd37 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -11,7 +11,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ - xz-utils + xz-utils \ + wget \ + patch # FIXME: build the `ptx-linker` instead. RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.2/rust-ptx-linker.linux64.tar.gz | \ @@ -20,10 +22,16 @@ RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-a RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \ tar -xJ +WORKDIR /build/ +COPY scripts/musl-toolchain.sh /build/ +RUN bash musl-toolchain.sh x86_64 && rm -rf build +WORKDIR / + COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ + --musl-root-x86_64=/usr/local/x86_64-linux-musl \ --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \ --set rust.lld @@ -48,4 +56,9 @@ ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \ src/test/run-make \ src/test/assembly -ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT +ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ + CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ + CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ +ENV MUSL_SCRIPT python2.7 /checkout/x.py test --target $MUSL_TARGETS + +ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs deleted file mode 100644 index 6767cf89f73ba..0000000000000 --- a/src/liballoc/prelude.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! The alloc Prelude -//! -//! The purpose of this module is to alleviate imports of commonly-used -//! items of the `alloc` crate by adding a glob import to the top of modules: -//! -//! ``` -//! # #![allow(unused_imports)] -//! # #![feature(alloc)] -//! extern crate alloc; -//! use alloc::prelude::*; -//! ``` - -#![unstable(feature = "alloc", issue = "27783")] - -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs new file mode 100644 index 0000000000000..33cc51d173203 --- /dev/null +++ b/src/liballoc/prelude/mod.rs @@ -0,0 +1,16 @@ +//! The alloc Prelude +//! +//! The purpose of this module is to alleviate imports of commonly-used +//! items of the `alloc` crate by adding a glob import to the top of modules: +//! +//! ``` +//! # #![allow(unused_imports)] +//! # #![feature(alloc)] +//! #![feature(alloc_prelude)] +//! extern crate alloc; +//! use alloc::prelude::v1::*; +//! ``` + +#![unstable(feature = "alloc_prelude", issue = "58935")] + +pub mod v1; diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs new file mode 100644 index 0000000000000..b6b01395ad632 --- /dev/null +++ b/src/liballoc/prelude/v1.rs @@ -0,0 +1,11 @@ +//! The first version of the prelude of `alloc` crate. +//! +//! See the [module-level documentation](../index.html) for more. + +#![unstable(feature = "alloc_prelude", issue = "58935")] + +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac42..0930f8dacd494 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support panics nor entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index f14750089c956..844afe870766b 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_equal_excluded() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(2), Excluded(2))); @@ -234,7 +233,6 @@ fn test_range_equal_excluded() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_1() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Included(2))); @@ -242,7 +240,6 @@ fn test_range_backwards_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_2() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Excluded(2))); @@ -250,7 +247,6 @@ fn test_range_backwards_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_3() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Included(2))); @@ -258,7 +254,6 @@ fn test_range_backwards_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_4() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Excluded(2))); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index feba46b0fad78..b54c128a0249a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -258,7 +258,6 @@ fn test_swap_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -632,7 +631,6 @@ fn test_insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -657,7 +655,6 @@ fn test_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -939,7 +936,6 @@ fn test_windowsator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_windowsator_0() { let v = &[1, 2, 3, 4]; let _it = v.windows(0); @@ -964,7 +960,6 @@ fn test_chunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks(0); @@ -989,7 +984,6 @@ fn test_chunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks_exact(0); @@ -1014,7 +1008,6 @@ fn test_rchunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks(0); @@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks_exact(0); @@ -1092,7 +1084,6 @@ fn test_vec_default() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(!0); @@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(!0); @@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); @@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_exact_mut(0); @@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_mut(0); @@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_exact_mut(0); @@ -1411,7 +1397,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1462,6 @@ fn test_copy_from_slice() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_longer() { let src = [0, 1, 2, 3]; let mut dst = [0; 5]; @@ -1485,7 +1470,6 @@ fn test_copy_from_slice_dst_longer() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_shorter() { let src = [0, 1, 2, 3]; let mut dst = [0; 3]; @@ -1605,7 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..b197516403f78 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -7,7 +7,7 @@ fn test_le() { assert!("" <= ""); assert!("" <= "foo"); assert!("foo" <= "foo"); - assert!("foo" != "bar"); + assert_ne!("foo", "bar"); } #[test] @@ -351,7 +351,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of bounds")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!("abc", 0..5, "abc"); } @@ -361,7 +360,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!("abc", 0..2, "abc"); } @@ -409,7 +407,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v: String = $data.into(); let v: &str = &v; @@ -418,7 +415,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v: String = $data.into(); let v: &mut str = &mut v; @@ -514,7 +510,6 @@ mod slice_index { #[test] #[should_panic] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail() { &"中华Việt Nam"[0..2]; } @@ -666,14 +661,12 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] #[should_panic(expected="luctus, im`[...]")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -894,7 +885,6 @@ fn test_as_bytes() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -984,7 +974,6 @@ fn test_split_at_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e93d84fe3b97..7e75b8c4f28c8 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -231,7 +231,6 @@ fn test_split_off_empty() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_past_end() { let orig = "Hello, world!"; let mut split = String::from(orig); @@ -240,7 +239,6 @@ fn test_split_off_past_end() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_mid_char() { let mut orig = String::from("山"); orig.split_off(1); @@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_truncate_split_codepoint() { let mut s = String::from("\u{FC}"); // ü s.truncate(1); @@ -324,7 +321,6 @@ fn remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn remove_bad() { "ศ".to_string().remove(1); } @@ -360,13 +356,11 @@ fn insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad2() { "ệ".to_string().insert(1, 't'); } @@ -447,7 +441,6 @@ fn test_replace_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); @@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); @@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 6e4ca1d90e642..545332bcd6a2f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -368,7 +368,6 @@ fn test_vec_truncate_drop() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -392,7 +391,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let vec = vec![1, 2, 3]; let _ = vec[3]; @@ -400,7 +398,6 @@ fn test_index_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_1() { let x = vec![1, 2, 3, 4, 5]; &x[!0..]; @@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_2() { let x = vec![1, 2, 3, 4, 5]; &x[..6]; @@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_3() { let x = vec![1, 2, 3, 4, 5]; &x[!0..4]; @@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_4() { let x = vec![1, 2, 3, 4, 5]; &x[1..6]; @@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_5() { let x = vec![1, 2, 3, 4, 5]; &x[3..2]; @@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_empty() { let mut vec = Vec::::new(); vec.swap_remove(0); @@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..6); @@ -585,7 +576,6 @@ fn test_drain_max_vec_size() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..=5); @@ -615,7 +605,6 @@ fn test_splice_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; @@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 16ddc1444fcf9..e0fe10a55f55c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -108,7 +108,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 94bed3708369a..7de94d25c7618 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -567,6 +567,32 @@ pub trait Ord: Eq + PartialOrd { where Self: Sized { if self <= other { self } else { other } } + + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this will return self. Panics if min > max. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp)] + /// + /// assert!((-3).clamp(-2, 1) == -2); + /// assert!(0.clamp(-2, 1) == 0); + /// assert!(2.clamp(-2, 1) == 1); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + fn clamp(self, min: Self, max: Self) -> Self + where Self: Sized { + assert!(min <= max); + if self < min { + min + } + else if self > max { + max + } else { + self + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index d88793f2801e7..5cc9c25c21e0f 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -79,9 +79,9 @@ impl fmt::Debug for VaListImpl { all supported platforms", issue = "44930")] struct VaListImpl { - stack: *mut (), - gr_top: *mut (), - vr_top: *mut (), + stack: *mut c_void, + gr_top: *mut c_void, + vr_top: *mut c_void, gr_offs: i32, vr_offs: i32, } @@ -98,8 +98,8 @@ struct VaListImpl { gpr: u8, fpr: u8, reserved: u16, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// x86_64 ABI implementation of a `va_list`. @@ -113,8 +113,8 @@ struct VaListImpl { struct VaListImpl { gp_offset: i32, fp_offset: i32, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// A wrapper for a `va_list` diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index d4ad22c16bbfa..cccd51b577930 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1198,7 +1198,7 @@ impl Peekable { } } -/// An iterator that rejects elements while `predicate` is true. +/// An iterator that rejects elements while `predicate` returns `true`. /// /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. @@ -1286,7 +1286,7 @@ impl Iterator for SkipWhile impl FusedIterator for SkipWhile where I: FusedIterator, P: FnMut(&I::Item) -> bool {} -/// An iterator that only accepts elements while `predicate` is true. +/// An iterator that only accepts elements while `predicate` returns `true`. /// /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 74ff7f41d76fa..ffc24df3ed42e 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -39,8 +39,7 @@ unsafe impl TrustedLen for Repeat {} /// Creates a new iterator that endlessly repeats a single element. /// -/// The `repeat()` function repeats a single value over and over and over and -/// over and over and 🔁. +/// The `repeat()` function repeats a single value over and over again. /// /// Infinite iterators like `repeat()` are often used with adapters like /// [`take`], in order to make them finite. @@ -128,8 +127,7 @@ unsafe impl A> TrustedLen for RepeatWith {} /// Creates a new iterator that repeats elements of type `A` endlessly by /// applying the provided closure, the repeater, `F: FnMut() -> A`. /// -/// The `repeat_with()` function calls the repeater over and over and over and -/// over and over and 🔁. +/// The `repeat_with()` function calls the repeater over and over again. /// /// Infinite iterators like `repeat_with()` are often used with adapters like /// [`take`], in order to make them finite. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 90e84d0b28c3b..3d2fcdc979377 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1111,11 +1111,12 @@ impl DerefMut for ManuallyDrop { /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. +// // FIXME before stabilizing, explain how to initialize a struct field-by-field. #[allow(missing_debug_implementations)] #[unstable(feature = "maybe_uninit", issue = "53491")] #[derive(Copy)] -// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`. +// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`. pub union MaybeUninit { uninit: (), value: ManuallyDrop, @@ -1125,13 +1126,13 @@ pub union MaybeUninit { impl Clone for MaybeUninit { #[inline(always)] fn clone(&self) -> Self { - // Not calling T::clone(), we cannot know if we are initialized enough for that. + // Not calling `T::clone()`, we cannot know if we are initialized enough for that. *self } } impl MaybeUninit { - /// Create a new `MaybeUninit` initialized with the given value. + /// Creates a new `MaybeUninit` initialized with the given value. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. @@ -1239,6 +1240,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] @@ -1277,6 +1279,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index 3b57bb7544b35..a83134a6b2ca4 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -326,7 +326,7 @@ pub fn algorithm_m(f: &Big, e: i16) -> T { round_by_remainder(v, rem, q, z) } -/// Skip over most Algorithm M iterations by checking the bit length. +/// Skips over most Algorithm M iterations by checking the bit length. fn quick_start(u: &mut Big, v: &mut Big, k: &mut i16) { // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v). // The estimate is off by at most 1, but always an under-estimate, so the error on log(u) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 47ea5aa5ff000..d62cdae0688be 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) { } } -/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and -/// Algorithm M will compute while working on the given decimal. +/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R +/// and Algorithm M will compute while working on the given decimal. fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { // We don't need to worry too much about overflow here thanks to trivial_cases() and the // parser, which filter out the most extreme inputs for us. @@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { } } -/// Detect obvious overflows and underflows without even looking at the decimal digits. +/// Detects obvious overflows and underflows without even looking at the decimal digits. fn trivial_cases(decimal: &Decimal) -> Option { // There were zeros but they were stripped by simplify() if decimal.integral.is_empty() && decimal.fractional.is_empty() { diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 933f8c1d3f781..f970595452ec9 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult { } } -/// Carve off decimal digits up to the first non-digit character. +/// Carves off decimal digits up to the first non-digit character. fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { let mut i = 0; while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index a3bf783976bbd..a8da31d3e4858 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat; /// /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will /// round to the original value. The range is inclusive only when -/// `inclusive` is true. +/// `inclusive` is `true`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Decoded { /// The scaled mantissa. diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index f9b46a12f7fef..defd4247f4ea4 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, } } -/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form -/// with at least given number of significant digits. When `upper` is true, +/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential +/// form with at least the given number of significant digits. When `upper` is `true`, /// the exponent will be prefixed by `E`; otherwise that's `e`. The result is /// stored to the supplied parts array and a slice of written parts is returned. /// /// `min_digits` can be less than the number of actual significant digits in `buf`; /// it will be ignored and full digits will be printed. It is only used to print -/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that -/// it will only print given digits and nothing else. +/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that +/// it will only print the given digits and nothing else. fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { assert!(!buf.is_empty()); @@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static } } -/// Formats given floating point number into the decimal form with at least +/// Formats the given floating point number into the decimal form with at least /// given number of fractional digits. The result is stored to the supplied parts /// array while utilizing given byte buffer as a scratch. `upper` is currently /// unused but left for the future decision to change the case of non-finite values, @@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Formats given floating point number into the decimal form or +/// Formats the given floating point number into the decimal form or /// the exponential form, depending on the resulting exponent. The result is /// stored to the supplied parts array while utilizing given byte buffer /// as a scratch. `upper` is used to determine the case of non-finite values @@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Returns rather crude approximation (upper bound) for the maximum buffer size +/// Returns a rather crude approximation (upper bound) for the maximum buffer size /// calculated from the given decoded exponent. /// /// The exact limit is: diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 81a8d001dd9cb..4f71c8e794954 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -95,8 +95,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..5).contains(&2)); @@ -112,7 +110,7 @@ impl> Range { /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -175,7 +173,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -196,8 +194,6 @@ impl> RangeFrom { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..).contains(&2)); @@ -208,7 +204,7 @@ impl> RangeFrom { /// assert!(!(0.0..).contains(&f32::NAN)); /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -280,8 +276,6 @@ impl> RangeTo { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..5).contains(&-1_000_000_000)); @@ -292,7 +286,7 @@ impl> RangeTo { /// assert!(!(..1.0).contains(&f32::NAN)); /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -329,7 +323,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone)] // not Copy -- see #27186 +#[derive(Clone)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { pub(crate) start: Idx, @@ -365,7 +359,8 @@ impl RangeInclusiveEquality for T { impl PartialEq for RangeInclusive { #[inline] fn eq(&self, other: &Self) -> bool { - self.start == other.start && self.end == other.end + self.start == other.start + && self.end == other.end && RangeInclusiveEquality::canonicalized_is_empty(self) == RangeInclusiveEquality::canonicalized_is_empty(other) } @@ -397,7 +392,11 @@ impl RangeInclusive { #[inline] #[rustc_promotable] pub const fn new(start: Idx, end: Idx) -> Self { - Self { start, end, is_empty: None } + Self { + start, + end, + is_empty: None, + } } /// Returns the lower bound of the range (inclusive). @@ -478,8 +477,6 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..=5).contains(&2)); @@ -496,7 +493,7 @@ impl> RangeInclusive { /// assert!(!(0.0..=f32::NAN).contains(&0.0)); /// assert!(!(f32::NAN..=1.0).contains(&1.0)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -609,15 +606,12 @@ impl fmt::Debug for RangeToInclusive { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeToInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..=5).contains(&-1_000_000_000)); @@ -628,7 +622,7 @@ impl> RangeToInclusive { /// assert!(!(..=1.0).contains(&f32::NAN)); /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -730,14 +724,11 @@ pub trait RangeBounds { #[stable(feature = "collections_range", since = "1.28.0")] fn end_bound(&self) -> Bound<&T>; - /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (3..5).contains(&4)); @@ -747,7 +738,7 @@ pub trait RangeBounds { /// assert!(!(0.0..1.0).contains(&f32::NAN)); /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where T: PartialOrd, @@ -757,9 +748,7 @@ pub trait RangeBounds { Included(ref start) => *start <= item, Excluded(ref start) => *start < item, Unbounded => true, - }) - && - (match self.end_bound() { + }) && (match self.end_bound() { Included(ref end) => item <= *end, Excluded(ref end) => item < *end, Unbounded => true, @@ -835,7 +824,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (Included(ref start), _) => Included(start), (Excluded(ref start), _) => Excluded(start), - (Unbounded, _) => Unbounded, + (Unbounded, _) => Unbounded, } } @@ -843,7 +832,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (_, Included(ref end)) => Included(end), (_, Excluded(ref end)) => Excluded(end), - (_, Unbounded) => Unbounded, + (_, Unbounded) => Unbounded, } } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 46dfe28da622c..dfc388409a84b 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -210,7 +210,7 @@ impl Option { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Option` to `Option<&T>`. + /// Converts from `&Option` to `Option<&T>`. /// /// # Examples /// @@ -239,7 +239,7 @@ impl Option { } } - /// Converts from `Option` to `Option<&mut T>`. + /// Converts from `&mut Option` to `Option<&mut T>`. /// /// # Examples /// @@ -881,15 +881,13 @@ impl Option<&T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let x = 12; /// let opt_x = Some(&x); /// assert_eq!(opt_x, Some(&12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&t| t) } @@ -902,15 +900,13 @@ impl Option<&mut T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let mut x = 12; /// let opt_x = Some(&mut x); /// assert_eq!(opt_x, Some(&mut 12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&mut t| t) } diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index fb78f5e5a2384..cf55b6c379d04 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -1,4 +1,4 @@ -//! Types which pin data to its location in memory +//! Types that pin data to its location in memory. //! //! It is sometimes useful to have objects that are guaranteed to not move, //! in the sense that their placement in memory does not change, and can thus be relied upon. diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 2bd6b536301e8..967f7e3e2fe72 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -369,7 +369,7 @@ impl Result { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Result` to `Result<&T, &E>`. + /// Converts from `&Result` to `Result<&T, &E>`. /// /// Produces a new `Result`, containing a reference /// into the original, leaving the original in place. @@ -394,7 +394,7 @@ impl Result { } } - /// Converts from `Result` to `Result<&mut T, &mut E>`. + /// Converts from `&mut Result` to `Result<&mut T, &mut E>`. /// /// # Examples /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 53334adadb856..528281d317be3 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2968,7 +2968,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3143,7 +3143,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3326,7 +3326,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3402,7 +3402,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 21f0a8cea4168..12f812d3bed3e 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -108,7 +108,7 @@ impl Waker { unsafe { (self.waker.vtable.wake)(self.waker.data) } } - /// Returns whether or not this `Waker` and other `Waker` have awaken the same task. + /// Returns `true` if this `Waker` and another `Waker` have awoken the same task. /// /// This function works on a best-effort basis, and may return false even /// when the `Waker`s would awaken the same task. However, if this function diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..7bd7d1874101a 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -5,15 +5,15 @@ use std::mem::drop; #[test] fn smoketest_cell() { let x = Cell::new(10); - assert!(x == Cell::new(10)); - assert!(x.get() == 10); + assert_eq!(x, Cell::new(10)); + assert_eq!(x.get(), 10); x.set(20); - assert!(x == Cell::new(20)); - assert!(x.get() == 20); + assert_eq!(x, Cell::new(20)); + assert_eq!(x.get(), 20); let y = Cell::new((30, 40)); - assert!(y == Cell::new((30, 40))); - assert!(y.get() == (30, 40)); + assert_eq!(y, Cell::new((30, 40))); + assert_eq!(y.get(), (30, 40)); } #[test] @@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn discard_doesnt_unborrow() { let x = RefCell::new(0); let _b = x.borrow(); @@ -350,7 +349,6 @@ fn refcell_ref_coercion() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_swap_borrows() { let x = RefCell::new(0); let _b = x.borrow(); @@ -360,7 +358,6 @@ fn refcell_swap_borrows() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_replace_borrows() { let x = RefCell::new(0); let _b = x.borrow(); diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index a9db9b35d8d80..a3f0b02e2fe33 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); @@ -1442,7 +1441,6 @@ fn test_rposition() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index d002137638977..a50310e195f0d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -1,6 +1,5 @@ #![feature(box_syntax)] #![feature(cell_update)] -#![feature(copied)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index 956c22c998219..b873f1dd0652f 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big; #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_from_u64_overflow() { Big::from_u64(0x1000000); } @@ -20,14 +19,12 @@ fn test_add() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_1() { Big::from_small(1).add(&Big::from_u64(0xffffff)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_2() { Big::from_u64(0xffffff).add(&Big::from_small(1)); } @@ -45,7 +42,6 @@ fn test_add_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_small_overflow() { Big::from_u64(0xffffff).add_small(1); } @@ -61,14 +57,12 @@ fn test_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_1() { Big::from_u64(0x10665).sub(&Big::from_u64(0x10666)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_2() { Big::from_small(0).sub(&Big::from_u64(0x123456)); } @@ -82,7 +76,6 @@ fn test_mul_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_small_overflow() { Big::from_u64(0x800000).mul_small(2); } @@ -101,14 +94,12 @@ fn test_mul_pow2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_1() { Big::from_u64(0x1).mul_pow2(24); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_2() { Big::from_u64(0x123).mul_pow2(16); } @@ -127,14 +118,12 @@ fn test_mul_pow5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_1() { Big::from_small(1).mul_pow5(12); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_2() { Big::from_small(230).mul_pow5(8); } @@ -152,14 +141,12 @@ fn test_mul_digits() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_1() { Big::from_u64(0x800000).mul_digits(&[2]); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_2() { Big::from_u64(0x1000).mul_digits(&[0, 0x10]); } @@ -219,7 +206,6 @@ fn test_get_bit() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_get_bit_out_of_range() { Big::from_small(42).get_bit(24); } diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 5c6ee8f8ba038..4881f79ec248a 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -12,7 +12,7 @@ mod tests { fn test_overflows() { assert!(MAX > 0); assert!(MIN <= 0); - assert!(MIN + MAX + 1 == 0); + assert_eq!(MIN + MAX + 1, 0); } #[test] @@ -22,22 +22,22 @@ mod tests { #[test] fn test_rem_euclid() { - assert!((-1 as $T).rem_euclid(MIN) == MAX); + assert_eq!((-1 as $T).rem_euclid(MIN), MAX); } #[test] pub fn test_abs() { - assert!((1 as $T).abs() == 1 as $T); - assert!((0 as $T).abs() == 0 as $T); - assert!((-1 as $T).abs() == 1 as $T); + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); } #[test] fn test_signum() { - assert!((1 as $T).signum() == 1 as $T); - assert!((0 as $T).signum() == 0 as $T); - assert!((-0 as $T).signum() == 0 as $T); - assert!((-1 as $T).signum() == -1 as $T); + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); } #[test] @@ -58,12 +58,12 @@ mod tests { #[test] fn test_bitwise_operators() { - assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); - assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); - assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); - assert!(0b1110 as $T == (0b0111 as $T).shl(1)); - assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not()); + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); } const A: $T = 0b0101100; @@ -75,17 +75,17 @@ mod tests { #[test] fn test_count_ones() { - assert!(A.count_ones() == 3); - assert!(B.count_ones() == 2); - assert!(C.count_ones() == 5); + assert_eq!(A.count_ones(), 3); + assert_eq!(B.count_ones(), 2); + assert_eq!(C.count_ones(), 5); } #[test] fn test_count_zeros() { let bits = mem::size_of::<$T>() * 8; - assert!(A.count_zeros() == bits as u32 - 3); - assert!(B.count_zeros() == bits as u32 - 2); - assert!(C.count_zeros() == bits as u32 - 5); + assert_eq!(A.count_zeros(), bits as u32 - 3); + assert_eq!(B.count_zeros(), bits as u32 - 2); + assert_eq!(C.count_zeros(), bits as u32 - 5); } #[test] @@ -148,9 +148,9 @@ mod tests { #[test] fn test_signed_checked_div() { - assert!((10 as $T).checked_div(2) == Some(5)); - assert!((5 as $T).checked_div(0) == None); - assert!(isize::MIN.checked_div(-1) == None); + assert_eq!((10 as $T).checked_div(2), Some(5)); + assert_eq!((5 as $T).checked_div(0), None); + assert_eq!(isize::MIN.checked_div(-1), None); } #[test] diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 401644e120d16..78cf07119e729 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -7,11 +7,11 @@ fn test_range() { let r = Range { start: 2, end: 10 }; let mut count = 0; for (i, ri) in r.enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 10); count += 1; } - assert!(count == 8); + assert_eq!(count, 8); } #[test] @@ -19,11 +19,11 @@ fn test_range_from() { let r = RangeFrom { start: 2 }; let mut count = 0; for (i, ri) in r.take(10).enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 12); count += 1; } - assert!(count == 10); + assert_eq!(count, 10); } #[test] diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 87ce2720c5918..b059b134868d9 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,7 +69,6 @@ fn test_option_dance() { } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -130,7 +129,6 @@ fn test_unwrap() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -138,7 +136,6 @@ fn test_unwrap_panic1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index bbc8568517667..1fab07526a07f 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,7 +117,6 @@ fn test_unwrap_or_else() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -139,7 +138,6 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -153,7 +151,6 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 31d16e0e32057..ac9c17a0f7c35 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,7 +782,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -792,7 +791,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -842,7 +840,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v = $data; let v: &[_] = &v; @@ -851,7 +848,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1304,7 +1300,6 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 09aae4583482f..6efd22572dc18 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -107,14 +107,12 @@ fn checked_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad1() { let _ = Duration::new(0, 0) - Duration::new(0, 1); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad2() { let _ = Duration::new(0, 0) - Duration::new(1, 0); } diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 91161ca477e39..ae6d8078fd236 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -21,7 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000; const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; -const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -510,15 +509,34 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.as_float_secs(), 2.7); + /// assert_eq!(dur.as_secs_f64(), 2.7); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub const fn as_float_secs(&self) -> f64 { + pub const fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) } - /// Creates a new `Duration` from the specified number of seconds. + /// Returns the number of seconds contained by this `Duration` as `f32`. + /// + /// The returned value does include the fractional (nanosecond) part of the duration. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.as_secs_f32(), 2.7); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub const fn as_secs_f32(&self) -> f32 { + (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) + } + + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f64`. /// /// # Panics /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. @@ -528,12 +546,14 @@ impl Duration { /// #![feature(duration_float)] /// use std::time::Duration; /// - /// let dur = Duration::from_float_secs(2.7); + /// let dur = Duration::from_secs_f64(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn from_float_secs(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { + const MAX_NANOS_F64: f64 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -551,6 +571,42 @@ impl Duration { } } + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f32`. + /// + /// # Panics + /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::from_secs_f32(2.7); + /// assert_eq!(dur, Duration::new(2, 700_000_000)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn from_secs_f32(secs: f32) -> Duration { + const MAX_NANOS_F32: f32 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; + let nanos = secs * (NANOS_PER_SEC as f32); + if !nanos.is_finite() { + panic!("got non-finite value when converting float to duration"); + } + if nanos >= MAX_NANOS_F32 { + panic!("overflow when converting float to duration"); + } + if nanos < 0.0 { + panic!("underflow when converting float to duration"); + } + let nanos = nanos as u128; + Duration { + secs: (nanos / (NANOS_PER_SEC as u128)) as u64, + nanos: (nanos % (NANOS_PER_SEC as u128)) as u32, + } + } + /// Multiplies `Duration` by `f64`. /// /// # Panics @@ -568,7 +624,29 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn mul_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(rhs * self.as_float_secs()) + Duration::from_secs_f64(rhs * self.as_secs_f64()) + } + + /// Multiplies `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// // note that due to rounding errors result is slightly different + /// // from 8.478 and 847800.0 + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn mul_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(rhs * self.as_secs_f32()) } /// Divide `Duration` by `f64`. @@ -589,7 +667,30 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn div_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(self.as_float_secs() / rhs) + Duration::from_secs_f64(self.as_secs_f64() / rhs) + } + + /// Divide `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// // note that due to rounding errors result is slightly + /// // different from 0.859_872_611 + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576)); + /// // note that truncation is used, not rounding + /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(self.as_secs_f32() / rhs) } /// Divide `Duration` by `Duration` and return `f64`. @@ -601,12 +702,29 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_duration_f64(self, rhs: Duration) -> f64 { + self.as_secs_f64() / rhs.as_secs_f64() + } + + /// Divide `Duration` by `Duration` and return `f32`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur1 = Duration::new(2, 700_000_000); + /// let dur2 = Duration::new(5, 400_000_000); + /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn div_duration(self, rhs: Duration) -> f64 { - self.as_float_secs() / rhs.as_float_secs() + pub fn div_duration_f32(self, rhs: Duration) -> f32 { + self.as_secs_f32() / rhs.as_secs_f32() } } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 41a4a8031006f..eb75e624d34b2 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -724,7 +724,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId { } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(*self) + tcx.def_path_str(*self) } } @@ -736,7 +736,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex { } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(DefId::local(*self)) + tcx.def_path_str(DefId::local(*self)) } } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index ed1c15a73c260..397843fd75afa 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -249,7 +249,7 @@ impl DefId { if self.is_local() && self.index == CRATE_DEF_INDEX { format!("top-level module") } else { - format!("module `{}`", tcx.item_path_str(*self)) + format!("module `{}`", tcx.def_path_str(*self)) } } } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index f454d691d4188..dca4ce4aef817 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -679,13 +679,13 @@ impl DefPathData { return name } // note that this does not show up in user printouts - CrateRoot => "{{root}}", + CrateRoot => "{{crate}}", Impl => "{{impl}}", - Misc => "{{?}}", + Misc => "{{misc}}", ClosureExpr => "{{closure}}", StructCtor => "{{constructor}}", AnonConst => "{{constant}}", - ImplTrait => "{{impl-Trait}}", + ImplTrait => "{{opaque}}", }; Symbol::intern(s).as_interned_str() diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 86b6805cc9b4c..151c5413dcf60 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -541,7 +541,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_owner(&self, id: HirId) -> HirId { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id, + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id, Node::GenericParam(_) => self.get_parent_node_by_hir_id(id), _ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id)) } @@ -549,7 +550,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_name(&self, id: HirId) -> Name { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(), + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(), Node::GenericParam(param) => param.name.ident().name, _ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)), } @@ -1019,6 +1021,7 @@ impl<'hir> Map<'hir> { pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { self.read(id); // reveals attributes on the node let attrs = match self.find(id) { + Some(Node::Local(l)) => Some(&l.attrs[..]), Some(Node::Item(i)) => Some(&i.attrs[..]), Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]), Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]), @@ -1350,7 +1353,8 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { // the user-friendly path, otherwise fall back to stringifying DefPath. crate::ty::tls::with_opt(|tcx| { if let Some(tcx) = tcx { - tcx.node_path_str(id) + let def_id = map.local_def_id(id); + tcx.def_path_str(def_id) } else if let Some(path) = map.def_path_from_id(id) { path.data.into_iter().map(|elem| { elem.data.to_string() diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c7936534aad2e..2810b5a8e6ada 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.hir().span_by_hir_id(node), ), _ => ( - format!("the lifetime {} as defined on", fr.bound_region), + format!("the lifetime {} as defined on", region), cm.def_span(self.hir().span_by_hir_id(node)), ), }, @@ -444,17 +444,109 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { terr: &TypeError<'tcx>, sp: Span, ) { + use hir::def_id::CrateNum; + use hir::map::DisambiguatedDefPathData; + use ty::print::Printer; + use ty::subst::Kind; + + struct AbsolutePathPrinter<'a, 'gcx, 'tcx> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + } + + struct NonTrivialPath; + + impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> { + type Error = NonTrivialPath; + + type Path = Vec; + type Region = !; + type Type = !; + type DynExistential = !; + + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + + fn print_region( + self, + _region: ty::Region<'_>, + ) -> Result { + Err(NonTrivialPath) + } + + fn print_type( + self, + _ty: Ty<'tcx>, + ) -> Result { + Err(NonTrivialPath) + } + + fn print_dyn_existential( + self, + _predicates: &'tcx ty::List>, + ) -> Result { + Err(NonTrivialPath) + } + + fn path_crate( + self, + cnum: CrateNum, + ) -> Result { + Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) + } + fn path_qualified( + self, + _self_ty: Ty<'tcx>, + _trait_ref: Option>, + ) -> Result { + Err(NonTrivialPath) + } + + fn path_append_impl( + self, + _print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + _self_ty: Ty<'tcx>, + _trait_ref: Option>, + ) -> Result { + Err(NonTrivialPath) + } + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + let mut path = print_prefix(self)?; + path.push(disambiguated_data.data.as_interned_str().to_string()); + Ok(path) + } + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, + _args: &[Kind<'tcx>], + ) -> Result { + print_prefix(self) + } + } + let report_path_match = |err: &mut DiagnosticBuilder<'_>, did1: DefId, did2: DefId| { // Only external crates, if either is from a local // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { - let exp_path = self.tcx.item_path_str(did1); - let found_path = self.tcx.item_path_str(did2); - let exp_abs_path = self.tcx.absolute_item_path_str(did1); - let found_abs_path = self.tcx.absolute_item_path_str(did2); + let abs_path = |def_id| { + AbsolutePathPrinter { tcx: self.tcx } + .print_def_path(def_id, &[]) + }; + // We compare strings because DefPath can be different // for imported and non-imported crates - if exp_path == found_path || exp_abs_path == found_abs_path { + let same_path = || -> Result<_, NonTrivialPath> { + Ok( + self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) || + abs_path(did1)? == abs_path(did2)? + ) + }; + if same_path().unwrap_or(false) { let crate_name = self.tcx.crate_name(did1.krate); err.span_note( sp, @@ -658,7 +750,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return Some(()); } if let &ty::Adt(def, _) = &ta.sty { - let path_ = self.tcx.item_path_str(def.did.clone()); + let path_ = self.tcx.def_path_str(def.did.clone()); if path_ == other_path { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); return Some(()); @@ -683,7 +775,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// For generic types with parameters with defaults, remove the parameters corresponding to - /// the defaults. This repeats a lot of the logic found in `PrintContext::parameterized`. + /// the defaults. This repeats a lot of the logic found in `ty::print::pretty`. fn strip_generic_default_params( &self, def_id: DefId, @@ -742,11 +834,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { mutbl: hir::Mutability, s: &mut DiagnosticStyledString, ) { - let r = &r.to_string(); + let mut r = r.to_string(); + if r == "'_" { + r.clear(); + } else { + r.push(' '); + } s.push_highlighted(format!( - "&{}{}{}", + "&{}{}", r, - if r == "" { "" } else { " " }, if mutbl == hir::MutMutable { "mut " } else { "" } )); s.push_normal(ty.to_string()); @@ -757,8 +853,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1); let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - let path1 = self.tcx.item_path_str(def1.did.clone()); - let path2 = self.tcx.item_path_str(def2.did.clone()); + let path1 = self.tcx.def_path_str(def1.did.clone()); + let path2 = self.tcx.def_path_str(def2.did.clone()); if def1.did == def2.did { // Easy case. Replace same types with `_` to shorten the output and highlight // the differing ones. @@ -1013,7 +1109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() { let message = format!( "did you mean `{}(/* fields */)`?", - self.tcx.item_path_str(def_id) + self.tcx.def_path_str(def_id) ); diag.span_label(span, message); } @@ -1425,7 +1521,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { var_origin: RegionVariableOrigin, ) -> DiagnosticBuilder<'tcx> { let br_string = |br: ty::BoundRegion| { - let mut s = br.to_string(); + let mut s = match br { + ty::BrNamed(_, name) => name.to_string(), + _ => String::new(), + }; if !s.is_empty() { s.push_str(" "); } diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 9e0e48e474118..0a83b839201ed 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -1,8 +1,10 @@ +use crate::hir::def::Namespace; use crate::hir::{self, Local, Pat, Body, HirId}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOrigin; use crate::ty::{self, Ty, Infer, TyVar}; +use crate::ty::print::Print; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -64,18 +66,26 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String { + pub fn extract_type_name( + &self, + ty: &'a Ty<'tcx>, + highlight: Option, + ) -> String { if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty { let ty_vars = self.type_variables.borrow(); if let TypeVariableOrigin::TypeParameterDefinition(_, name) = *ty_vars.var_origin(ty_vid) { - name.to_string() - } else { - ty.to_string() + return name.to_string(); } - } else { - ty.to_string() } + + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); + if let Some(highlight) = highlight { + printer.region_highlight_mode = highlight; + } + let _ = ty.print(printer); + s } pub fn need_type_info_err(&self, @@ -84,7 +94,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty: Ty<'tcx>) -> DiagnosticBuilder<'gcx> { let ty = self.resolve_type_vars_if_possible(&ty); - let name = self.extract_type_name(&ty); + let name = self.extract_type_name(&ty, None); let mut err_span = span; let mut labels = vec![( diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 506388c268bb1..e708454b5b672 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,14 +1,17 @@ use errors::DiagnosticBuilder; +use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; -use crate::ty; +use crate::ty::{self, TyCtxt}; use crate::ty::error::ExpectedFound; use crate::ty::subst::SubstsRef; -use crate::util::ppaux::RegionHighlightMode; +use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter}; + +use std::fmt::{self, Write}; impl NiceRegionError<'me, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and @@ -193,7 +196,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { cause.span(&self.tcx()), &format!( "implementation of `{}` is not general enough", - self.tcx().item_path_str(trait_def_id), + self.tcx().def_path_str(trait_def_id), ), ); @@ -201,7 +204,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { ObligationCauseCode::ItemObligation(def_id) => { err.note(&format!( "Due to a where-clause on `{}`,", - self.tcx().item_path_str(def_id), + self.tcx().def_path_str(def_id), )); } _ => (), @@ -309,13 +312,46 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { sup_placeholder: Option>, has_sub: Option, has_sup: Option, - expected_trait_ref: ty::TraitRef<'_>, - actual_trait_ref: ty::TraitRef<'_>, + expected_trait_ref: ty::TraitRef<'tcx>, + actual_trait_ref: ty::TraitRef<'tcx>, vid: Option>, expected_has_vid: Option, actual_has_vid: Option, any_self_ty_has_vid: bool, ) { + // HACK(eddyb) maybe move this in a more central location. + #[derive(Copy, Clone)] + struct Highlighted<'a, 'gcx, 'tcx, T> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + highlight: RegionHighlightMode, + value: T, + } + + impl<'a, 'gcx, 'tcx, T> Highlighted<'a, 'gcx, 'tcx, T> { + fn map(self, f: impl FnOnce(T) -> U) -> Highlighted<'a, 'gcx, 'tcx, U> { + Highlighted { + tcx: self.tcx, + highlight: self.highlight, + value: f(self.value), + } + } + } + + impl<'a, 'gcx, 'tcx, T> fmt::Display for Highlighted<'a, 'gcx, 'tcx, T> + where T: for<'b, 'c> Print<'gcx, 'tcx, + FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>, + Error = fmt::Error, + >, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut printer = ty::print::FmtPrinter::new(self.tcx, f, Namespace::TypeNS); + printer.region_highlight_mode = self.highlight; + + self.value.print(printer)?; + Ok(()) + } + } + // The weird thing here with the `maybe_highlighting_region` calls and the // the match inside is meant to be like this: // @@ -331,112 +367,93 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { // None, an then we check again inside the closure, but this // setup sort of minimized the number of calls and so form. - RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { - RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { - match (has_sub, has_sup) { - (Some(n1), Some(n2)) => { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - )); - } else { - err.note(&format!( - "`{}` must implement `{}`, \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - )); - } - } - (Some(n), _) | (_, Some(n)) => { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any lifetime `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - n, - )); - } else { - err.note(&format!( - "`{}` must implement `{}`, for any lifetime `'{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - n, - )); - } - } - (None, None) => RegionHighlightMode::maybe_highlighting_region( - vid, - expected_has_vid, - || { - if let Some(n) = expected_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for some specific lifetime `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - n, - )); - } else { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - )); - } else { - err.note(&format!( - "`{}` must implement `{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - )); - } - } - }, - ), - } - }) - }); + let highlight_trait_ref = |trait_ref| Highlighted { + tcx: self.tcx(), + highlight: RegionHighlightMode::default(), + value: trait_ref, + }; - RegionHighlightMode::maybe_highlighting_region( - vid, - actual_has_vid, - || match actual_has_vid { - Some(n) => { - if any_self_ty_has_vid { - err.note(&format!( - "but `{}` is actually implemented for the type `{}`, \ - for some specific lifetime `'{}`", - actual_trait_ref, - actual_trait_ref.self_ty(), - n - )); - } else { - err.note(&format!( - "but `{}` actually implements `{}`, for some specific lifetime `'{}`", - actual_trait_ref.self_ty(), - actual_trait_ref, - n - )); + let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref); + expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub); + expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup); + err.note(&{ + let passive_voice = match (has_sub, has_sup) { + (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid, + (None, None) => { + expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid); + match expected_has_vid { + Some(_) => true, + None => any_self_ty_has_vid, } } + }; - _ => { - err.note(&format!( - "but `{}` is actually implemented for the type `{}`", - actual_trait_ref, - actual_trait_ref.self_ty(), - )); + let mut note = if passive_voice { + format!( + "`{}` would have to be implemented for the type `{}`", + expected_trait_ref, + expected_trait_ref.map(|tr| tr.self_ty()), + ) + } else { + format!( + "`{}` must implement `{}`", + expected_trait_ref.map(|tr| tr.self_ty()), + expected_trait_ref, + ) + }; + + match (has_sub, has_sup) { + (Some(n1), Some(n2)) => { + let _ = write!(note, + ", for any two lifetimes `'{}` and `'{}`", + std::cmp::min(n1, n2), + std::cmp::max(n1, n2), + ); } - }, - ); + (Some(n), _) | (_, Some(n)) => { + let _ = write!(note, + ", for any lifetime `'{}`", + n, + ); + } + (None, None) => if let Some(n) = expected_has_vid { + let _ = write!(note, + ", for some specific lifetime `'{}`", + n, + ); + }, + } + + note + }); + + let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref); + actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid); + err.note(&{ + let passive_voice = match actual_has_vid { + Some(_) => any_self_ty_has_vid, + None => true, + }; + + let mut note = if passive_voice { + format!( + "but `{}` is actually implemented for the type `{}`", + actual_trait_ref, + actual_trait_ref.map(|tr| tr.self_ty()), + ) + } else { + format!( + "but `{}` actually implements `{}`", + actual_trait_ref.map(|tr| tr.self_ty()), + actual_trait_ref, + ) + }; + + if let Some(n) = actual_has_vid { + let _ = write!(note, ", for some specific lifetime `'{}`", n); + } + + note + }); } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index 6db1bc382afe9..3ed28a1f98825 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -3,7 +3,7 @@ use crate::hir; use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use crate::ty::{self, Region, Ty}; +use crate::ty::{self, DefIdTree, Region, Ty}; use crate::hir::def_id::DefId; use syntax_pos::Span; @@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let (id, bound_region) = match *anon_region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ref ebr) => ( - self.tcx().parent_def_id(ebr.def_id).unwrap(), + self.tcx().parent(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index 78353e52ad462..5349e990a7761 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -91,7 +91,7 @@ impl_stable_hash_for!(struct FreeRegionMap<'tcx> { impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { - self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx)) + self.relation.maybe_map(|&fr| tcx.lift(&fr)) .map(|relation| FreeRegionMap { relation }) } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 6adfaa53946ac..b6677326227f4 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -31,6 +31,7 @@ #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(core_intrinsics)] @@ -134,9 +135,7 @@ pub mod ty; pub mod util { pub mod captures; pub mod common; - pub mod ppaux; pub mod nodemap; - pub mod time_graph; pub mod profiling; pub mod bug; } diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 924aa3fde0a08..3c6635c034131 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -157,6 +157,7 @@ pub struct LintLevelsBuilder<'a> { pub struct BuilderPush { prev: u32, + pub(super) changed: bool, } impl<'a> LintLevelsBuilder<'a> { @@ -454,6 +455,7 @@ impl<'a> LintLevelsBuilder<'a> { BuilderPush { prev: prev, + changed: prev != self.cur, } } @@ -512,11 +514,6 @@ impl LintLevelMap { self.sets.get_lint_level(lint, *idx, None, session) }) } - - /// Returns if this `id` has lint level information. - pub fn lint_level_set(&self, id: HirId) -> Option { - self.id_to_set.get(&id).cloned() - } } impl<'a> HashStable> for LintLevelMap { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 496ff568b31b4..c01b0ae2ccc1d 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -721,6 +721,16 @@ pub fn struct_lint_level<'a>(sess: &'a Session, return err } +pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { + let attrs = tcx.hir().attrs_by_hir_id(id); + for attr in attrs { + if Level::from_str(&attr.name().as_str()).is_some() { + return true; + } + } + false +} + fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) -> Lrc { @@ -731,9 +741,10 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) }; let krate = tcx.hir().krate(); - builder.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |builder| { - intravisit::walk_crate(builder, krate); - }); + let push = builder.levels.push(&krate.attrs); + builder.levels.register_id(hir::CRATE_HIR_ID); + intravisit::walk_crate(&mut builder, krate); + builder.levels.pop(push); Lrc::new(builder.levels.build_map()) } @@ -751,7 +762,9 @@ impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> { where F: FnOnce(&mut Self) { let push = self.levels.push(attrs); - self.levels.register_id(id); + if push.changed { + self.levels.register_id(id); + } f(self); self.levels.pop(push); } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 94de999c25da8..3da82d728c0c4 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -12,7 +12,7 @@ use crate::hir::CodegenFnAttrFlags; use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::lint; use crate::middle::privacy; -use crate::ty::{self, TyCtxt}; +use crate::ty::{self, DefIdTree, TyCtxt}; use crate::util::nodemap::FxHashSet; use rustc_data_structures::fx::FxHashMap; @@ -78,7 +78,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) | Def::Local(..) | Def::Upvar(..) => {} Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { - if let Some(enum_id) = self.tcx.parent_def_id(variant_id) { + if let Some(enum_id) = self.tcx.parent(variant_id) { self.check_def_id(enum_id); } if !self.ignore_variant_stack.contains(&variant_id) { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index a3e8598194e79..b36d2a57cb3b1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -64,7 +64,7 @@ use crate::hir::Node; use crate::infer::InferCtxt; use crate::hir::def::{Def, CtorKind}; use crate::ty::adjustment; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::fold::TypeFoldable; use crate::ty::layout::VariantIdx; @@ -786,7 +786,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk // FnOnce | copied | upvar -> &'up bk - let kind = match self.node_ty(fn_hir_id)?.sty { + let ty = self.node_ty(fn_hir_id)?; + let kind = match ty.sty { ty::Generator(..) => ty::ClosureKind::FnOnce, ty::Closure(closure_def_id, closure_substs) => { match self.infcx { @@ -803,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { .closure_kind(closure_def_id, self.tcx.global_tcx()), } } - ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t), + _ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty), }; let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id); @@ -1064,7 +1065,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let bk = ty::BorrowKind::from_mutbl(mutbl); BorrowedPtr(bk, r) } - ref ty => bug!("unexpected type in cat_deref: {:?}", ty) + _ => bug!("unexpected type in cat_deref: {:?}", base_cmt.ty) }; let ret = cmt_ { hir_id: node.hir_id(), @@ -1132,7 +1133,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { variant_did: DefId) -> cmt<'tcx> { // univariant enums do not need downcasts - let base_did = self.tcx.parent_def_id(variant_did).unwrap(); + let base_did = self.tcx.parent(variant_did).unwrap(); if self.tcx.adt_def(base_did).variants.len() != 1 { let base_ty = base_cmt.ty; let ret = Rc::new(cmt_ { @@ -1274,16 +1275,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { return Err(()) } Def::VariantCtor(def_id, CtorKind::Fn) => { - let enum_def = self.tcx.parent_def_id(def_id).unwrap(); + let enum_def = self.tcx.parent(def_id).unwrap(); (self.cat_downcast_if_needed(pat, cmt, def_id), self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()) } Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => { - match self.pat_ty_unadjusted(&pat)?.sty { + let ty = self.pat_ty_unadjusted(&pat)?; + match ty.sty { ty::Adt(adt_def, _) => { (cmt, adt_def.non_enum_variant().fields.len()) } - ref ty => { + _ => { span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty); } @@ -1334,9 +1336,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::Tuple(ref subpats, ddpos) => { // (p1, ..., pN) - let expected_len = match self.pat_ty_unadjusted(&pat)?.sty { + let ty = self.pat_ty_unadjusted(&pat)?; + let expected_len = match ty.sty { ty::Tuple(ref tys) => tys.len(), - ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), + _ => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 42e253273ab3e..2b3802388106a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,7 +17,7 @@ use rustc_macros::HashStable; use syntax::source_map; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use crate::ty::TyCtxt; +use crate::ty::{DefIdTree, TyCtxt}; use crate::ty::query::Providers; use crate::hir; @@ -650,7 +650,7 @@ impl<'tcx> ScopeTree { pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, br: &ty::EarlyBoundRegion) -> Scope { - let param_owner = tcx.parent_def_id(br.def_id).unwrap(); + let param_owner = tcx.parent(br.def_id).unwrap(); let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap(); let scope = tcx.hir().maybe_body_owned_by_by_hir_id(param_owner_id).map(|body_id| { @@ -679,7 +679,7 @@ impl<'tcx> ScopeTree { -> Scope { let param_owner = match fr.bound_region { ty::BoundRegion::BrNamed(def_id, _) => { - tcx.parent_def_id(def_id).unwrap() + tcx.parent(def_id).unwrap() } _ => fr.scope }; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 96f0beafa005f..ab10536038872 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2299,6 +2299,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; let mut scope = self.scope; + let mut lifetime_names = FxHashSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2306,12 +2307,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, .. } => { + Scope::Binder { s, ref lifetimes, .. } => { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } late_depth += 1; scope = s; } - Scope::Elision { ref elide, .. } => { + Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { Elide::FreshLateAnon(ref counter) => { for lifetime_ref in lifetime_refs { @@ -2321,7 +2328,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } Elide::Exact(l) => l.shifted(late_depth), - Elide::Error(ref e) => break Some(e), + Elide::Error(ref e) => { + if let Scope::Binder { ref lifetimes, .. } = s { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } + } + break Some(e); + } }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2344,7 +2361,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + add_missing_lifetime_specifiers_label( + &mut err, + span, + lifetime_refs.len(), + &lifetime_names, + self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + ); } err.emit(); @@ -2885,10 +2908,23 @@ fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, span: Span, count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); + } else if let (1, Some(name), Some("&")) = ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet, + ) { + err.span_suggestion( + span, + "consider using the named lifetime", + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, "expected lifetime parameter"); - }; + } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 1677384059e09..0a2a375e1b2c1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -593,7 +593,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { - let path = self.item_path_str(def_id); + let path = self.def_path_str(def_id); let message = format!("use of deprecated item '{}'", path); lint_deprecated(def_id, id, @@ -620,7 +620,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(id) = id { if let Some(stability) = stability { if let Some(depr) = &stability.rustc_depr { - let path = self.item_path_str(def_id); + let path = self.def_path_str(def_id); if deprecation_in_effect(&depr.since.as_str()) { let message = format!("use of deprecated item '{}'", path); lint_deprecated(def_id, diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index d4ee60eee6310..80fef910cc718 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -101,8 +101,7 @@ impl AllocationExtra<(), ()> for () { impl Allocation { /// Creates a read-only allocation initialized by the given bytes pub fn from_bytes(slice: &[u8], align: Align, extra: Extra) -> Self { - let mut undef_mask = UndefMask::new(Size::ZERO); - undef_mask.grow(Size::from_bytes(slice.len() as u64), true); + let undef_mask = UndefMask::new(Size::from_bytes(slice.len() as u64), true); Self { bytes: slice.to_owned(), relocations: Relocations::new(), @@ -122,7 +121,7 @@ impl Allocation { Allocation { bytes: vec![0; size.bytes() as usize], relocations: Relocations::new(), - undef_mask: UndefMask::new(size), + undef_mask: UndefMask::new(size, false), align, mutability: Mutability::Mutable, extra, @@ -614,8 +613,9 @@ impl DerefMut for Relocations { //////////////////////////////////////////////////////////////////////////////// type Block = u64; -const BLOCK_SIZE: u64 = 64; +/// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte +/// is defined. If it is `false` the byte is undefined. #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct UndefMask { blocks: Vec, @@ -625,12 +625,14 @@ pub struct UndefMask { impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len}); impl UndefMask { - pub fn new(size: Size) -> Self { + pub const BLOCK_SIZE: u64 = 64; + + pub fn new(size: Size, state: bool) -> Self { let mut m = UndefMask { blocks: vec![], len: Size::ZERO, }; - m.grow(size, false); + m.grow(size, state); m } @@ -644,6 +646,7 @@ impl UndefMask { return Err(self.len); } + // FIXME(oli-obk): optimize this for allocations larger than a block. let idx = (start.bytes()..end.bytes()) .map(|i| Size::from_bytes(i)) .find(|&i| !self.get(i)); @@ -663,20 +666,63 @@ impl UndefMask { } pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) { - for i in start.bytes()..end.bytes() { - self.set(Size::from_bytes(i), new_state); + let (blocka, bita) = bit_index(start); + let (blockb, bitb) = bit_index(end); + if blocka == blockb { + // first set all bits but the first `bita` + // then unset the last `64 - bitb` bits + let range = if bitb == 0 { + u64::max_value() << bita + } else { + (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb)) + }; + if new_state { + self.blocks[blocka] |= range; + } else { + self.blocks[blocka] &= !range; + } + return; + } + // across block boundaries + if new_state { + // set bita..64 to 1 + self.blocks[blocka] |= u64::max_value() << bita; + // set 0..bitb to 1 + if bitb != 0 { + self.blocks[blockb] |= u64::max_value() >> (64 - bitb); + } + // fill in all the other blocks (much faster than one bit at a time) + for block in (blocka + 1) .. blockb { + self.blocks[block] = u64::max_value(); + } + } else { + // set bita..64 to 0 + self.blocks[blocka] &= !(u64::max_value() << bita); + // set 0..bitb to 0 + if bitb != 0 { + self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb)); + } + // fill in all the other blocks (much faster than one bit at a time) + for block in (blocka + 1) .. blockb { + self.blocks[block] = 0; + } } } #[inline] pub fn get(&self, i: Size) -> bool { let (block, bit) = bit_index(i); - (self.blocks[block] & 1 << bit) != 0 + (self.blocks[block] & (1 << bit)) != 0 } #[inline] pub fn set(&mut self, i: Size, new_state: bool) { let (block, bit) = bit_index(i); + self.set_bit(block, bit, new_state); + } + + #[inline] + fn set_bit(&mut self, block: usize, bit: usize, new_state: bool) { if new_state { self.blocks[block] |= 1 << bit; } else { @@ -685,11 +731,15 @@ impl UndefMask { } pub fn grow(&mut self, amount: Size, new_state: bool) { - let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len.bytes(); + if amount.bytes() == 0 { + return; + } + let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes(); if amount.bytes() > unused_trailing_bits { - let additional_blocks = amount.bytes() / BLOCK_SIZE + 1; + let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1; assert_eq!(additional_blocks as usize as u64, additional_blocks); self.blocks.extend( + // FIXME(oli-obk): optimize this by repeating `new_state as Block` iter::repeat(0).take(additional_blocks as usize), ); } @@ -702,8 +752,8 @@ impl UndefMask { #[inline] fn bit_index(bits: Size) -> (usize, usize) { let bits = bits.bytes(); - let a = bits / BLOCK_SIZE; - let b = bits % BLOCK_SIZE; + let a = bits / UndefMask::BLOCK_SIZE; + let b = bits % UndefMask::BLOCK_SIZE; assert_eq!(a as usize as u64, a); assert_eq!(b as usize as u64, b); (a as usize, b as usize) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3a4422a62390b..718b506d05113 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html -use crate::hir::def::CtorKind; +use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def_id::DefId; use crate::hir::{self, HirId, InlineAsm}; use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar}; @@ -34,7 +34,7 @@ use crate::ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; -use crate::util::ppaux; +use crate::ty::print::{FmtPrinter, Printer}; pub use crate::mir::interpret::AssertMessage; @@ -2062,7 +2062,7 @@ impl<'tcx> Debug for Place<'tcx> { Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!( fmt, "({}: {:?})", - ty::tls::with(|tcx| tcx.item_path_str(def_id)), + ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty ), Base(PlaceBase::Promoted(ref promoted)) => write!( @@ -2369,7 +2369,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - let region = if ppaux::verbose() || ppaux::identify_regions() { + let print_region = ty::tls::with(|tcx| { + tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions + }); + let region = if print_region { let mut region = region.to_string(); if region.len() > 0 { region.push(' '); @@ -2403,7 +2406,13 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, substs, variant_def.did, &[])?; + let f = &mut *fmt; + ty::tls::with(|tcx| { + let substs = tcx.lift(&substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, f, Namespace::ValueNS) + .print_def_path(variant_def.did, substs)?; + Ok(()) + })?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), @@ -2729,7 +2738,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul } // print function definitions if let FnDef(did, _) = ty.sty { - return write!(f, "{}", item_path_str(did)); + return write!(f, "{}", def_path_str(did)); } // print string literals if let ConstValue::Slice(ptr, len) = value { @@ -2754,8 +2763,8 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul write!(f, "{:?}:{}", value, ty) } -fn item_path_str(def_id: DefId) -> String { - ty::tls::with(|tcx| tcx.item_path_str(def_id)) +fn def_path_str(def_id: DefId) -> String { + ty::tls::with(|tcx| tcx.def_path_str(def_id)) } impl<'tcx> graph::DirectedGraph for Mir<'tcx> { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 55c4b0e54b822..ff18678f091b9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -800,6 +800,7 @@ macro_rules! options { pub const parse_opt_pathbuf: Option<&str> = Some("a path"); pub const parse_list: Option<&str> = Some("a space-separated list of strings"); pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings"); pub const parse_uint: Option<&str> = Some("a number"); pub const parse_passes: Option<&str> = Some("a space-separated list of passes, or `all`"); @@ -926,6 +927,18 @@ macro_rules! options { } } + fn parse_opt_comma_list(slot: &mut Option>, v: Option<&str>) + -> bool { + match v { + Some(s) => { + let v = s.split(',').map(|s| s.to_string()).collect(); + *slot = Some(v); + true + }, + None => false, + } + } + fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(i) => { *slot = i; true }, @@ -1427,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, merge_functions: Option = (None, parse_merge_functions, [TRACKED], "control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name"), + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (space separated)"), } pub fn default_lib_output() -> CrateType { @@ -3273,6 +3288,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index c7674ae7a28a2..6c8fe0875b60c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -854,10 +854,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => vec![ArgKind::empty()], }; - let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { + let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); + let expected = match expected_ty.sty { ty::Tuple(ref tys) => tys.iter() .map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(), - ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())], + _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], }; if found.len() == expected.len() { @@ -1284,11 +1285,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!(self.sess, span, E0072, "recursive type `{}` has infinite size", - self.item_path_str(type_def_id)); + self.def_path_str(type_def_id)); err.span_label(span, "recursive type has infinite size"); err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \ at some point to make `{}` representable", - self.item_path_str(type_def_id))); + self.def_path_str(type_def_id))); err } @@ -1298,7 +1299,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { violations: Vec) -> DiagnosticBuilder<'tcx> { - let trait_str = self.item_path_str(trait_def_id); + let trait_str = self.def_path_str(trait_def_id); let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!( self.sess, span, E0038, @@ -1523,7 +1524,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { region, object_ty)); } ObligationCauseCode::ItemObligation(item_def_id) => { - let item_name = tcx.item_path_str(item_def_id); + let item_name = tcx.def_path_str(item_def_id); let msg = format!("required by `{}`", item_name); if let Some(sp) = tcx.hir().span_if_local(item_def_id) { @@ -1686,10 +1687,10 @@ impl ArgKind { ty::Tuple(ref tys) => ArgKind::Tuple( span, tys.iter() - .map(|ty| ("_".to_owned(), ty.sty.to_string())) + .map(|ty| ("_".to_owned(), ty.to_string())) .collect::>() ), - _ => ArgKind::Arg("_".to_owned(), t.sty.to_string()), + _ => ArgKind::Arg("_".to_owned(), t.to_string()), } } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index df127b934b0b1..78c80b48ee80d 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -650,7 +650,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( ) -> bool { debug!("type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})", ty, - infcx.tcx.item_path_str(def_id)); + infcx.tcx.def_path_str(def_id)); let trait_ref = ty::TraitRef { def_id, @@ -665,7 +665,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( let result = infcx.predicate_must_hold_modulo_regions(&obligation); debug!("type_known_to_meet_ty={:?} bound={} => {:?}", - ty, infcx.tcx.item_path_str(def_id), result); + ty, infcx.tcx.def_path_str(def_id), result); if result && (ty.has_infer_types() || ty.has_closure_types()) { // Because of inference "guessing", selection can sometimes claim @@ -692,13 +692,13 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( Ok(()) => { debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success", ty, - infcx.tcx.item_path_str(def_id)); + infcx.tcx.def_path_str(def_id)); true } Err(e) => { debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}", ty, - infcx.tcx.item_path_str(def_id), + infcx.tcx.def_path_str(def_id), e); false } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index e7a5138e6893c..1c8ea5c7b9c5b 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { hir::CRATE_HIR_ID, *span, &format!("the trait `{}` cannot be made into an object", - self.item_path_str(trait_def_id)), + self.def_path_str(trait_def_id)), &violation.error_msg()); false } else { diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index c86fd0d52b901..fc0058a1df5ff 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { -> String { let name = tcx.item_name(trait_ref.def_id); - let trait_str = tcx.item_path_str(trait_ref.def_id); + let trait_str = tcx.def_path_str(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id); let generic_map = generics.params.iter().filter_map(|param| { let value = match param.kind { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 197bea1c31189..ab6acc662131b 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1549,7 +1549,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( // should have failed in astconv. bug!("No associated type `{}` for {}", assoc_ty_name, - tcx.item_path_str(impl_def_id)) + tcx.def_path_str(impl_def_id)) } } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index a2924cb993fbf..c576586fcad8e 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< w.push('<'); w.push_str(&substs.iter() .map(|k| k.to_string()) - .filter(|k| &k[..] != "'_") + .filter(|k| k != "'_") .collect::>().join(", ")); w.push('>'); } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index b5be1777fa0d8..f3a800bf46d87 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -165,7 +165,8 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { use crate::traits::WhereClause::*; - // Bypass ppaux because it does not print out anonymous regions. + // Bypass `ty::print` because it does not print out anonymous regions. + // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`. fn write_region_name<'tcx>( r: ty::Region<'tcx>, fmt: &mut fmt::Formatter<'_> @@ -256,7 +257,7 @@ impl fmt::Display for traits::QuantifierKind { } /// Collect names for regions / types bound by a quantified goal / clause. -/// This collector does not try to do anything clever like in ppaux, it's just used +/// This collector does not try to do anything clever like in `ty::print`, it's just used /// for debug output in tests anyway. struct BoundNamesCollector { // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 5e4274fa1c8e5..1942f98abff17 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -26,7 +26,7 @@ use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; use crate::traits; use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals}; -use crate::ty::{self, Ty, TypeAndMut}; +use crate::ty::{self, DefIdTree, Ty, TypeAndMut}; use crate::ty::{TyS, TyKind, List}; use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst}; use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; @@ -1594,7 +1594,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let (suitable_region_binding_scope, bound_region) = match *region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ref ebr) => ( - self.parent_def_id(ebr.def_id).unwrap(), + self.parent(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region @@ -2886,30 +2886,44 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { err.emit() } - pub fn lint_level_at_node(self, lint: &'static Lint, mut id: hir::HirId) - -> (lint::Level, lint::LintSource) - { - // Right now we insert a `with_ignore` node in the dep graph here to - // ignore the fact that `lint_levels` below depends on the entire crate. - // For now this'll prevent false positives of recompiling too much when - // anything changes. - // - // Once red/green incremental compilation lands we should be able to - // remove this because while the crate changes often the lint level map - // will change rarely. - self.dep_graph.with_ignore(|| { - let sets = self.lint_levels(LOCAL_CRATE); - loop { - if let Some(pair) = sets.level_and_source(lint, id, self.sess) { - return pair - } - let next = self.hir().get_parent_node_by_hir_id(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; + /// Walks upwards from `id` to find a node which might change lint levels with attributes. + /// It stops at `bound` and just returns it if reached. + pub fn maybe_lint_level_root_bounded( + self, + mut id: hir::HirId, + bound: hir::HirId, + ) -> hir::HirId { + loop { + if id == bound { + return bound; } - }) + if lint::maybe_lint_level_root(self, id) { + return id; + } + let next = self.hir().get_parent_node_by_hir_id(id); + if next == id { + bug!("lint traversal reached the root of the crate"); + } + id = next; + } + } + + pub fn lint_level_at_node( + self, + lint: &'static Lint, + mut id: hir::HirId + ) -> (lint::Level, lint::LintSource) { + let sets = self.lint_levels(LOCAL_CRATE); + loop { + if let Some(pair) = sets.level_and_source(lint, id, self.sess) { + return pair + } + let next = self.hir().get_parent_node_by_hir_id(id); + if next == id { + bug!("lint traversal reached the root of the crate"); + } + id = next; + } } pub fn struct_span_lint_hir>(self, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index f58e5e4fb69f6..fa3c76a817a4f 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -71,6 +71,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } } + let br_string = |br: ty::BoundRegion| { + match br { + ty::BrNamed(_, name) => format!(" {}", name), + _ => String::new(), + } + }; + match *self { CyclicTy(_) => write!(f, "cyclic type of infinite size"), Mismatch => write!(f, "types differ"), @@ -105,15 +112,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } RegionsInsufficientlyPolymorphic(br, _) => { write!(f, - "expected bound lifetime parameter{}{}, found concrete lifetime", - if br.is_named() { " " } else { "" }, - br) + "expected bound lifetime parameter{}, found concrete lifetime", + br_string(br)) } RegionsOverlyPolymorphic(br, _) => { write!(f, - "expected concrete lifetime, found bound lifetime parameter{}{}", - if br.is_named() { " " } else { "" }, - br) + "expected concrete lifetime, found bound lifetime parameter{}", + br_string(br)) } RegionsPlaceholderMismatch => { write!(f, "one type is more general than the other") @@ -125,9 +130,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { Traits(values) => ty::tls::with(|tcx| { report_maybe_different(f, &format!("trait `{}`", - tcx.item_path_str(values.expected)), + tcx.def_path_str(values.expected)), &format!("trait `{}`", - tcx.item_path_str(values.found))) + tcx.def_path_str(values.found))) }), IntMismatch(ref values) => { write!(f, "expected `{:?}`, found `{:?}`", @@ -146,8 +151,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } ProjectionMismatched(ref values) => ty::tls::with(|tcx| { write!(f, "expected {}, found {}", - tcx.item_path_str(values.expected), - tcx.item_path_str(values.found)) + tcx.def_path_str(values.expected), + tcx.def_path_str(values.found)) }), ProjectionBoundsLength(ref values) => { write!(f, "expected {} associated type bindings, found {}", @@ -169,8 +174,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(), ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(), - ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(), - ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(), + ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(), + ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), ty::Array(_, n) => match n { ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) { Some(n) => format!("array of {} elements", n).into(), @@ -185,7 +190,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { let tymut_string = tymut.to_string(); if tymut_string == "_" || //unknown type name, tymut_string.len() > 10 || //name longer than saying "reference", - region.to_string() != "" //... or a complex type + region.to_string() != "'_" //... or a complex type { format!("{}reference", match mutbl { hir::Mutability::MutMutable => "mutable ", @@ -199,7 +204,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { if let Some(principal) = inner.principal() { - format!("trait {}", tcx.item_path_str(principal.def_id())).into() + format!("trait {}", tcx.def_path_str(principal.def_id())).into() } else { "trait".into() } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index e0b7bbc68e25e..995e85fc5f4db 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,10 +1,11 @@ use crate::hir::Unsafety; +use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; +use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; -use crate::util::ppaux; use std::fmt; use std::iter; @@ -175,7 +176,13 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ppaux::parameterized(f, self.substs, self.def_id(), &[])?; + ty::tls::with(|tcx| { + let substs = tcx.lift(&self.substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS) + .print_def_path(self.def_id(), substs)?; + Ok(()) + })?; + match self.def { InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => { diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs deleted file mode 100644 index 26e2705a7a034..0000000000000 --- a/src/librustc/ty/item_path.rs +++ /dev/null @@ -1,573 +0,0 @@ -use crate::hir::map::DefPathData; -use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt}; -use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use syntax::ast; -use syntax::symbol::{keywords, LocalInternedString, Symbol}; - -use std::cell::Cell; -use std::fmt::Debug; - -thread_local! { - static FORCE_ABSOLUTE: Cell = Cell::new(false); - static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); - static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); -} - -/// Enforces that item_path_str always returns an absolute path and -/// also enables "type-based" impl paths. This is used when building -/// symbols that contain types, where we want the crate name to be -/// part of the symbol. -pub fn with_forced_absolute_paths R, R>(f: F) -> R { - FORCE_ABSOLUTE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - -/// Force us to name impls with just the filename/line number. We -/// normally try to use types. But at some points, notably while printing -/// cycle errors, this can result in extra or suboptimal error output, -/// so this variable disables that check. -pub fn with_forced_impl_filename_line R, R>(f: F) -> R { - FORCE_IMPL_FILENAME_LINE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - -/// Adds the `crate::` prefix to paths where appropriate. -pub fn with_crate_prefix R, R>(f: F) -> R { - SHOULD_PREFIX_WITH_CRATE.with(|flag| { - let old = flag.get(); - flag.set(true); - let result = f(); - flag.set(old); - result - }) -} - -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. It is relative to the current crate - /// root, unless with_forced_absolute_paths was used. - pub fn item_path_str(self, def_id: DefId) -> String { - let mode = FORCE_ABSOLUTE.with(|force| { - if force.get() { - RootMode::Absolute - } else { - RootMode::Local - } - }); - let mut buffer = LocalPathBuffer::new(mode); - debug!("item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id, false); - buffer.into_string() - } - - /// Returns a string identifying this local node-id. - pub fn node_path_str(self, id: ast::NodeId) -> String { - self.item_path_str(self.hir().local_def_id(id)) - } - - /// Returns a string identifying this def-id. This string is - /// suitable for user output. It always begins with a crate identifier. - pub fn absolute_item_path_str(self, def_id: DefId) -> String { - let mut buffer = LocalPathBuffer::new(RootMode::Absolute); - debug!("absolute_item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id, false); - buffer.into_string() - } - - /// Returns the "path" to a particular crate. This can proceed in - /// various ways, depending on the `root_mode` of the `buffer`. - /// (See `RootMode` enum for more details.) - /// - /// `pushed_prelude_crate` argument should be `true` when the buffer - /// has had a prelude crate pushed to it. If this is the case, then - /// we do not want to prepend `crate::` (as that would not be a valid - /// path). - pub fn push_krate_path(self, buffer: &mut T, cnum: CrateNum, pushed_prelude_crate: bool) - where T: ItemPathBuffer + Debug - { - debug!( - "push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}", - buffer, cnum, LOCAL_CRATE - ); - match *buffer.root_mode() { - RootMode::Local => { - // In local mode, when we encounter a crate other than - // LOCAL_CRATE, execution proceeds in one of two ways: - // - // 1. for a direct dependency, where user added an - // `extern crate` manually, we put the `extern - // crate` as the parent. So you wind up with - // something relative to the current crate. - // 2. for an extern inferred from a path or an indirect crate, - // where there is no explicit `extern crate`, we just prepend - // the crate name. - // - // Returns `None` for the local crate. - if cnum != LOCAL_CRATE { - let opt_extern_crate = self.extern_crate(cnum.as_def_id()); - if let Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - .. - }) = *opt_extern_crate - { - debug!("push_krate_path: def_id={:?}", def_id); - self.push_item_path(buffer, def_id, pushed_prelude_crate); - } else { - let name = self.crate_name(cnum).as_str(); - debug!("push_krate_path: name={:?}", name); - buffer.push(&name); - } - } else if self.sess.rust_2018() && !pushed_prelude_crate { - SHOULD_PREFIX_WITH_CRATE.with(|flag| { - // We only add the `crate::` keyword where appropriate. In particular, - // when we've not previously pushed a prelude crate to this path. - if flag.get() { - buffer.push(&keywords::Crate.name().as_str()) - } - }) - } - } - RootMode::Absolute => { - // In absolute mode, just write the crate name - // unconditionally. - let name = self.original_crate_name(cnum).as_str(); - debug!("push_krate_path: original_name={:?}", name); - buffer.push(&name); - } - } - } - - /// If possible, this pushes a global path resolving to `external_def_id` that is visible - /// from at least one local module and returns true. If the crate defining `external_def_id` is - /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - pub fn try_push_visible_item_path( - self, - buffer: &mut T, - external_def_id: DefId, - pushed_prelude_crate: bool, - ) -> bool - where T: ItemPathBuffer + Debug - { - debug!( - "try_push_visible_item_path: buffer={:?} external_def_id={:?}", - buffer, external_def_id - ); - let visible_parent_map = self.visible_parent_map(LOCAL_CRATE); - - let (mut cur_def, mut cur_path) = (external_def_id, Vec::::new()); - loop { - debug!( - "try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}", - cur_def, cur_path, CRATE_DEF_INDEX, - ); - // If `cur_def` is a direct or injected extern crate, push the path to the crate - // followed by the path to the item within the crate and return. - if cur_def.index == CRATE_DEF_INDEX { - match *self.extern_crate(cur_def) { - Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - .. - }) => { - debug!("try_push_visible_item_path: def_id={:?}", def_id); - self.push_item_path(buffer, def_id, pushed_prelude_crate); - cur_path.iter().rev().for_each(|segment| buffer.push(&segment)); - return true; - } - None => { - buffer.push(&self.crate_name(cur_def.krate).as_str()); - cur_path.iter().rev().for_each(|segment| buffer.push(&segment)); - return true; - } - _ => {}, - } - } - - let mut cur_def_key = self.def_key(cur_def); - debug!("try_push_visible_item_path: cur_def_key={:?}", cur_def_key); - - // For a UnitStruct or TupleStruct we want the name of its parent rather than . - if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { - let parent = DefId { - krate: cur_def.krate, - index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), - }; - - cur_def_key = self.def_key(parent); - } - - let visible_parent = visible_parent_map.get(&cur_def).cloned(); - let actual_parent = self.parent(cur_def); - - let data = cur_def_key.disambiguated_data.data; - debug!( - "try_push_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", - data, visible_parent, actual_parent, - ); - let symbol = match data { - // In order to output a path that could actually be imported (valid and visible), - // we need to handle re-exports correctly. - // - // For example, take `std::os::unix::process::CommandExt`, this trait is actually - // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). - // - // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is - // private so the "true" path to `CommandExt` isn't accessible. - // - // In this case, the `visible_parent_map` will look something like this: - // - // (child) -> (parent) - // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` - // `std::sys::unix::ext::process` -> `std::sys::unix::ext` - // `std::sys::unix::ext` -> `std::os` - // - // This is correct, as the visible parent of `std::sys::unix::ext` is in fact - // `std::os`. - // - // When printing the path to `CommandExt` and looking at the `cur_def_key` that - // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go - // to the parent - resulting in a mangled path like - // `std::os::ext::process::CommandExt`. - // - // Instead, we must detect that there was a re-export and instead print `unix` - // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To - // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with - // the visible parent (`std::os`). If these do not match, then we iterate over - // the children of the visible parent (as was done when computing - // `visible_parent_map`), looking for the specific child we currently have and then - // have access to the re-exported name. - DefPathData::Module(actual_name) | - DefPathData::TypeNs(actual_name) if visible_parent != actual_parent => { - visible_parent - .and_then(|parent| { - self.item_children(parent) - .iter() - .find(|child| child.def.def_id() == cur_def) - .map(|child| child.ident.as_str()) - }) - .unwrap_or_else(|| actual_name.as_str()) - }, - _ => { - data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { - // Re-exported `extern crate` (#43189). - if let DefPathData::CrateRoot = data { - self.original_crate_name(cur_def.krate).as_str() - } else { - Symbol::intern("").as_str() - } - }) - }, - }; - debug!("try_push_visible_item_path: symbol={:?}", symbol); - cur_path.push(symbol); - - match visible_parent { - Some(def) => cur_def = def, - None => return false, - }; - } - } - - pub fn push_item_path(self, buffer: &mut T, def_id: DefId, pushed_prelude_crate: bool) - where T: ItemPathBuffer + Debug - { - debug!( - "push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}", - buffer, def_id, pushed_prelude_crate - ); - match *buffer.root_mode() { - RootMode::Local if !def_id.is_local() => - if self.try_push_visible_item_path(buffer, def_id, pushed_prelude_crate) { return }, - _ => {} - } - - let key = self.def_key(def_id); - debug!("push_item_path: key={:?}", key); - match key.disambiguated_data.data { - DefPathData::CrateRoot => { - assert!(key.parent.is_none()); - self.push_krate_path(buffer, def_id.krate, pushed_prelude_crate); - } - - DefPathData::Impl => { - self.push_impl_path(buffer, def_id, pushed_prelude_crate); - } - - // Unclear if there is any value in distinguishing these. - // Probably eventually (and maybe we would even want - // finer-grained distinctions, e.g., between enum/struct). - data @ DefPathData::Misc | - data @ DefPathData::TypeNs(..) | - data @ DefPathData::Trait(..) | - data @ DefPathData::TraitAlias(..) | - data @ DefPathData::AssocTypeInTrait(..) | - data @ DefPathData::AssocTypeInImpl(..) | - data @ DefPathData::AssocExistentialInImpl(..) | - data @ DefPathData::ValueNs(..) | - data @ DefPathData::Module(..) | - data @ DefPathData::TypeParam(..) | - data @ DefPathData::LifetimeParam(..) | - data @ DefPathData::ConstParam(..) | - data @ DefPathData::EnumVariant(..) | - data @ DefPathData::Field(..) | - data @ DefPathData::AnonConst | - data @ DefPathData::MacroDef(..) | - data @ DefPathData::ClosureExpr | - data @ DefPathData::ImplTrait | - data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.parent_def_id(def_id).unwrap(); - - // Keep track of whether we are one recursion away from the `CrateRoot` and - // pushing the name of a prelude crate. If we are, we'll want to know this when - // printing the `CrateRoot` so we don't prepend a `crate::` to paths. - let mut is_prelude_crate = false; - if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data { - if self.extern_prelude.contains_key(&data.as_interned_str().as_symbol()) { - is_prelude_crate = true; - } - } - - self.push_item_path( - buffer, parent_did, pushed_prelude_crate || is_prelude_crate - ); - buffer.push(&data.as_interned_str().as_symbol().as_str()); - }, - - DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` - let parent_def_id = self.parent_def_id(def_id).unwrap(); - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); - } - } - } - - fn push_impl_path( - self, - buffer: &mut T, - impl_def_id: DefId, - pushed_prelude_crate: bool, - ) - where T: ItemPathBuffer + Debug - { - debug!("push_impl_path: buffer={:?} impl_def_id={:?}", buffer, impl_def_id); - let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); - - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = !impl_def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - return self.push_impl_path_fallback(buffer, impl_def_id, pushed_prelude_crate); - } - - // Decide whether to print the parent path for the impl. - // Logically, since impls are global, it's never needed, but - // users may find it useful. Currently, we omit the parent if - // the impl is either in the same module as the self-type or - // as the trait. - let self_ty = self.type_of(impl_def_id); - let in_self_mod = match characteristic_def_id_of_type(self_ty) { - None => false, - Some(ty_def_id) => self.parent_def_id(ty_def_id) == Some(parent_def_id), - }; - - let impl_trait_ref = self.impl_trait_ref(impl_def_id); - let in_trait_mod = match impl_trait_ref { - None => false, - Some(trait_ref) => self.parent_def_id(trait_ref.def_id) == Some(parent_def_id), - }; - - if !in_self_mod && !in_trait_mod { - // If the impl is not co-located with either self-type or - // trait-type, then fallback to a format that identifies - // the module more clearly. - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); - if let Some(trait_ref) = impl_trait_ref { - buffer.push(&format!("", trait_ref, self_ty)); - } else { - buffer.push(&format!("", self_ty)); - } - return; - } - - // Otherwise, try to give a good form that would be valid language - // syntax. Preferably using associated item notation. - - if let Some(trait_ref) = impl_trait_ref { - // Trait impls. - buffer.push(&format!("<{} as {}>", self_ty, trait_ref)); - return; - } - - // Inherent impls. Try to print `Foo::bar` for an inherent - // impl on `Foo`, but fallback to `::bar` if self-type is - // anything other than a simple path. - match self_ty.sty { - ty::Adt(adt_def, substs) => { - if substs.types().next().is_none() { // ignore regions - self.push_item_path(buffer, adt_def.did, pushed_prelude_crate); - } else { - buffer.push(&format!("<{}>", self_ty)); - } - } - - ty::Foreign(did) => self.push_item_path(buffer, did, pushed_prelude_crate), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::Str => { - buffer.push(&self_ty.to_string()); - } - - _ => { - buffer.push(&format!("<{}>", self_ty)); - } - } - } - - fn push_impl_path_fallback( - self, - buffer: &mut T, - impl_def_id: DefId, - pushed_prelude_crate: bool, - ) - where T: ItemPathBuffer + Debug - { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); - let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap(); - let item = self.hir().expect_item_by_hir_id(hir_id); - let span_str = self.sess.source_map().span_to_string(item.span); - buffer.push(&format!("", span_str)); - } - - /// Returns the `DefId` of `def_id`'s parent in the def tree. If - /// this returns `None`, then `def_id` represents a crate root or - /// inlined root. - pub fn parent_def_id(self, def_id: DefId) -> Option { - let key = self.def_key(def_id); - key.parent.map(|index| DefId { krate: def_id.krate, index: index }) - } -} - -/// As a heuristic, when we see an impl, if we see that the -/// 'self type' is a type defined in the same module as the impl, -/// we can omit including the path to the impl itself. This -/// function tries to find a "characteristic `DefId`" for a -/// type. It's just a heuristic so it makes some questionable -/// decisions and we may want to adjust it later. -pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Adt(adt_def, _) => Some(adt_def.did), - - ty::Dynamic(data, ..) => data.principal_def_id(), - - ty::Array(subty, _) | - ty::Slice(subty) => characteristic_def_id_of_type(subty), - - ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty), - - ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty), - - ty::Tuple(ref tys) => tys.iter() - .filter_map(|ty| characteristic_def_id_of_type(ty)) - .next(), - - ty::FnDef(def_id, _) | - ty::Closure(def_id, _) | - ty::Generator(def_id, _, _) | - ty::Foreign(def_id) => Some(def_id), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Str | - ty::FnPtr(_) | - ty::Projection(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Param(_) | - ty::Opaque(..) | - ty::Infer(_) | - ty::Bound(..) | - ty::Error | - ty::GeneratorWitness(..) | - ty::Never | - ty::Float(_) => None, - } -} - -/// Unifying Trait for different kinds of item paths we might -/// construct. The basic interface is that components get pushed: the -/// instance can also customize how we handle the root of a crate. -pub trait ItemPathBuffer { - fn root_mode(&self) -> &RootMode; - fn push(&mut self, text: &str); -} - -#[derive(Debug)] -pub enum RootMode { - /// Try to make a path relative to the local crate. In - /// particular, local paths have no prefix, and if the path comes - /// from an extern crate, start with the path to the `extern - /// crate` declaration. - Local, - - /// Always prepend the crate name to the path, forming an absolute - /// path from within a given set of crates. - Absolute, -} - -#[derive(Debug)] -struct LocalPathBuffer { - root_mode: RootMode, - str: String, -} - -impl LocalPathBuffer { - fn new(root_mode: RootMode) -> LocalPathBuffer { - LocalPathBuffer { - root_mode, - str: String::new(), - } - } - - fn into_string(self) -> String { - self.str - } -} - -impl ItemPathBuffer for LocalPathBuffer { - fn root_mode(&self) -> &RootMode { - &self.root_mode - } - - fn push(&mut self, text: &str) { - if !self.str.is_empty() { - self.str.push_str("::"); - } - self.str.push_str(text); - } -} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 68bdae7d744c5..882e2dc62b1c3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -95,10 +95,10 @@ mod erase_regions; pub mod fast_reject; pub mod fold; pub mod inhabitedness; -pub mod item_path; pub mod layout; pub mod _match; pub mod outlives; +pub mod print; pub mod query; pub mod relate; pub mod steal; @@ -1000,7 +1000,7 @@ impl<'a, 'gcx, 'tcx> Generics { } /// Bounds on generics. -#[derive(Clone, Default, HashStable)] +#[derive(Clone, Default, Debug, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: Vec<(Predicate<'tcx>, Span)>, @@ -1505,7 +1505,7 @@ impl<'tcx> Predicate<'tcx> { /// `[[], [U:Bar]]`. Now if there were some particular reference /// like `Foo`, then the `InstantiatedPredicates` would be `[[], /// [usize:Bar]]`. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct InstantiatedPredicates<'tcx> { pub predicates: Vec>, } @@ -2055,7 +2055,7 @@ impl ReprOptions { } // This is here instead of layout because the choice must make it into metadata. - if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) { + if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) { flags.insert(ReprFlags::IS_LINEAR); } ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags } @@ -2892,14 +2892,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef { match def { Def::Variant(did) | Def::VariantCtor(did, ..) => { - let enum_did = self.parent_def_id(did).unwrap(); + let enum_did = self.parent(did).unwrap(); self.adt_def(enum_did).variant_with_id(did) } Def::Struct(did) | Def::Union(did) => { self.adt_def(did).non_enum_variant() } Def::StructCtor(ctor_did, ..) => { - let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent"); + let did = self.parent(ctor_did).expect("struct ctor has no parent"); self.adt_def(did).non_enum_variant() } _ => bug!("expect_variant_def used with unexpected def {:?}", def) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs new file mode 100644 index 0000000000000..ef30a4032d8fa --- /dev/null +++ b/src/librustc/ty/print/mod.rs @@ -0,0 +1,327 @@ +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; +use crate::hir::def_id::{CrateNum, DefId}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::ty::subst::{Kind, Subst}; + +use rustc_data_structures::fx::FxHashSet; + +// `pretty` is a separate module only for organization. +mod pretty; +pub use self::pretty::*; + +pub trait Print<'gcx, 'tcx, P> { + type Output; + type Error; + + fn print(&self, cx: P) -> Result; +} + +/// Interface for outputting user-facing "type-system entities" +/// (paths, types, lifetimes, constants, etc.) as a side-effect +/// (e.g. formatting, like `PrettyPrinter` implementors do) or by +/// constructing some alternative representation (e.g. an AST), +/// which the associated types allow passing through the methods. +/// +/// For pretty-printing/formatting in particular, see `PrettyPrinter`. +// FIXME(eddyb) find a better name, this is more general than "printing". +pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { + type Error; + + type Path; + type Region; + type Type; + type DynExistential; + + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; + + fn print_def_path( + self, + def_id: DefId, + substs: &'tcx [Kind<'tcx>], + ) -> Result { + self.default_print_def_path(def_id, substs) + } + fn print_impl_path( + self, + impl_def_id: DefId, + substs: &'tcx [Kind<'tcx>], + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref) + } + + fn print_region( + self, + region: ty::Region<'_>, + ) -> Result; + + fn print_type( + self, + ty: Ty<'tcx>, + ) -> Result; + + fn print_dyn_existential( + self, + predicates: &'tcx ty::List>, + ) -> Result; + + fn path_crate( + self, + cnum: CrateNum, + ) -> Result; + fn path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result; + + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result; + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result; + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, + args: &[Kind<'tcx>], + ) -> Result; + + // Defaults (should not be overriden): + + fn default_print_def_path( + self, + def_id: DefId, + substs: &'tcx [Kind<'tcx>], + ) -> Result { + debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); + let key = self.tcx().def_key(def_id); + debug!("default_print_def_path: key={:?}", key); + + match key.disambiguated_data.data { + DefPathData::CrateRoot => { + assert!(key.parent.is_none()); + self.path_crate(def_id.krate) + } + + DefPathData::Impl => { + let generics = self.tcx().generics_of(def_id); + let mut self_ty = self.tcx().type_of(def_id); + let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); + if substs.len() >= generics.count() { + self_ty = self_ty.subst(self.tcx(), substs); + impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs); + } + self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) + } + + _ => { + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + + let mut parent_substs = substs; + let mut trait_qualify_parent = false; + if !substs.is_empty() { + let generics = self.tcx().generics_of(def_id); + parent_substs = &substs[..generics.parent_count.min(substs.len())]; + + match key.disambiguated_data.data { + // Closures' own generics are only captures, don't print them. + DefPathData::ClosureExpr => {} + + // If we have any generic arguments to print, we do that + // on top of the same path, but without its own generics. + _ => if !generics.params.is_empty() && substs.len() >= generics.count() { + let args = self.generic_args_to_print(generics, substs); + return self.path_generic_args( + |cx| cx.print_def_path(def_id, parent_substs), + args, + ); + } + } + + // FIXME(eddyb) try to move this into the parent's printing + // logic, instead of doing it when printing the child. + trait_qualify_parent = + generics.has_self && + generics.parent == Some(parent_def_id) && + parent_substs.len() == generics.parent_count && + self.tcx().generics_of(parent_def_id).parent_count == 0; + } + + self.path_append( + |cx: Self| if trait_qualify_parent { + let trait_ref = ty::TraitRef::new( + parent_def_id, + cx.tcx().intern_substs(parent_substs), + ); + cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) + } else { + cx.print_def_path(parent_def_id, parent_substs) + }, + &key.disambiguated_data, + ) + } + } + } + + fn generic_args_to_print( + &self, + generics: &'tcx ty::Generics, + substs: &'tcx [Kind<'tcx>], + ) -> &'tcx [Kind<'tcx>] { + let mut own_params = generics.parent_count..generics.count(); + + // Don't print args for `Self` parameters (of traits). + if generics.has_self && own_params.start == 0 { + own_params.start = 1; + } + + // Don't print args that are the defaults of their respective parameters. + own_params.end -= generics.params.iter().rev().take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default && substs[param.index as usize] == Kind::from( + self.tcx().type_of(param.def_id).subst(self.tcx(), substs) + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) + } + }).count(); + + &substs[own_params] + } + + fn default_print_impl_path( + self, + impl_def_id: DefId, + _substs: &'tcx [Kind<'tcx>], + self_ty: Ty<'tcx>, + impl_trait_ref: Option>, + ) -> Result { + debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", + impl_def_id, self_ty, impl_trait_ref); + + let key = self.tcx().def_key(impl_def_id); + let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; + + // Decide whether to print the parent path for the impl. + // Logically, since impls are global, it's never needed, but + // users may find it useful. Currently, we omit the parent if + // the impl is either in the same module as the self-type or + // as the trait. + let in_self_mod = match characteristic_def_id_of_type(self_ty) { + None => false, + Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id), + }; + let in_trait_mod = match impl_trait_ref { + None => false, + Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id), + }; + + if !in_self_mod && !in_trait_mod { + // If the impl is not co-located with either self-type or + // trait-type, then fallback to a format that identifies + // the module more clearly. + self.path_append_impl( + |cx| cx.print_def_path(parent_def_id, &[]), + &key.disambiguated_data, + self_ty, + impl_trait_ref, + ) + } else { + // Otherwise, try to give a good form that would be valid language + // syntax. Preferably using associated item notation. + self.path_qualified(self_ty, impl_trait_ref) + } + } +} + +/// As a heuristic, when we see an impl, if we see that the +/// 'self type' is a type defined in the same module as the impl, +/// we can omit including the path to the impl itself. This +/// function tries to find a "characteristic `DefId`" for a +/// type. It's just a heuristic so it makes some questionable +/// decisions and we may want to adjust it later. +pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { + match ty.sty { + ty::Adt(adt_def, _) => Some(adt_def.did), + + ty::Dynamic(data, ..) => data.principal_def_id(), + + ty::Array(subty, _) | + ty::Slice(subty) => characteristic_def_id_of_type(subty), + + ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty), + + ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty), + + ty::Tuple(ref tys) => tys.iter() + .filter_map(|ty| characteristic_def_id_of_type(ty)) + .next(), + + ty::FnDef(def_id, _) | + ty::Closure(def_id, _) | + ty::Generator(def_id, _, _) | + ty::Foreign(def_id) => Some(def_id), + + ty::Bool | + ty::Char | + ty::Int(_) | + ty::Uint(_) | + ty::Str | + ty::FnPtr(_) | + ty::Projection(_) | + ty::Placeholder(..) | + ty::UnnormalizedProjection(..) | + ty::Param(_) | + ty::Opaque(..) | + ty::Infer(_) | + ty::Bound(..) | + ty::Error | + ty::GeneratorWitness(..) | + ty::Never | + ty::Float(_) => None, + } +} + +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind { + type Output = P::Region; + type Error = P::Error; + fn print(&self, cx: P) -> Result { + cx.print_region(self) + } +} + +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> { + type Output = P::Region; + type Error = P::Error; + fn print(&self, cx: P) -> Result { + cx.print_region(self) + } +} + +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> { + type Output = P::Type; + type Error = P::Error; + fn print(&self, cx: P) -> Result { + cx.print_type(self) + } +} + +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for &'tcx ty::List> +{ + type Output = P::DynExistential; + type Error = P::Error; + fn print(&self, cx: P) -> Result { + cx.print_dyn_existential(self) + } +} diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs new file mode 100644 index 0000000000000..fa57e0b96745a --- /dev/null +++ b/src/librustc/ty/print/pretty.rs @@ -0,0 +1,1621 @@ +use crate::hir; +use crate::hir::def::Namespace; +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::middle::cstore::{ExternCrate, ExternCrateSource}; +use crate::middle::region; +use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; +use crate::ty::subst::{Kind, Subst, UnpackedKind}; +use crate::mir::interpret::ConstValue; +use syntax::symbol::{keywords, Symbol}; + +use rustc_target::spec::abi::Abi; +use syntax::symbol::InternedString; + +use std::cell::Cell; +use std::fmt::{self, Write as _}; +use std::ops::{Deref, DerefMut}; + +// `pretty` is a separate module only for organization. +use super::*; + +macro_rules! p { + (@write($($data:expr),+)) => { + write!(scoped_cx!(), $($data),+)? + }; + (@print($x:expr)) => { + scoped_cx!() = $x.print(scoped_cx!())? + }; + (@$method:ident($($arg:expr),*)) => { + scoped_cx!() = scoped_cx!().$method($($arg),*)? + }; + ($($kind:ident $data:tt),+) => {{ + $(p!(@$kind $data);)+ + }}; +} +macro_rules! define_scoped_cx { + ($cx:ident) => { + #[allow(unused_macros)] + macro_rules! scoped_cx { + () => ($cx) + } + }; +} + +thread_local! { + static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); + static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); +} + +/// Force us to name impls with just the filename/line number. We +/// normally try to use types. But at some points, notably while printing +/// cycle errors, this can result in extra or suboptimal error output, +/// so this variable disables that check. +pub fn with_forced_impl_filename_line R, R>(f: F) -> R { + FORCE_IMPL_FILENAME_LINE.with(|force| { + let old = force.get(); + force.set(true); + let result = f(); + force.set(old); + result + }) +} + +/// Adds the `crate::` prefix to paths where appropriate. +pub fn with_crate_prefix R, R>(f: F) -> R { + SHOULD_PREFIX_WITH_CRATE.with(|flag| { + let old = flag.get(); + flag.set(true); + let result = f(); + flag.set(old); + result + }) +} + +/// The "region highlights" are used to control region printing during +/// specific error messages. When a "region highlight" is enabled, it +/// gives an alternate way to print specific regions. For now, we +/// always print those regions using a number, so something like "`'0`". +/// +/// Regions not selected by the region highlight mode are presently +/// unaffected. +#[derive(Copy, Clone, Default)] +pub struct RegionHighlightMode { + /// If enabled, when we see the selected region, use "`'N`" + /// instead of the ordinary behavior. + highlight_regions: [Option<(ty::RegionKind, usize)>; 3], + + /// If enabled, when printing a "free region" that originated from + /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily + /// have names print as normal. + /// + /// This is used when you have a signature like `fn foo(x: &u32, + /// y: &'a u32)` and we want to give a name to the region of the + /// reference `x`. + highlight_bound_region: Option<(ty::BoundRegion, usize)>, +} + +impl RegionHighlightMode { + /// If `region` and `number` are both `Some`, invokes + /// `highlighting_region`. + pub fn maybe_highlighting_region( + &mut self, + region: Option>, + number: Option, + ) { + if let Some(k) = region { + if let Some(n) = number { + self.highlighting_region(k, n); + } + } + } + + /// Highlights the region inference variable `vid` as `'N`. + pub fn highlighting_region( + &mut self, + region: ty::Region<'_>, + number: usize, + ) { + let num_slots = self.highlight_regions.len(); + let first_avail_slot = self.highlight_regions.iter_mut() + .filter(|s| s.is_none()) + .next() + .unwrap_or_else(|| { + bug!( + "can only highlight {} placeholders at a time", + num_slots, + ) + }); + *first_avail_slot = Some((*region, number)); + } + + /// Convenience wrapper for `highlighting_region`. + pub fn highlighting_region_vid( + &mut self, + vid: ty::RegionVid, + number: usize, + ) { + self.highlighting_region(&ty::ReVar(vid), number) + } + + /// Returns `Some(n)` with the number to use for the given region, if any. + fn region_highlighted(&self, region: ty::Region<'_>) -> Option { + self + .highlight_regions + .iter() + .filter_map(|h| match h { + Some((r, n)) if r == region => Some(*n), + _ => None, + }) + .next() + } + + /// Highlight the given bound region. + /// We can only highlight one bound region at a time. See + /// the field `highlight_bound_region` for more detailed notes. + pub fn highlighting_bound_region( + &mut self, + br: ty::BoundRegion, + number: usize, + ) { + assert!(self.highlight_bound_region.is_none()); + self.highlight_bound_region = Some((br, number)); + } +} + +/// Trait for printers that pretty-print using `fmt::Write` to the printer. +pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: + Printer<'gcx, 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + > + + fmt::Write +{ + /// Like `print_def_path` but for value paths. + fn print_value_path( + self, + def_id: DefId, + substs: &'tcx [Kind<'tcx>], + ) -> Result { + self.print_def_path(def_id, substs) + } + + fn in_binder( + self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + value.skip_binder().print(self) + } + + /// Print comma-separated elements. + fn comma_sep( + mut self, + mut elems: impl Iterator, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + { + if let Some(first) = elems.next() { + self = first.print(self)?; + for elem in elems { + self.write_str(", ")?; + self = elem.print(self)?; + } + } + Ok(self) + } + + /// Print `<...>` around what `f` prints. + fn generic_delimiters( + self, + f: impl FnOnce(Self) -> Result, + ) -> Result; + + /// Return `true` if the region should be printed in + /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. + /// This is typically the case for all non-`'_` regions. + fn region_should_not_be_omitted( + &self, + region: ty::Region<'_>, + ) -> bool; + + // Defaults (should not be overriden): + + /// If possible, this returns a global path resolving to `def_id` that is visible + /// from at least one local module and returns true. If the crate defining `def_id` is + /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. + fn try_print_visible_def_path( + mut self, + def_id: DefId, + ) -> Result<(Self, bool), Self::Error> { + define_scoped_cx!(self); + + debug!("try_print_visible_def_path: def_id={:?}", def_id); + + // If `def_id` is a direct or injected extern crate, return the + // path to the crate followed by the path to the item within the crate. + if def_id.index == CRATE_DEF_INDEX { + let cnum = def_id.krate; + + if cnum == LOCAL_CRATE { + return Ok((self.path_crate(cnum)?, true)); + } + + // In local mode, when we encounter a crate other than + // LOCAL_CRATE, execution proceeds in one of two ways: + // + // 1. for a direct dependency, where user added an + // `extern crate` manually, we put the `extern + // crate` as the parent. So you wind up with + // something relative to the current crate. + // 2. for an extern inferred from a path or an indirect crate, + // where there is no explicit `extern crate`, we just prepend + // the crate name. + match *self.tcx().extern_crate(def_id) { + Some(ExternCrate { + src: ExternCrateSource::Extern(def_id), + direct: true, + span, + .. + }) => { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + return Ok((if !span.is_dummy() { + self.print_def_path(def_id, &[])? + } else { + self.path_crate(cnum)? + }, true)); + } + None => { + return Ok((self.path_crate(cnum)?, true)); + } + _ => {}, + } + } + + if def_id.is_local() { + return Ok((self, false)); + } + + let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE); + + let mut cur_def_key = self.tcx().def_key(def_id); + debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); + + // For a UnitStruct or TupleStruct we want the name of its parent rather than . + if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { + let parent = DefId { + krate: def_id.krate, + index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), + }; + + cur_def_key = self.tcx().def_key(parent); + } + + let visible_parent = match visible_parent_map.get(&def_id).cloned() { + Some(parent) => parent, + None => return Ok((self, false)), + }; + // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid + // knowing ahead of time whether the entire path will succeed or not. + // To support printers that do not implement `PrettyPrinter`, a `Vec` or + // linked list on the stack would need to be built, before any printing. + match self.try_print_visible_def_path(visible_parent)? { + (cx, false) => return Ok((cx, false)), + (cx, true) => self = cx, + } + let actual_parent = self.tcx().parent(def_id); + debug!( + "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", + visible_parent, actual_parent, + ); + + let mut data = cur_def_key.disambiguated_data.data; + debug!( + "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", + data, visible_parent, actual_parent, + ); + + match data { + // In order to output a path that could actually be imported (valid and visible), + // we need to handle re-exports correctly. + // + // For example, take `std::os::unix::process::CommandExt`, this trait is actually + // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). + // + // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is + // private so the "true" path to `CommandExt` isn't accessible. + // + // In this case, the `visible_parent_map` will look something like this: + // + // (child) -> (parent) + // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` + // `std::sys::unix::ext::process` -> `std::sys::unix::ext` + // `std::sys::unix::ext` -> `std::os` + // + // This is correct, as the visible parent of `std::sys::unix::ext` is in fact + // `std::os`. + // + // When printing the path to `CommandExt` and looking at the `cur_def_key` that + // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go + // to the parent - resulting in a mangled path like + // `std::os::ext::process::CommandExt`. + // + // Instead, we must detect that there was a re-export and instead print `unix` + // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To + // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with + // the visible parent (`std::os`). If these do not match, then we iterate over + // the children of the visible parent (as was done when computing + // `visible_parent_map`), looking for the specific child we currently have and then + // have access to the re-exported name. + DefPathData::Module(ref mut name) | + DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { + let reexport = self.tcx().item_children(visible_parent) + .iter() + .find(|child| child.def.def_id() == def_id) + .map(|child| child.ident.as_interned_str()); + if let Some(reexport) = reexport { + *name = reexport; + } + } + // Re-exported `extern crate` (#43189). + DefPathData::CrateRoot => { + data = DefPathData::Module( + self.tcx().original_crate_name(def_id.krate).as_interned_str(), + ); + } + _ => {} + } + debug!("try_print_visible_def_path: data={:?}", data); + + Ok((self.path_append(Ok, &DisambiguatedDefPathData { + data, + disambiguator: 0, + })?, true)) + } + + fn pretty_path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + if trait_ref.is_none() { + // Inherent impls. Try to print `Foo::bar` for an inherent + // impl on `Foo`, but fallback to `::bar` if self-type is + // anything other than a simple path. + match self_ty.sty { + ty::Adt(..) | ty::Foreign(_) | + ty::Bool | ty::Char | ty::Str | + ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + return self_ty.print(self); + } + + _ => {} + } + } + + self.generic_delimiters(|mut cx| { + define_scoped_cx!(cx); + + p!(print(self_ty)); + if let Some(trait_ref) = trait_ref { + p!(write(" as "), print(trait_ref)); + } + Ok(cx) + }) + } + + fn pretty_path_append_impl( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = print_prefix(self)?; + + self.generic_delimiters(|mut cx| { + define_scoped_cx!(cx); + + p!(write("impl ")); + if let Some(trait_ref) = trait_ref { + p!(print(trait_ref), write(" for ")); + } + p!(print(self_ty)); + + Ok(cx) + }) + } + + fn pretty_print_type( + mut self, + ty: Ty<'tcx>, + ) -> Result { + define_scoped_cx!(self); + + match ty.sty { + ty::Bool => p!(write("bool")), + ty::Char => p!(write("char")), + ty::Int(t) => p!(write("{}", t.ty_to_string())), + ty::Uint(t) => p!(write("{}", t.ty_to_string())), + ty::Float(t) => p!(write("{}", t.ty_to_string())), + ty::RawPtr(ref tm) => { + p!(write("*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })); + p!(print(tm.ty)) + } + ty::Ref(r, ty, mutbl) => { + p!(write("&")); + if self.region_should_not_be_omitted(r) { + p!(print(r), write(" ")); + } + p!(print(ty::TypeAndMut { ty, mutbl })) + } + ty::Never => p!(write("!")), + ty::Tuple(ref tys) => { + p!(write("(")); + let mut tys = tys.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty), write(",")); + if let Some(&ty) = tys.next() { + p!(write(" "), print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } + } + p!(write(")")) + } + ty::FnDef(def_id, substs) => { + let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); + p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}")); + } + ty::FnPtr(ref bare_fn) => { + p!(print(bare_fn)) + } + ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Error => p!(write("[type error]")), + ty::Param(ref param_ty) => p!(write("{}", param_ty)), + ty::Bound(debruijn, bound_ty) => { + match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) + } + } + + ty::BoundTyKind::Param(p) => p!(write("{}", p)), + } + } + ty::Adt(def, substs) => { + p!(print_def_path(def.did, substs)); + } + ty::Dynamic(data, r) => { + let print_r = self.region_should_not_be_omitted(r); + if print_r { + p!(write("(")); + } + p!(write("dyn "), print(data)); + if print_r { + p!(write(" + "), print(r), write(")")); + } + } + ty::Foreign(def_id) => { + p!(print_def_path(def_id, &[])); + } + ty::Projection(ref data) => p!(print(data)), + ty::UnnormalizedProjection(ref data) => { + p!(write("Unnormalized("), print(data), write(")")) + } + ty::Placeholder(placeholder) => { + p!(write("Placeholder({:?})", placeholder)) + } + ty::Opaque(def_id, substs) => { + // FIXME(eddyb) print this with `print_def_path`. + if self.tcx().sess.verbose() { + p!(write("Opaque({:?}, {:?})", def_id, substs)); + return Ok(self); + } + + let def_key = self.tcx().def_key(def_id); + if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { + p!(write("{}", name)); + let mut substs = substs.iter(); + // FIXME(eddyb) print this with `print_def_path`. + if let Some(first) = substs.next() { + p!(write("::<")); + p!(print(first)); + for subst in substs { + p!(write(", "), print(subst)); + } + p!(write(">")); + } + return Ok(self); + } + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs); + + let mut first = true; + let mut is_sized = false; + p!(write("impl")); + for predicate in bounds.predicates { + if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { + // Don't print +Sized, but rather +?Sized if absent. + if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { + is_sized = true; + continue; + } + + p!( + write("{}", if first { " " } else { "+" }), + print(trait_ref)); + first = false; + } + } + if !is_sized { + p!(write("{}?Sized", if first { " " } else { "+" })); + } else if first { + p!(write(" Sized")); + } + } + ty::Str => p!(write("str")), + ty::Generator(did, substs, movability) => { + let upvar_tys = substs.upvar_tys(did, self.tcx()); + let witness = substs.witness(did, self.tcx()); + if movability == hir::GeneratorMovability::Movable { + p!(write("[generator")); + } else { + p!(write("[static generator")); + } + + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx().freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx().hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), + print(upvar_ty)); + sep = ", "; + } + } + + p!(write(" "), print(witness), write("]")) + }, + ty::GeneratorWitness(types) => { + p!(in_binder(&types)); + } + ty::Closure(did, substs) => { + let upvar_tys = substs.upvar_tys(did, self.tcx()); + p!(write("[closure")); + + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + if self.tcx().sess.opts.debugging_opts.span_free_formats { + p!(write("@{:?}", hir_id)); + } else { + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); + } + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx().freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx().hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), + print(upvar_ty)); + sep = ", "; + } + } + + if self.tcx().sess.verbose() { + p!(write( + " closure_kind_ty={:?} closure_sig_ty={:?}", + substs.closure_kind_ty(did, self.tcx()), + substs.closure_sig_ty(did, self.tcx()) + )); + } + + p!(write("]")) + }, + ty::Array(ty, sz) => { + p!(write("["), print(ty), write("; ")); + match sz { + ty::LazyConst::Unevaluated(_def_id, _substs) => { + p!(write("_")); + } + ty::LazyConst::Evaluated(c) => { + match c.val { + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => + p!(write("{}", name)), + _ => p!(write("{}", c.unwrap_usize(self.tcx()))), + } + } + } + p!(write("]")) + } + ty::Slice(ty) => { + p!(write("["), print(ty), write("]")) + } + } + + Ok(self) + } + + fn pretty_print_dyn_existential( + mut self, + predicates: &'tcx ty::List>, + ) -> Result { + define_scoped_cx!(self); + + // Generate the main trait ref, including associated types. + let mut first = true; + + if let Some(principal) = predicates.principal() { + p!(print_def_path(principal.def_id, &[])); + + let mut resugared = false; + + // Special-case `Fn(...) -> ...` and resugar it. + let fn_trait_kind = self.tcx().lang_items().fn_trait_kind(principal.def_id); + if !self.tcx().sess.verbose() && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { + let mut projections = predicates.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + p!(pretty_fn_sig(args, false, proj.ty)); + resugared = true; + } + } + } + + // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`, + // in order to place the projections inside the `<...>`. + if !resugared { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = self.tcx().mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(self.tcx(), dummy_self); + + let args = self.generic_args_to_print( + self.tcx().generics_of(principal.def_id), + principal.substs, + ); + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let mut args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + let mut projections = predicates.projection_bounds(); + + let arg0 = args.next(); + let projection0 = projections.next(); + if arg0.is_some() || projection0.is_some() { + let args = arg0.into_iter().chain(args); + let projections = projection0.into_iter().chain(projections); + + p!(generic_delimiters(|mut cx| { + cx = cx.comma_sep(args)?; + if arg0.is_some() && projection0.is_some() { + write!(cx, ", ")?; + } + cx.comma_sep(projections) + })); + } + } + first = false; + } + + // Builtin bounds. + // FIXME(eddyb) avoid printing twice (needed to ensure + // that the auto traits are sorted *and* printed via cx). + let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { + (self.tcx().def_path_str(did), did) + }).collect(); + + // The auto traits come ordered by `DefPathHash`. While + // `DefPathHash` is *stable* in the sense that it depends on + // neither the host nor the phase of the moon, it depends + // "pseudorandomly" on the compiler version and the target. + // + // To avoid that causing instabilities in compiletest + // output, sort the auto-traits alphabetically. + auto_traits.sort(); + + for (_, def_id) in auto_traits { + if !first { + p!(write(" + ")); + } + first = false; + + p!(print_def_path(def_id, &[])); + } + + Ok(self) + } + + fn pretty_fn_sig( + mut self, + inputs: &[Ty<'tcx>], + c_variadic: bool, + output: Ty<'tcx>, + ) -> Result { + define_scoped_cx!(self); + + p!(write("(")); + let mut inputs = inputs.iter(); + if let Some(&ty) = inputs.next() { + p!(print(ty)); + for &ty in inputs { + p!(write(", "), print(ty)); + } + if c_variadic { + p!(write(", ...")); + } + } + p!(write(")")); + if !output.is_unit() { + p!(write(" -> "), print(output)); + } + + Ok(self) + } +} + +// HACK(eddyb) boxed to avoid moving around a large struct by-value. +pub struct FmtPrinter<'a, 'gcx, 'tcx, F>(Box>); + +pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + fmt: F, + + empty_path: bool, + in_value: bool, + + used_region_names: FxHashSet, + region_index: usize, + binder_depth: usize, + + pub region_highlight_mode: RegionHighlightMode, +} + +impl Deref for FmtPrinter<'a, 'gcx, 'tcx, F> { + type Target = FmtPrinterData<'a, 'gcx, 'tcx, F>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for FmtPrinter<'_, '_, '_, F> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl FmtPrinter<'a, 'gcx, 'tcx, F> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fmt: F, ns: Namespace) -> Self { + FmtPrinter(Box::new(FmtPrinterData { + tcx, + fmt, + empty_path: false, + in_value: ns == Namespace::ValueNS, + used_region_names: Default::default(), + region_index: 0, + binder_depth: 0, + region_highlight_mode: RegionHighlightMode::default(), + })) + } +} + +impl TyCtxt<'_, '_, '_> { + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ConstParam(..) | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. + pub fn def_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); + let mut s = String::new(); + let _ = FmtPrinter::new(self, &mut s, ns) + .print_def_path(def_id, &[]); + s + } +} + +impl fmt::Write for FmtPrinter<'_, '_, '_, F> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.fmt.write_str(s) + } +} + +impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + type Error = fmt::Error; + + type Path = Self; + type Region = Self; + type Type = Self; + type DynExistential = Self; + + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + + fn print_def_path( + mut self, + def_id: DefId, + substs: &'tcx [Kind<'tcx>], + ) -> Result { + define_scoped_cx!(self); + + if substs.is_empty() { + match self.try_print_visible_def_path(def_id)? { + (cx, true) => return Ok(cx), + (cx, false) => self = cx, + } + } + + let key = self.tcx.def_key(def_id); + if let DefPathData::Impl = key.disambiguated_data.data { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = + !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let span = self.tcx.def_span(def_id); + + self = self.print_def_path(parent_def_id, &[])?; + + // HACK(eddyb) copy of `path_append` to avoid + // constructing a `DisambiguatedDefPathData`. + if !self.empty_path { + write!(self, "::")?; + } + write!(self, "", span)?; + self.empty_path = false; + + return Ok(self); + } + } + + self.default_print_def_path(def_id, substs) + } + + fn print_region( + self, + region: ty::Region<'_>, + ) -> Result { + self.pretty_print_region(region) + } + + fn print_type( + self, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + + fn print_dyn_existential( + self, + predicates: &'tcx ty::List>, + ) -> Result { + self.pretty_print_dyn_existential(predicates) + } + + fn path_crate( + mut self, + cnum: CrateNum, + ) -> Result { + self.empty_path = true; + if cnum == LOCAL_CRATE { + if self.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + write!(self, "{}", keywords::Crate.name())?; + self.empty_path = false; + } + } + } else { + write!(self, "{}", self.tcx.crate_name(cnum))?; + self.empty_path = false; + } + Ok(self) + } + fn path_qualified( + mut self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_qualified(self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + + fn path_append_impl( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_append_impl(|mut cx| { + cx = print_prefix(cx)?; + if !cx.empty_path { + write!(cx, "::")?; + } + + Ok(cx) + }, self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + self = print_prefix(self)?; + + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::StructCtor => return Ok(self), + _ => {} + } + + // FIXME(eddyb) `name` should never be empty, but it + // currently is for `extern { ... }` "foreign modules". + let name = disambiguated_data.data.as_interned_str().as_str(); + if !name.is_empty() { + if !self.empty_path { + write!(self, "::")?; + } + write!(self, "{}", name)?; + + // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it + // might be nicer to use something else, e.g. `{closure#3}`. + let dis = disambiguated_data.disambiguator; + let print_dis = + disambiguated_data.data.get_opt_name().is_none() || + dis != 0 && self.tcx.sess.verbose(); + if print_dis { + write!(self, "#{}", dis)?; + } + + self.empty_path = false; + } + + Ok(self) + } + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + args: &[Kind<'tcx>], + ) -> Result { + self = print_prefix(self)?; + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + + if args.clone().next().is_some() { + if self.in_value { + write!(self, "::")?; + } + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + Ok(self) + } + } +} + +impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + fn print_value_path( + mut self, + def_id: DefId, + substs: &'tcx [Kind<'tcx>], + ) -> Result { + let was_in_value = std::mem::replace(&mut self.in_value, true); + self = self.print_def_path(def_id, substs)?; + self.in_value = was_in_value; + + Ok(self) + } + + fn in_binder( + self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + self.pretty_in_binder(value) + } + + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, + ) -> Result { + write!(self, "<")?; + + let was_in_value = std::mem::replace(&mut self.in_value, false); + let mut inner = f(self)?; + inner.in_value = was_in_value; + + write!(inner, ">")?; + Ok(inner) + } + + fn region_should_not_be_omitted( + &self, + region: ty::Region<'_>, + ) -> bool { + let highlight = self.region_highlight_mode; + if highlight.region_highlighted(region).is_some() { + return true; + } + + if self.tcx.sess.verbose() { + return true; + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + match *region { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } + + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } + + ty::ReScope(_) | + ty::ReVar(_) if identify_regions => true, + + ty::ReVar(_) | + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. +impl FmtPrinter<'_, '_, '_, F> { + pub fn pretty_print_region( + mut self, + region: ty::Region<'_>, + ) -> Result { + define_scoped_cx!(self); + + // Watch out for region highlights. + let highlight = self.region_highlight_mode; + if let Some(n) = highlight.region_highlighted(region) { + p!(write("'{}", n)); + return Ok(self); + } + + if self.tcx.sess.verbose() { + p!(write("{:?}", region)); + return Ok(self); + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *region { + ty::ReEarlyBound(ref data) => { + if data.name != "" { + p!(write("{}", data.name)); + return Ok(self); + } + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + p!(write("{}", name)); + return Ok(self); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + p!(write("'{}", counter)); + return Ok(self); + } + } + } + ty::ReScope(scope) if identify_regions => { + match scope.data { + region::ScopeData::Node => + p!(write("'{}s", scope.item_local_id().as_usize())), + region::ScopeData::CallSite => + p!(write("'{}cs", scope.item_local_id().as_usize())), + region::ScopeData::Arguments => + p!(write("'{}as", scope.item_local_id().as_usize())), + region::ScopeData::Destruction => + p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => p!(write( + "'{}_{}rs", + scope.item_local_id().as_usize(), + first_statement_index.index() + )), + } + return Ok(self); + } + ty::ReVar(region_vid) if identify_regions => { + p!(write("{:?}", region_vid)); + return Ok(self); + } + ty::ReVar(_) => {} + ty::ReScope(_) | + ty::ReErased => {} + ty::ReStatic => { + p!(write("'static")); + return Ok(self); + } + ty::ReEmpty => { + p!(write("'")); + return Ok(self); + } + + // The user should never encounter these in unsubstituted form. + ty::ReClosureBound(vid) => { + p!(write("{:?}", vid)); + return Ok(self); + } + } + + p!(write("'_")); + + Ok(self) + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, +// `region_index` and `used_region_names`. +impl FmtPrinter<'_, 'gcx, 'tcx, F> { + pub fn pretty_in_binder( + mut self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> + { + fn name_by_region_index(index: usize) -> InternedString { + match index { + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), + }.as_interned_str() + } + + // Replace any anonymous late-bound regions with named + // variants, using gensym'd identifiers, so that we can + // clearly differentiate between named and unnamed regions in + // the output. We'll probably want to tweak this over time to + // decide just how much information to give. + if self.binder_depth == 0 { + self.prepare_late_bound_region_info(value); + } + + let mut empty = true; + let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { + write!(cx, "{}", if empty { + empty = false; + start + } else { + cont + }) + }; + + define_scoped_cx!(self); + + let old_region_index = self.region_index; + let mut region_index = old_region_index; + let new_value = self.tcx.replace_late_bound_regions(value, |br| { + let _ = start_or_continue(&mut self, "for<", ", "); + let br = match br { + ty::BrNamed(_, name) => { + let _ = write!(self, "{}", name); + br + } + ty::BrAnon(_) | + ty::BrFresh(_) | + ty::BrEnv => { + let name = loop { + let name = name_by_region_index(region_index); + region_index += 1; + if !self.used_region_names.contains(&name) { + break name; + } + }; + let _ = write!(self, "{}", name); + ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) + } + }; + self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) + }).0; + start_or_continue(&mut self, "", "> ")?; + + self.binder_depth += 1; + self.region_index = region_index; + let mut inner = new_value.print(self)?; + inner.region_index = old_region_index; + inner.binder_depth -= 1; + Ok(inner) + } + + fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) + where T: TypeFoldable<'tcx> + { + + struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); + impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + match *r { + ty::ReLateBound(_, ty::BrNamed(_, name)) => { + self.0.insert(name); + }, + _ => {}, + } + r.super_visit_with(self) + } + } + + self.used_region_names.clear(); + let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names); + value.visit_with(&mut collector); + self.region_index = 0; + } +} + +impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::Binder + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> +{ + type Output = P; + type Error = P::Error; + fn print(&self, cx: P) -> Result { + cx.in_binder(self) + } +} + +impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::OutlivesPredicate + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, + U: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, +{ + type Output = P; + type Error = P::Error; + fn print(&self, mut cx: P) -> Result { + define_scoped_cx!(cx); + p!(print(self.0), write(" : "), print(self.1)); + Ok(cx) + } +} + +macro_rules! forward_display_to_print { + ($($ty:ty),+) => { + $(impl fmt::Display for $ty { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + tcx.lift(self) + .expect("could not lift for printing") + .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) + } + })+ + }; +} + +macro_rules! define_print_and_forward_display { + (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { + $(impl<'gcx: 'tcx, 'tcx, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for $ty { + type Output = P; + type Error = fmt::Error; + fn print(&$self, $cx: P) -> Result { + #[allow(unused_mut)] + let mut $cx = $cx; + define_scoped_cx!($cx); + let _: () = $print; + #[allow(unreachable_code)] + Ok($cx) + } + })+ + + forward_display_to_print!($($ty),+); + }; +} + +// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. +impl fmt::Display for ty::RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) + } +} + +forward_display_to_print! { + Ty<'tcx>, + &'tcx ty::List>, + + // HACK(eddyb) these are exhaustive instead of generic, + // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet. + ty::Binder<&'tcx ty::List>>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder, ty::Region<'tcx>>>, + ty::Binder, ty::Region<'tcx>>>, + + ty::OutlivesPredicate, ty::Region<'tcx>>, + ty::OutlivesPredicate, ty::Region<'tcx>> +} + +define_print_and_forward_display! { + (self, cx): + + &'tcx ty::List> { + p!(write("{{")); + let mut tys = self.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } + p!(write("}}")) + } + + ty::TypeAndMut<'tcx> { + p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), + print(self.ty)) + } + + ty::ExistentialTraitRef<'tcx> { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0)); + let trait_ref = self.with_self_ty(cx.tcx(), dummy_self); + p!(print(trait_ref)) + } + + ty::ExistentialProjection<'tcx> { + let name = cx.tcx().associated_item(self.item_def_id).ident; + p!(write("{} = ", name), print(self.ty)) + } + + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + p!(print_def_path(def_id, &[])); + } + } + } + + ty::FnSig<'tcx> { + if self.unsafety == hir::Unsafety::Unsafe { + p!(write("unsafe ")); + } + + if self.abi != Abi::Rust { + p!(write("extern {} ", self.abi)); + } + + p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + } + + ty::InferTy { + if cx.tcx().sess.verbose() { + p!(write("{:?}", self)); + return Ok(cx); + } + match *self { + ty::TyVar(_) => p!(write("_")), + ty::IntVar(_) => p!(write("{}", "{integer}")), + ty::FloatVar(_) => p!(write("{}", "{float}")), + ty::FreshTy(v) => p!(write("FreshTy({})", v)), + ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)), + ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) + } + } + + ty::TraitRef<'tcx> { + p!(print_def_path(self.def_id, self.substs)); + } + + ConstValue<'tcx> { + match self { + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), + _ => p!(write("{:?}", self)), + } + } + + ty::Const<'tcx> { + p!(write("{} : {}", self.val, self.ty)) + } + + &'tcx ty::LazyConst<'tcx> { + match self { + // FIXME(const_generics) this should print at least the type. + ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), + ty::LazyConst::Evaluated(c) => p!(write("{}", c)), + } + } + + ty::ParamTy { + p!(write("{}", self.name)) + } + + ty::ParamConst { + p!(write("{}", self.name)) + } + + ty::SubtypePredicate<'tcx> { + p!(print(self.a), write(" <: "), print(self.b)) + } + + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + } + + ty::ProjectionPredicate<'tcx> { + p!(print(self.projection_ty), write(" == "), print(self.ty)) + } + + ty::ProjectionTy<'tcx> { + p!(print_def_path(self.item_def_id, self.substs)); + } + + ty::ClosureKind { + match *self { + ty::ClosureKind::Fn => p!(write("Fn")), + ty::ClosureKind::FnMut => p!(write("FnMut")), + ty::ClosureKind::FnOnce => p!(write("FnOnce")), + } + } + + ty::Predicate<'tcx> { + match *self { + ty::Predicate::Trait(ref data) => p!(print(data)), + ty::Predicate::Subtype(ref predicate) => p!(print(predicate)), + ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::Projection(ref predicate) => p!(print(predicate)), + ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), + ty::Predicate::ObjectSafe(trait_def_id) => { + p!(write("the trait `"), + print_def_path(trait_def_id, &[]), + write("` is object-safe")) + } + ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { + p!(write("the closure `"), + print_value_path(closure_def_id, &[]), + write("` implements the trait `{}`", kind)) + } + ty::Predicate::ConstEvaluatable(def_id, substs) => { + p!(write("the constant `"), + print_value_path(def_id, substs), + write("` can be evaluated")) + } + } + } + + Kind<'tcx> { + match self.unpack() { + UnpackedKind::Lifetime(lt) => p!(print(lt)), + UnpackedKind::Type(ty) => p!(print(ty)), + UnpackedKind::Const(ct) => p!(print(ct)), + } + } +} diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 6488c0db42bc5..395b288df141e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -71,7 +71,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M { default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { if !tcx.sess.verbose() { - format!("processing `{}`", tcx.item_path_str(def_id)).into() + format!("processing `{}`", tcx.def_path_str(def_id)).into() } else { let name = unsafe { ::std::intrinsics::type_name::() }; format!("processing {:?} with query `{}`", def_id, name).into() @@ -301,7 +301,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("computing the supertraits of `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } @@ -322,7 +322,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("coherence checking all impls of trait `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } @@ -359,7 +359,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { format!("generating MIR shim for `{}`", - tcx.item_path_str(def.def_id())).into() + tcx.def_path_str(def.def_id())).into() } } @@ -394,7 +394,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { ) -> Cow<'static, str> { format!( "const-evaluating + checking `{}`", - tcx.item_path_str(key.value.instance.def.def_id()), + tcx.def_path_str(key.value.instance.def.def_id()), ).into() } @@ -415,7 +415,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> Cow<'static, str> { - format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into() + format!("const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id())).into() } #[inline] @@ -513,7 +513,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("const checking if rvalue is promotable to static `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } #[inline] @@ -532,21 +532,21 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking which parts of `{}` are promotable to static", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking if item is mir available: `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> { - format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id())) + format!("checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id())) .into() } @@ -565,19 +565,19 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("trait impls of `{}`", tcx.item_path_str(def_id)).into() + format!("trait impls of `{}`", tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into() + format!("determine object safety of trait `{}`", tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into() + format!("checking if item is const fn: `{}`", tcx.def_path_str(def_id)).into() } } @@ -883,7 +883,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> { - format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into() + format!("finding all methods for trait {}", tcx.def_path_str(key.def_id())).into() } } @@ -927,7 +927,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> { - format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into() + format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into() } } @@ -945,7 +945,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { - format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into() + format!("estimating size for `{}`", tcx.def_path_str(def.def_id())).into() } } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e3276ba0bea7b..cff99f23d0e95 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -4,11 +4,10 @@ use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; use crate::ty::tls; -use crate::ty::{TyCtxt}; +use crate::ty::{self, TyCtxt}; use crate::ty::query::Query; use crate::ty::query::config::{QueryConfig, QueryDescription}; use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo}; -use crate::ty::item_path; use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg}; @@ -299,7 +298,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // sometimes cycles itself, leading to extra cycle errors. // (And cycle errors around impls tend to occur during the // collect/coherence phases anyhow.) - item_path::with_forced_impl_filename_line(|| { + ty::print::with_forced_impl_filename_line(|| { let span = fix_span(stack[1 % stack.len()].span, &stack[0].query); let mut err = struct_span_err!(self.sess, span, diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 3a31801b3be39..b245d90379996 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -351,10 +351,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { let tcx = relation.tcx(); - let a_sty = &a.sty; - let b_sty = &b.sty; - debug!("super_relate_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty); - match (a_sty, b_sty) { + debug!("super_relate_tys: a={:?} b={:?}", a, b); + match (&a.sty, &b.sty) { (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f9eb336a4a3e2..ecfb034e4f2fe 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -3,17 +3,288 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. +use crate::hir::def::Namespace; use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use smallvec::SmallVec; use crate::mir::interpret; +use std::fmt; use std::marker::PhantomData; use std::rc::Rc; +impl fmt::Debug for ty::GenericParamDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let type_name = match self.kind { + ty::GenericParamDefKind::Lifetime => "Lifetime", + ty::GenericParamDefKind::Type {..} => "Type", + ty::GenericParamDefKind::Const => "Const", + }; + write!(f, "{}({}, {:?}, {})", + type_name, + self.name, + self.def_id, + self.index) + } +} + +impl fmt::Debug for ty::TraitDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.def_id, &[])?; + Ok(()) + }) + } +} + +impl fmt::Debug for ty::AdtDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.did, &[])?; + Ok(()) + }) + } +} + +impl fmt::Debug for ty::ClosureUpvar<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ClosureUpvar({:?},{:?})", + self.def, + self.ty) + } +} + +impl fmt::Debug for ty::UpvarId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = ty::tls::with(|tcx| { + tcx.hir().name_by_hir_id(self.var_path.hir_id) + }); + write!(f, "UpvarId({:?};`{}`;{:?})", + self.var_path.hir_id, + name, + self.closure_expr_id) + } +} + +impl fmt::Debug for ty::UpvarBorrow<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "UpvarBorrow({:?}, {:?})", + self.kind, self.region) + } +} + +impl fmt::Debug for ty::ExistentialTraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Debug for ty::adjustment::Adjustment<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} -> {}", self.kind, self.target) + } +} + +impl fmt::Debug for ty::BoundRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), + ty::BrFresh(n) => write!(f, "BrFresh({:?})", n), + ty::BrNamed(did, name) => { + write!(f, "BrNamed({:?}:{:?}, {})", + did.krate, did.index, name) + } + ty::BrEnv => write!(f, "BrEnv"), + } + } +} + +impl fmt::Debug for ty::RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::ReEarlyBound(ref data) => { + write!(f, "ReEarlyBound({}, {})", + data.index, + data.name) + } + + ty::ReClosureBound(ref vid) => { + write!(f, "ReClosureBound({:?})", vid) + } + + ty::ReLateBound(binder_id, ref bound_region) => { + write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region) + } + + ty::ReFree(ref fr) => fr.fmt(f), + + ty::ReScope(id) => write!(f, "ReScope({:?})", id), + + ty::ReStatic => write!(f, "ReStatic"), + + ty::ReVar(ref vid) => vid.fmt(f), + + ty::RePlaceholder(placeholder) => { + write!(f, "RePlaceholder({:?})", placeholder) + } + + ty::ReEmpty => write!(f, "ReEmpty"), + + ty::ReErased => write!(f, "ReErased"), + } + } +} + +impl fmt::Debug for ty::FreeRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + } +} + +impl fmt::Debug for ty::Variance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + ty::Covariant => "+", + ty::Contravariant => "-", + ty::Invariant => "o", + ty::Bivariant => "*", + }) + } +} + +impl fmt::Debug for ty::FnSig<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({:?}; c_variadic: {})->{:?}", + self.inputs(), self.c_variadic, self.output()) + } +} + +impl fmt::Debug for ty::TyVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}t", self.index) + } +} + +impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}c", self.index) + } +} + +impl fmt::Debug for ty::IntVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}i", self.index) + } +} + +impl fmt::Debug for ty::FloatVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}f", self.index) + } +} + +impl fmt::Debug for ty::RegionVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'_#{}r", self.index()) + } +} + +impl fmt::Debug for ty::InferTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::TyVar(ref v) => v.fmt(f), + ty::IntVar(ref v) => v.fmt(f), + ty::FloatVar(ref v) => v.fmt(f), + ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), + ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), + ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v), + } + } +} + +impl fmt::Debug for ty::IntVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::IntType(ref v) => v.fmt(f), + ty::UintType(ref v) => v.fmt(f), + } + } +} + +impl fmt::Debug for ty::FloatVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Debug for ty::TraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // FIXME(#59188) this is used across the compiler to print + // a `TraitRef` qualified (with the Self type explicit), + // instead of having a different way to make that choice. + write!(f, "<{} as {}>", self.self_ty(), self) + } +} + +impl fmt::Debug for Ty<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Debug for ty::ParamTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.idx) + } +} + +impl fmt::Debug for ty::ParamConst { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.index) + } +} + +impl fmt::Debug for ty::TraitPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "TraitPredicate({:?})", self.trait_ref) + } +} + +impl fmt::Debug for ty::ProjectionPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty) + } +} + +impl fmt::Debug for ty::Predicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::Predicate::Trait(ref a) => a.fmt(f), + ty::Predicate::Subtype(ref pair) => pair.fmt(f), + ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f), + ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f), + ty::Predicate::Projection(ref pair) => pair.fmt(f), + ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty), + ty::Predicate::ObjectSafe(trait_def_id) => { + write!(f, "ObjectSafe({:?})", trait_def_id) + } + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + write!(f, "ClosureKind({:?}, {:?}, {:?})", + closure_def_id, closure_substs, kind) + } + ty::Predicate::ConstEvaluatable(def_id, substs) => { + write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + } + } + } +} + /////////////////////////////////////////////////////////////////////////// // Atomic structs // @@ -48,10 +319,14 @@ CloneTypeFoldableAndLiftImpls! { // really meant to be folded. In general, we can only fold a fully // general `Region`. crate::ty::BoundRegion, + crate::ty::Placeholder, crate::ty::ClosureKind, + crate::ty::FreeRegion, + crate::ty::InferTy, crate::ty::IntVarValue, crate::ty::ParamConst, crate::ty::ParamTy, + crate::ty::RegionVid, crate::ty::UniverseIndex, crate::ty::Variance, ::syntax_pos::Span, @@ -60,6 +335,7 @@ CloneTypeFoldableAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations +// FIXME(eddyb) replace all the uses of `Option::map` with `?`. impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { type Lifted = (A::Lifted, B::Lifted); fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { @@ -156,6 +432,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { } } +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { + type Lifted = ty::ExistentialPredicate<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + match self { + ty::ExistentialPredicate::Trait(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Trait) + } + ty::ExistentialPredicate::Projection(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Projection) + } + ty::ExistentialPredicate::AutoTrait(def_id) => { + Some(ty::ExistentialPredicate::AutoTrait(*def_id)) + } + } + } +} + impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { type Lifted = ty::TraitPredicate<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) @@ -480,6 +773,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { } } +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> { + type Lifted = ty::TypeAndMut<'tcx>; + ty, mutbl + } +} + BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> { type Lifted = ty::Instance<'tcx>; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 39728cc8cd5cb..7b6a51c018459 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -9,7 +9,7 @@ use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; use rustc_macros::HashStable; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind}; -use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtDef, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable}; use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; use crate::util::captures::Captures; use crate::mir::interpret::{Scalar, Pointer}; @@ -84,7 +84,7 @@ impl BoundRegion { /// N.B., if you change this, you'll probably want to change the corresponding /// AST structure in `libsyntax/ast.rs` as well. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] pub enum TyKind<'tcx> { /// The primitive boolean type. Written as `bool`. @@ -383,9 +383,10 @@ impl<'tcx> ClosureSubsts<'tcx> { /// /// If you have an inference context, use `infcx.closure_sig()`. pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> { - match self.closure_sig_ty(def_id, tcx).sty { + let ty = self.closure_sig_ty(def_id, tcx); + match ty.sty { ty::FnPtr(sig) => sig, - ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t), + _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty), } } } @@ -1590,7 +1591,7 @@ impl RegionKind { pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId { match self { ty::ReEarlyBound(br) => { - tcx.parent_def_id(br.def_id).unwrap() + tcx.parent(br.def_id).unwrap() } ty::ReFree(fr) => fr.scope, _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), @@ -1910,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_machine(&self) -> bool { match self.sty { - Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false, Int(..) | Uint(..) | Float(..) => true, _ => false, } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 38be19a71c48c..8464286561469 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -12,8 +12,8 @@ use smallvec::SmallVec; use rustc_macros::HashStable; use core::intrinsics; -use std::cmp::Ordering; use std::fmt; +use std::cmp::Ordering; use std::marker::PhantomData; use std::mem; use std::num::NonZeroUsize; @@ -70,6 +70,16 @@ impl<'tcx> UnpackedKind<'tcx> { } } +impl fmt::Debug for Kind<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.unpack() { + UnpackedKind::Lifetime(lt) => lt.fmt(f), + UnpackedKind::Type(ty) => ty.fmt(f), + UnpackedKind::Const(ct) => ct.fmt(f), + } + } +} + impl<'tcx> Ord for Kind<'tcx> { fn cmp(&self, other: &Kind<'_>) -> Ordering { self.unpack().cmp(&other.unpack()) @@ -115,34 +125,14 @@ impl<'tcx> Kind<'tcx> { } } -impl<'tcx> fmt::Debug for Kind<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { - UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt), - UnpackedKind::Type(ty) => write!(f, "{:?}", ty), - UnpackedKind::Const(ct) => write!(f, "{:?}", ct), - } - } -} - -impl<'tcx> fmt::Display for Kind<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { - UnpackedKind::Lifetime(lt) => write!(f, "{}", lt), - UnpackedKind::Type(ty) => write!(f, "{}", ty), - UnpackedKind::Const(ct) => write!(f, "{}", ct), - } - } -} - impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { type Lifted = Kind<'tcx>; fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option { match self.unpack() { - UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()), - UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()), - UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()), + UnpackedKind::Lifetime(lt) => tcx.lift(<).map(|lt| lt.into()), + UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()), + UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()), } } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 422f97b299646..65918a9082102 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -7,7 +7,7 @@ use crate::hir::{self, Node}; use crate::mir::interpret::{sign_extend, truncate}; use crate::ich::NodeIdHashingMode; use crate::traits::{self, ObligationCause}; -use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, UnpackedKind}; use crate::ty::query::TyCtxtAt; use crate::ty::TyKind::*; @@ -563,7 +563,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn closure_base_def_id(self, def_id: DefId) -> DefId { let mut def_id = def_id; while self.is_closure(def_id) { - def_id = self.parent_def_id(def_id).unwrap_or_else(|| { + def_id = self.parent(def_id).unwrap_or_else(|| { bug!("closure {:?} has no parent", def_id); }); } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs deleted file mode 100644 index a1398c69ff0c5..0000000000000 --- a/src/librustc/util/ppaux.rs +++ /dev/null @@ -1,1667 +0,0 @@ -use crate::hir::def_id::DefId; -use crate::hir::map::definitions::DefPathData; -use crate::middle::region; -use crate::ty::subst::{self, Subst, SubstsRef}; -use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; -use crate::ty::{Bool, Char, Adt}; -use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; -use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; -use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; -use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; -use crate::mir::interpret::ConstValue; -use crate::util::nodemap::FxHashSet; - -use std::cell::Cell; -use std::fmt; -use std::usize; - -use rustc_target::spec::abi::Abi; -use syntax::ast::CRATE_NODE_ID; -use syntax::symbol::{Symbol, InternedString}; -use crate::hir; - -/// The "region highlights" are used to control region printing during -/// specific error messages. When a "region highlight" is enabled, it -/// gives an alternate way to print specific regions. For now, we -/// always print those regions using a number, so something like "`'0`". -/// -/// Regions not selected by the region highlight mode are presently -/// unaffected. -#[derive(Copy, Clone, Default)] -pub struct RegionHighlightMode { - /// If enabled, when we see the selected region, use "`'N`" - /// instead of the ordinary behavior. - highlight_regions: [Option<(ty::RegionKind, usize)>; 3], - - /// If enabled, when printing a "free region" that originated from - /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily - /// have names print as normal. - /// - /// This is used when you have a signature like `fn foo(x: &u32, - /// y: &'a u32)` and we want to give a name to the region of the - /// reference `x`. - highlight_bound_region: Option<(ty::BoundRegion, usize)>, -} - -thread_local! { - /// Mechanism for highlighting of specific regions for display in NLL region inference errors. - /// Contains region to highlight and counter for number to use when highlighting. - static REGION_HIGHLIGHT_MODE: Cell = - Cell::new(RegionHighlightMode::default()) -} - -impl RegionHighlightMode { - /// Reads and returns the current region highlight settings (accesses thread-local state). - pub fn get() -> Self { - REGION_HIGHLIGHT_MODE.with(|c| c.get()) - } - - // Internal helper to update current settings during the execution of `op`. - fn set( - old_mode: Self, - new_mode: Self, - op: impl FnOnce() -> R, - ) -> R { - REGION_HIGHLIGHT_MODE.with(|c| { - c.set(new_mode); - let result = op(); - c.set(old_mode); - result - }) - } - - /// If `region` and `number` are both `Some`, invokes - /// `highlighting_region`; otherwise, just invokes `op` directly. - pub fn maybe_highlighting_region( - region: Option>, - number: Option, - op: impl FnOnce() -> R, - ) -> R { - if let Some(k) = region { - if let Some(n) = number { - return Self::highlighting_region(k, n, op); - } - } - - op() - } - - /// During the execution of `op`, highlights the region inference - /// variable `vid` as `'N`. We can only highlight one region `vid` - /// at a time. - pub fn highlighting_region( - region: ty::Region<'_>, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - let old_mode = Self::get(); - let mut new_mode = old_mode; - let first_avail_slot = new_mode.highlight_regions.iter_mut() - .filter(|s| s.is_none()) - .next() - .unwrap_or_else(|| { - panic!( - "can only highlight {} placeholders at a time", - old_mode.highlight_regions.len(), - ) - }); - *first_avail_slot = Some((*region, number)); - Self::set(old_mode, new_mode, op) - } - - /// Convenience wrapper for `highlighting_region`. - pub fn highlighting_region_vid( - vid: ty::RegionVid, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - Self::highlighting_region(&ty::ReVar(vid), number, op) - } - - /// Returns `true` if any placeholders are highlighted, and `false` otherwise. - fn any_region_vids_highlighted(&self) -> bool { - Self::get() - .highlight_regions - .iter() - .any(|h| match h { - Some((ty::ReVar(_), _)) => true, - _ => false, - }) - } - - /// Returns `Some(n)` with the number to use for the given region, if any. - fn region_highlighted(&self, region: ty::Region<'_>) -> Option { - Self::get() - .highlight_regions - .iter() - .filter_map(|h| match h { - Some((r, n)) if r == region => Some(*n), - _ => None, - }) - .next() - } - - /// During the execution of `op`, highlight the given bound - /// region. We can only highlight one bound region at a time. See - /// the field `highlight_bound_region` for more detailed notes. - pub fn highlighting_bound_region( - br: ty::BoundRegion, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - let old_mode = Self::get(); - assert!(old_mode.highlight_bound_region.is_none()); - Self::set( - old_mode, - Self { - highlight_bound_region: Some((br, number)), - ..old_mode - }, - op, - ) - } - - /// Returns `true` if any placeholders are highlighted, and `false` otherwise. - pub fn any_placeholders_highlighted(&self) -> bool { - Self::get() - .highlight_regions - .iter() - .any(|h| match h { - Some((ty::RePlaceholder(_), _)) => true, - _ => false, - }) - } - - /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`". - pub fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { - self.region_highlighted(&ty::RePlaceholder(p)) - } -} - -macro_rules! gen_display_debug_body { - ( $with:path ) => { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut cx = PrintContext::new(); - $with(self, f, &mut cx) - } - }; -} -macro_rules! gen_display_debug { - ( ($($x:tt)+) $target:ty, display yes ) => { - impl<$($x)+> fmt::Display for $target { - gen_display_debug_body! { Print::print_display } - } - }; - ( () $target:ty, display yes ) => { - impl fmt::Display for $target { - gen_display_debug_body! { Print::print_display } - } - }; - ( ($($x:tt)+) $target:ty, debug yes ) => { - impl<$($x)+> fmt::Debug for $target { - gen_display_debug_body! { Print::print_debug } - } - }; - ( () $target:ty, debug yes ) => { - impl fmt::Debug for $target { - gen_display_debug_body! { Print::print_debug } - } - }; - ( $generic:tt $target:ty, $t:ident no ) => {}; -} -macro_rules! gen_print_impl { - ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl<$($x)+> Print for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { - if $cx.is_debug $dbg - else $disp - } - } - }; - ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl Print for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { - if $cx.is_debug $dbg - else $disp - } - } - }; - ( $generic:tt $target:ty, - $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => { - gen_print_impl! { $generic $target, $vars $disp $dbg } - gen_display_debug! { $generic $target, display $gendisp } - gen_display_debug! { $generic $target, debug $gendbg } - } -} -macro_rules! define_print { - ( $generic:tt $target:ty, - $vars:tt { display $disp:block debug $dbg:block } ) => { - gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } - }; - ( $generic:tt $target:ty, - $vars:tt { debug $dbg:block display $disp:block } ) => { - gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } - }; - ( $generic:tt $target:ty, - $vars:tt { debug $dbg:block } ) => { - gen_print_impl! { $generic $target, $vars no { - bug!(concat!("display not implemented for ", stringify!($target))); - } yes $dbg } - }; - ( $generic:tt $target:ty, - ($self:ident, $f:ident, $cx:ident) { display $disp:block } ) => { - gen_print_impl! { $generic $target, ($self, $f, $cx) yes $disp no { - write!($f, "{:?}", $self) - } } - }; -} -macro_rules! define_print_multi { - ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => { - $(define_print! { $generic $target, $vars $def })* - }; -} -macro_rules! print_inner { - ( $f:expr, $cx:expr, write ($($data:expr),+) ) => { - write!($f, $($data),+) - }; - ( $f:expr, $cx:expr, $kind:ident ($data:expr) ) => { - $data.$kind($f, $cx) - }; -} -macro_rules! print { - ( $f:expr, $cx:expr $(, $kind:ident $data:tt)+ ) => { - Ok(())$(.and_then(|_| print_inner!($f, $cx, $kind $data)))+ - }; -} - - -struct LateBoundRegionNameCollector(FxHashSet); -impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { - fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - match *r { - ty::ReLateBound(_, ty::BrNamed(_, name)) => { - self.0.insert(name); - }, - _ => {}, - } - r.super_visit_with(self) - } -} - -#[derive(Debug)] -pub struct PrintContext { - is_debug: bool, - is_verbose: bool, - identify_regions: bool, - used_region_names: Option>, - region_index: usize, - binder_depth: usize, -} -impl PrintContext { - fn new() -> Self { - ty::tls::with_opt(|tcx| { - let (is_verbose, identify_regions) = tcx.map( - |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions) - ).unwrap_or((false, false)); - PrintContext { - is_debug: false, - is_verbose: is_verbose, - identify_regions: identify_regions, - used_region_names: None, - region_index: 0, - binder_depth: 0, - } - }) - } - fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder) - where T: TypeFoldable<'tcx> - { - let mut collector = LateBoundRegionNameCollector(Default::default()); - value.visit_with(&mut collector); - self.used_region_names = Some(collector.0); - self.region_index = 0; - } -} - -pub trait Print { - fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print(&mut result, cx); - result - } - fn print_display(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { - let old_debug = cx.is_debug; - cx.is_debug = false; - let result = self.print(f, cx); - cx.is_debug = old_debug; - result - } - fn print_display_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print_display(&mut result, cx); - result - } - fn print_debug(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { - let old_debug = cx.is_debug; - cx.is_debug = true; - let result = self.print(f, cx); - cx.is_debug = old_debug; - result - } - fn print_debug_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print_debug(&mut result, cx); - result - } -} - -impl PrintContext { - fn fn_sig(&mut self, - f: &mut F, - inputs: &[Ty<'_>], - c_variadic: bool, - output: Ty<'_>) - -> fmt::Result { - write!(f, "(")?; - let mut inputs = inputs.iter(); - if let Some(&ty) = inputs.next() { - print!(f, self, print_display(ty))?; - for &ty in inputs { - print!(f, self, write(", "), print_display(ty))?; - } - if c_variadic { - write!(f, ", ...")?; - } - } - write!(f, ")")?; - if !output.is_unit() { - print!(f, self, write(" -> "), print_display(output))?; - } - - Ok(()) - } - - fn parameterized(&mut self, - f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { - let key = ty::tls::with(|tcx| tcx.def_key(did)); - - let verbose = self.is_verbose; - let mut num_supplied_defaults = 0; - let mut has_self = false; - let mut own_counts: GenericParamCount = Default::default(); - let mut is_value_path = false; - let mut item_name = Some(key.disambiguated_data.data.as_interned_str()); - let fn_trait_kind = ty::tls::with(|tcx| { - // Unfortunately, some kinds of items (e.g., closures) don't have - // generics. So walk back up the find the closest parent that DOES - // have them. - let mut item_def_id = did; - loop { - let key = tcx.def_key(item_def_id); - match key.disambiguated_data.data { - DefPathData::AssocTypeInTrait(_) | - DefPathData::AssocTypeInImpl(_) | - DefPathData::AssocExistentialInImpl(_) | - DefPathData::Trait(_) | - DefPathData::TraitAlias(_) | - DefPathData::Impl | - DefPathData::TypeNs(_) => { - break; - } - DefPathData::ValueNs(_) | - DefPathData::EnumVariant(_) => { - is_value_path = true; - break; - } - DefPathData::CrateRoot | - DefPathData::Misc | - DefPathData::Module(_) | - DefPathData::MacroDef(_) | - DefPathData::ClosureExpr | - DefPathData::TypeParam(_) | - DefPathData::LifetimeParam(_) | - DefPathData::ConstParam(_) | - DefPathData::Field(_) | - DefPathData::StructCtor | - DefPathData::AnonConst | - DefPathData::ImplTrait | - DefPathData::GlobalMetaData(_) => { - // if we're making a symbol for something, there ought - // to be a value or type-def or something in there - // *somewhere* - item_def_id.index = key.parent.unwrap_or_else(|| { - bug!("finding type for {:?}, encountered def-id {:?} with no \ - parent", did, item_def_id); - }); - } - } - } - let mut generics = tcx.generics_of(item_def_id); - let child_own_counts = generics.own_counts(); - let mut path_def_id = did; - has_self = generics.has_self; - - let mut child_types = 0; - if let Some(def_id) = generics.parent { - // Methods. - assert!(is_value_path); - child_types = child_own_counts.types; - generics = tcx.generics_of(def_id); - own_counts = generics.own_counts(); - - if has_self { - print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; - } - - path_def_id = def_id; - } else { - item_name = None; - - if is_value_path { - // Functions. - assert_eq!(has_self, false); - } else { - // Types and traits. - own_counts = child_own_counts; - } - } - - if !verbose { - let mut type_params = - generics.params.iter().rev().filter_map(|param| match param.kind { - GenericParamDefKind::Lifetime => None, - GenericParamDefKind::Type { has_default, .. } => { - Some((param.def_id, has_default)) - } - GenericParamDefKind::Const => None, // FIXME(const_generics:defaults) - }).peekable(); - let has_default = { - let has_default = type_params.peek().map(|(_, has_default)| has_default); - *has_default.unwrap_or(&false) - }; - if has_default { - if let Some(substs) = tcx.lift(&substs) { - let types = substs.types().rev().skip(child_types); - for ((def_id, has_default), actual) in type_params.zip(types) { - if !has_default { - break; - } - if tcx.type_of(def_id).subst(tcx, substs) != actual { - break; - } - num_supplied_defaults += 1; - } - } - } - } - - print!(f, self, write("{}", tcx.item_path_str(path_def_id)))?; - Ok(tcx.lang_items().fn_trait_kind(path_def_id)) - })?; - - if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { - let projection_ty = projections[0].ty; - if let Tuple(ref args) = substs.type_at(1).sty { - return self.fn_sig(f, args, false, projection_ty); - } - } - - let empty = Cell::new(true); - let start_or_continue = |f: &mut F, start: &str, cont: &str| { - if empty.get() { - empty.set(false); - write!(f, "{}", start) - } else { - write!(f, "{}", cont) - } - }; - - let print_regions = |f: &mut F, start: &str, skip, count| { - // Don't print any regions if they're all erased. - let regions = || substs.regions().skip(skip).take(count); - if regions().all(|r: ty::Region<'_>| *r == ty::ReErased) { - return Ok(()); - } - - for region in regions() { - let region: ty::Region<'_> = region; - start_or_continue(f, start, ", ")?; - if verbose { - write!(f, "{:?}", region)?; - } else { - let s = region.to_string(); - if s.is_empty() { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(f, "'_")?; - } else { - write!(f, "{}", s)?; - } - } - } - - Ok(()) - }; - - print_regions(f, "<", 0, own_counts.lifetimes)?; - - let tps = substs.types() - .take(own_counts.types - num_supplied_defaults) - .skip(has_self as usize); - - for ty in tps { - start_or_continue(f, "<", ", ")?; - ty.print_display(f, self)?; - } - - for projection in projections { - start_or_continue(f, "<", ", ")?; - ty::tls::with(|tcx| - print!(f, self, - write("{}=", - tcx.associated_item(projection.projection_ty.item_def_id).ident), - print_display(projection.ty)) - )?; - } - - // FIXME(const_generics::defaults) - let consts = substs.consts(); - - for ct in consts { - start_or_continue(f, "<", ", ")?; - ct.print_display(f, self)?; - } - - start_or_continue(f, "", ">")?; - - // For values, also print their name and type parameters. - if is_value_path { - empty.set(true); - - if has_self { - write!(f, ">")?; - } - - if let Some(item_name) = item_name { - write!(f, "::{}", item_name)?; - } - - print_regions(f, "::<", own_counts.lifetimes, usize::MAX)?; - - // FIXME: consider being smart with defaults here too - for ty in substs.types().skip(own_counts.types) { - start_or_continue(f, "::<", ", ")?; - ty.print_display(f, self)?; - } - - start_or_continue(f, "", ">")?; - } - - Ok(()) - } - - fn in_binder<'a, 'gcx, 'tcx, T, U, F>(&mut self, - f: &mut F, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - original: &ty::Binder, - lifted: Option>) -> fmt::Result - where T: Print, U: Print + TypeFoldable<'tcx>, F: fmt::Write - { - fn name_by_region_index(index: usize) -> InternedString { - match index { - 0 => Symbol::intern("'r"), - 1 => Symbol::intern("'s"), - i => Symbol::intern(&format!("'t{}", i-2)), - }.as_interned_str() - } - - // Replace any anonymous late-bound regions with named - // variants, using gensym'd identifiers, so that we can - // clearly differentiate between named and unnamed regions in - // the output. We'll probably want to tweak this over time to - // decide just how much information to give. - let value = if let Some(v) = lifted { - v - } else { - return original.skip_binder().print_display(f, self); - }; - - if self.binder_depth == 0 { - self.prepare_late_bound_region_info(&value); - } - - let mut empty = true; - let mut start_or_continue = |f: &mut F, start: &str, cont: &str| { - if empty { - empty = false; - write!(f, "{}", start) - } else { - write!(f, "{}", cont) - } - }; - - let old_region_index = self.region_index; - let mut region_index = old_region_index; - let new_value = tcx.replace_late_bound_regions(&value, |br| { - let _ = start_or_continue(f, "for<", ", "); - let br = match br { - ty::BrNamed(_, name) => { - let _ = write!(f, "{}", name); - br - } - ty::BrAnon(_) | - ty::BrFresh(_) | - ty::BrEnv => { - let name = loop { - let name = name_by_region_index(region_index); - region_index += 1; - if !self.is_name_used(&name) { - break name; - } - }; - let _ = write!(f, "{}", name); - ty::BrNamed(tcx.hir().local_def_id(CRATE_NODE_ID), name) - } - }; - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) - }).0; - start_or_continue(f, "", "> ")?; - - // Push current state to gcx, and restore after writing new_value. - self.binder_depth += 1; - self.region_index = region_index; - let result = new_value.print_display(f, self); - self.region_index = old_region_index; - self.binder_depth -= 1; - result - } - - fn is_name_used(&self, name: &InternedString) -> bool { - match self.used_region_names { - Some(ref names) => names.contains(name), - None => false, - } - } -} - -pub fn verbose() -> bool { - ty::tls::with(|tcx| tcx.sess.verbose()) -} - -pub fn identify_regions() -> bool { - ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions) -} - -pub fn parameterized(f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { - PrintContext::new().parameterized(f, substs, did, projections) -} - -impl<'a, T: Print> Print for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { - (*self).print(f, cx) - } -} - -define_print! { - ('tcx) &'tcx ty::List>, (self, f, cx) { - display { - // Generate the main trait ref, including associated types. - ty::tls::with(|tcx| { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - let mut first = true; - - if let Some(principal) = self.principal() { - let principal = tcx - .lift(&principal) - .expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift projection for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; - first = false; - } - - // Builtin bounds. - let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - tcx.item_path_str(did) - }).collect(); - - // The auto traits come ordered by `DefPathHash`. While - // `DefPathHash` is *stable* in the sense that it depends on - // neither the host nor the phase of the moon, it depends - // "pseudorandomly" on the compiler version and the target. - // - // To avoid that causing instabilities in compiletest - // output, sort the auto-traits alphabetically. - auto_traits.sort(); - - for auto_trait in auto_traits { - if !first { - write!(f, " + ")?; - } - first = false; - - write!(f, "{}", auto_trait)?; - } - - Ok(()) - })?; - - Ok(()) - } - } -} - -impl fmt::Debug for ty::GenericParamDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_name = match self.kind { - ty::GenericParamDefKind::Lifetime => "Lifetime", - ty::GenericParamDefKind::Type { .. } => "Type", - ty::GenericParamDefKind::Const => "Const", - }; - write!(f, "{}({}, {:?}, {})", - type_name, - self.name, - self.def_id, - self.index) - } -} - -impl fmt::Debug for ty::TraitDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - write!(f, "{}", tcx.item_path_str(self.def_id)) - }) - } -} - -impl fmt::Debug for ty::AdtDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - write!(f, "{}", tcx.item_path_str(self.did)) - }) - } -} - -impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ClosureUpvar({:?},{:?})", - self.def, - self.ty) - } -} - -impl fmt::Debug for ty::UpvarId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UpvarId({:?};`{}`;{:?})", - self.var_path.hir_id, - ty::tls::with(|tcx| tcx.hir().name_by_hir_id(self.var_path.hir_id)), - self.closure_expr_id) - } -} - -impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UpvarBorrow({:?}, {:?})", - self.kind, self.region) - } -} - -define_print! { - ('tcx) &'tcx ty::List>, (self, f, cx) { - display { - write!(f, "{{")?; - let mut tys = self.iter(); - if let Some(&ty) = tys.next() { - print!(f, cx, print(ty))?; - for &ty in tys { - print!(f, cx, write(", "), print(ty))?; - } - } - write!(f, "}}") - } - } -} - -define_print! { - ('tcx) ty::TypeAndMut<'tcx>, (self, f, cx) { - display { - print!(f, cx, - write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), - print(self.ty)) - } - } -} - -define_print! { - ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) { - display { - cx.parameterized(f, self.substs, self.def_id, &[]) - } - debug { - ty::tls::with(|tcx| { - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - - let trait_ref = *tcx.lift(&ty::Binder::bind(*self)) - .expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self).skip_binder(); - cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) - }) - } - } -} - -define_print! { - ('tcx) ty::adjustment::Adjustment<'tcx>, (self, f, cx) { - debug { - print!(f, cx, write("{:?} -> ", self.kind), print(self.target)) - } - } -} - -define_print! { - () ty::BoundRegion, (self, f, cx) { - display { - if cx.is_verbose { - return self.print_debug(f, cx); - } - - if let Some((region, counter)) = RegionHighlightMode::get().highlight_bound_region { - if *self == region { - return match *self { - BrNamed(_, name) => write!(f, "{}", name), - BrAnon(_) | BrFresh(_) | BrEnv => write!(f, "'{}", counter) - }; - } - } - - match *self { - BrNamed(_, name) => write!(f, "{}", name), - BrAnon(_) | BrFresh(_) | BrEnv => Ok(()) - } - } - debug { - return match *self { - BrAnon(n) => write!(f, "BrAnon({:?})", n), - BrFresh(n) => write!(f, "BrFresh({:?})", n), - BrNamed(did, name) => { - write!(f, "BrNamed({:?}:{:?}, {})", - did.krate, did.index, name) - } - BrEnv => write!(f, "BrEnv"), - }; - } - } -} - -define_print! { - () ty::PlaceholderRegion, (self, f, cx) { - display { - if cx.is_verbose { - return self.print_debug(f, cx); - } - - let highlight = RegionHighlightMode::get(); - if let Some(counter) = highlight.placeholder_highlight(*self) { - write!(f, "'{}", counter) - } else if highlight.any_placeholders_highlighted() { - write!(f, "'_") - } else { - write!(f, "{}", self.name) - } - } - } -} - -define_print! { - () ty::RegionKind, (self, f, cx) { - display { - if cx.is_verbose { - return self.print_debug(f, cx); - } - - // Watch out for region highlights. - if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { - return write!(f, "'{:?}", n); - } - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *self { - ty::ReEarlyBound(ref data) => { - write!(f, "{}", data.name) - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { - write!(f, "{}", br) - } - ty::RePlaceholder(p) => { - write!(f, "{}", p) - } - ty::ReScope(scope) if cx.identify_regions => { - match scope.data { - region::ScopeData::Node => - write!(f, "'{}s", scope.item_local_id().as_usize()), - region::ScopeData::CallSite => - write!(f, "'{}cs", scope.item_local_id().as_usize()), - region::ScopeData::Arguments => - write!(f, "'{}as", scope.item_local_id().as_usize()), - region::ScopeData::Destruction => - write!(f, "'{}ds", scope.item_local_id().as_usize()), - region::ScopeData::Remainder(first_statement_index) => write!( - f, - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - ), - } - } - ty::ReVar(region_vid) => { - if RegionHighlightMode::get().any_region_vids_highlighted() { - write!(f, "{:?}", region_vid) - } else if cx.identify_regions { - write!(f, "'{}rv", region_vid.index()) - } else { - Ok(()) - } - } - ty::ReScope(_) | - ty::ReErased => Ok(()), - ty::ReStatic => write!(f, "'static"), - ty::ReEmpty => write!(f, "'"), - - // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => write!(f, "{:?}", vid), - } - } - debug { - match *self { - ty::ReEarlyBound(ref data) => { - write!(f, "ReEarlyBound({}, {})", - data.index, - data.name) - } - - ty::ReClosureBound(ref vid) => { - write!(f, "ReClosureBound({:?})", - vid) - } - - ty::ReLateBound(binder_id, ref bound_region) => { - write!(f, "ReLateBound({:?}, {:?})", - binder_id, - bound_region) - } - - ty::ReFree(ref fr) => write!(f, "{:?}", fr), - - ty::ReScope(id) => { - write!(f, "ReScope({:?})", id) - } - - ty::ReStatic => write!(f, "ReStatic"), - - ty::ReVar(ref vid) => { - write!(f, "{:?}", vid) - } - - ty::RePlaceholder(placeholder) => { - write!(f, "RePlaceholder({:?})", placeholder) - } - - ty::ReEmpty => write!(f, "ReEmpty"), - - ty::ReErased => write!(f, "ReErased") - } - } - } -} - -define_print! { - () ty::FreeRegion, (self, f, cx) { - debug { - write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) - } - } -} - -define_print! { - () ty::Variance, (self, f, cx) { - debug { - f.write_str(match *self { - ty::Covariant => "+", - ty::Contravariant => "-", - ty::Invariant => "o", - ty::Bivariant => "*", - }) - } - } -} - -define_print! { - ('tcx) ty::GenericPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "GenericPredicates({:?})", self.predicates) - } - } -} - -define_print! { - ('tcx) ty::InstantiatedPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "InstantiatedPredicates({:?})", self.predicates) - } - } -} - -define_print! { - ('tcx) ty::FnSig<'tcx>, (self, f, cx) { - display { - if self.unsafety == hir::Unsafety::Unsafe { - write!(f, "unsafe ")?; - } - - if self.abi != Abi::Rust { - write!(f, "extern {} ", self.abi)?; - } - - write!(f, "fn")?; - cx.fn_sig(f, self.inputs(), self.c_variadic, self.output()) - } - debug { - write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) - } - } -} - -impl fmt::Debug for ty::TyVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}t", self.index) - } -} - -impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) - } -} - -impl fmt::Debug for ty::IntVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}i", self.index) - } -} - -impl fmt::Debug for ty::FloatVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) - } -} - -impl fmt::Debug for ty::RegionVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(counter) = RegionHighlightMode::get().region_highlighted(&ty::ReVar(*self)) { - return write!(f, "'{:?}", counter); - } else if RegionHighlightMode::get().any_region_vids_highlighted() { - return write!(f, "'_"); - } - - write!(f, "'_#{}r", self.index()) - } -} - -define_print! { - () ty::InferTy, (self, f, cx) { - display { - if cx.is_verbose { - print!(f, cx, print_debug(self)) - } else { - match *self { - ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) => write!(f, "{}", "{integer}"), - ty::FloatVar(_) => write!(f, "{}", "{float}"), - ty::FreshTy(v) => write!(f, "FreshTy({})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) - } - } - } - debug { - match *self { - ty::TyVar(ref v) => write!(f, "{:?}", v), - ty::IntVar(ref v) => write!(f, "{:?}", v), - ty::FloatVar(ref v) => write!(f, "{:?}", v), - ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v) - } - } - } -} - -impl fmt::Debug for ty::IntVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ty::IntType(ref v) => v.fmt(f), - ty::UintType(ref v) => v.fmt(f), - } - } -} - -impl fmt::Debug for ty::FloatVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -// The generic impl doesn't work yet because projections are not -// normalized under HRTB. -/*impl fmt::Display for ty::Binder - where T: fmt::Display + for<'a> ty::Lift<'a>, - for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -}*/ - -define_print_multi! { - [ - ('tcx) ty::Binder<&'tcx ty::List>>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder, ty::Region<'tcx>>>, - ('tcx) ty::Binder, ty::Region<'tcx>>> - ] - (self, f, cx) { - display { - ty::tls::with(|tcx| cx.in_binder(f, tcx, self, tcx.lift(self))) - } - } -} - -define_print! { - ('tcx) ty::TraitRef<'tcx>, (self, f, cx) { - display { - cx.parameterized(f, self.substs, self.def_id, &[]) - } - debug { - // when printing out the debug representation, we don't need - // to enumerate the `for<...>` etc because the debruijn index - // tells you everything you need to know. - print!(f, cx, - write("<"), - print(self.self_ty()), - write(" as "))?; - cx.parameterized(f, self.substs, self.def_id, &[])?; - write!(f, ">") - } - } -} - -define_print! { - ('tcx) ty::TyKind<'tcx>, (self, f, cx) { - display { - match *self { - Bool => write!(f, "bool"), - Char => write!(f, "char"), - Int(t) => write!(f, "{}", t.ty_to_string()), - Uint(t) => write!(f, "{}", t.ty_to_string()), - Float(t) => write!(f, "{}", t.ty_to_string()), - RawPtr(ref tm) => { - write!(f, "*{} ", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - })?; - tm.ty.print(f, cx) - } - Ref(r, ty, mutbl) => { - write!(f, "&")?; - let s = r.print_to_string(cx); - if s != "'_" { - write!(f, "{}", s)?; - if !s.is_empty() { - write!(f, " ")?; - } - } - ty::TypeAndMut { ty, mutbl }.print(f, cx) - } - Never => write!(f, "!"), - Tuple(ref tys) => { - write!(f, "(")?; - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - print!(f, cx, print(ty), write(","))?; - if let Some(&ty) = tys.next() { - print!(f, cx, write(" "), print(ty))?; - for &ty in tys { - print!(f, cx, write(", "), print(ty))?; - } - } - } - write!(f, ")") - } - FnDef(def_id, substs) => { - ty::tls::with(|tcx| { - let mut sig = tcx.fn_sig(def_id); - if let Some(substs) = tcx.lift(&substs) { - sig = sig.subst(tcx, substs); - } - print!(f, cx, print(sig), write(" {{")) - })?; - cx.parameterized(f, substs, def_id, &[])?; - write!(f, "}}") - } - FnPtr(ref bare_fn) => { - bare_fn.print(f, cx) - } - Infer(infer_ty) => write!(f, "{}", infer_ty), - Error => write!(f, "[type error]"), - Param(ref param_ty) => write!(f, "{}", param_ty), - Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - write!(f, "^{}", bound_ty.var.index()) - } else { - write!(f, "^{}_{}", debruijn.index(), bound_ty.var.index()) - } - } - - ty::BoundTyKind::Param(p) => write!(f, "{}", p), - } - } - Adt(def, substs) => cx.parameterized(f, substs, def.did, &[]), - Dynamic(data, r) => { - let r = r.print_to_string(cx); - if !r.is_empty() { - write!(f, "(")?; - } - write!(f, "dyn ")?; - data.print(f, cx)?; - if !r.is_empty() { - write!(f, " + {})", r) - } else { - Ok(()) - } - } - Foreign(def_id) => parameterized(f, subst::InternalSubsts::empty(), def_id, &[]), - Projection(ref data) => data.print(f, cx), - UnnormalizedProjection(ref data) => { - write!(f, "Unnormalized(")?; - data.print(f, cx)?; - write!(f, ")") - } - Placeholder(placeholder) => { - write!(f, "Placeholder({:?})", placeholder) - } - Opaque(def_id, substs) => { - if cx.is_verbose { - return write!(f, "Opaque({:?}, {:?})", def_id, substs); - } - - ty::tls::with(|tcx| { - let def_key = tcx.def_key(def_id); - if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - write!(f, "{}", name)?; - let mut substs = substs.iter(); - if let Some(first) = substs.next() { - write!(f, "::<")?; - write!(f, "{}", first)?; - for subst in substs { - write!(f, ", {}", subst)?; - } - write!(f, ">")?; - } - return Ok(()); - } - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let predicates_of = tcx.predicates_of(def_id); - let substs = tcx.lift(&substs).unwrap_or_else(|| { - tcx.intern_substs(&[]) - }); - let bounds = predicates_of.instantiate(tcx, substs); - - let mut first = true; - let mut is_sized = false; - write!(f, "impl")?; - for predicate in bounds.predicates { - if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { - is_sized = true; - continue; - } - - print!(f, cx, - write("{}", if first { " " } else { "+" }), - print(trait_ref))?; - first = false; - } - } - if !is_sized { - write!(f, "{}?Sized", if first { " " } else { "+" })?; - } else if first { - write!(f, " Sized")?; - } - Ok(()) - }) - } - Str => write!(f, "str"), - Generator(did, substs, movability) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); - let witness = substs.witness(did, tcx); - if movability == hir::GeneratorMovability::Movable { - write!(f, "[generator")?; - } else { - write!(f, "[static generator")?; - } - - if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { - write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?; - let mut sep = " "; - tcx.with_freevars(hir_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, - write("{}{}:", - sep, - tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; - sep = ", "; - } - Ok(()) - })? - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - write!(f, "@{:?}", did)?; - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - print!(f, cx, - write("{}{}:", sep, index), - print(upvar_ty))?; - sep = ", "; - } - } - - print!(f, cx, write(" "), print(witness), write("]")) - }), - GeneratorWitness(types) => { - ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types))) - } - Closure(did, substs) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); - write!(f, "[closure")?; - - if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { - if tcx.sess.opts.debugging_opts.span_free_formats { - write!(f, "@{:?}", hir_id)?; - } else { - write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?; - } - let mut sep = " "; - tcx.with_freevars(hir_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, - write("{}{}:", - sep, - tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; - sep = ", "; - } - Ok(()) - })? - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - write!(f, "@{:?}", did)?; - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - print!(f, cx, - write("{}{}:", sep, index), - print(upvar_ty))?; - sep = ", "; - } - } - - if cx.is_verbose { - write!( - f, - " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, tcx), - substs.closure_sig_ty(did, tcx), - )?; - } - - write!(f, "]") - }), - Array(ty, sz) => { - print!(f, cx, write("["), print(ty), write("; "))?; - match sz { - ty::LazyConst::Unevaluated(_def_id, _substs) => { - write!(f, "_")?; - } - ty::LazyConst::Evaluated(c) => ty::tls::with(|tcx| { - match c.val { - ConstValue::Infer(..) => write!(f, "_"), - ConstValue::Param(ParamConst { name, .. }) => - write!(f, "{}", name), - _ => write!(f, "{}", c.unwrap_usize(tcx)), - } - })?, - } - write!(f, "]") - } - Slice(ty) => { - print!(f, cx, write("["), print(ty), write("]")) - } - } - } - } -} - -define_print! { - ('tcx) ty::TyS<'tcx>, (self, f, cx) { - display { - self.sty.print(f, cx) - } - debug { - self.sty.print_display(f, cx) - } - } -} - -define_print! { - ('tcx) ConstValue<'tcx>, (self, f, cx) { - display { - match self { - ConstValue::Infer(..) => write!(f, "_"), - ConstValue::Param(ParamConst { name, .. }) => write!(f, "{}", name), - _ => write!(f, "{:?}", self), - } - } - } -} - -define_print! { - ('tcx) ty::Const<'tcx>, (self, f, cx) { - display { - write!(f, "{} : {}", self.val, self.ty) - } - } -} - -define_print! { - ('tcx) ty::LazyConst<'tcx>, (self, f, cx) { - display { - match self { - ty::LazyConst::Unevaluated(..) => write!(f, "_ : _"), - ty::LazyConst::Evaluated(c) => write!(f, "{}", c), - } - } - } -} - -define_print! { - () ty::ParamTy, (self, f, cx) { - display { - write!(f, "{}", self.name) - } - debug { - write!(f, "{}/#{}", self.name, self.idx) - } - } -} - -define_print! { - () ty::ParamConst, (self, f, cx) { - display { - write!(f, "{}", self.name) - } - debug { - write!(f, "{}/#{}", self.name, self.index) - } - } -} - -define_print! { - ('tcx, T: Print + fmt::Debug, U: Print + fmt::Debug) ty::OutlivesPredicate, - (self, f, cx) { - display { - print!(f, cx, print(self.0), write(" : "), print(self.1)) - } - } -} - -define_print! { - ('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) { - display { - print!(f, cx, print(self.a), write(" <: "), print(self.b)) - } - } -} - -define_print! { - ('tcx) ty::TraitPredicate<'tcx>, (self, f, cx) { - debug { - write!(f, "TraitPredicate({:?})", - self.trait_ref) - } - display { - print!(f, cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) - } - } -} - -define_print! { - ('tcx) ty::ProjectionPredicate<'tcx>, (self, f, cx) { - debug { - print!(f, cx, - write("ProjectionPredicate("), - print(self.projection_ty), - write(", "), - print(self.ty), - write(")")) - } - display { - print!(f, cx, print(self.projection_ty), write(" == "), print(self.ty)) - } - } -} - -define_print! { - ('tcx) ty::ProjectionTy<'tcx>, (self, f, cx) { - display { - // FIXME(tschottdorf): use something like - // parameterized(f, self.substs, self.item_def_id, &[]) - // (which currently ICEs). - let (trait_ref, item_name) = ty::tls::with(|tcx| - (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).ident) - ); - print!(f, cx, print_debug(trait_ref), write("::{}", item_name)) - } - } -} - -define_print! { - () ty::ClosureKind, (self, f, cx) { - display { - match *self { - ty::ClosureKind::Fn => write!(f, "Fn"), - ty::ClosureKind::FnMut => write!(f, "FnMut"), - ty::ClosureKind::FnOnce => write!(f, "FnOnce"), - } - } - } -} - -define_print! { - ('tcx) ty::Predicate<'tcx>, (self, f, cx) { - display { - match *self { - ty::Predicate::Trait(ref data) => data.print(f, cx), - ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx), - ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx), - ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx), - ty::Predicate::Projection(ref predicate) => predicate.print(f, cx), - ty::Predicate::WellFormed(ty) => print!(f, cx, print(ty), write(" well-formed")), - ty::Predicate::ObjectSafe(trait_def_id) => - ty::tls::with(|tcx| { - write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id)) - }), - ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => - ty::tls::with(|tcx| { - write!(f, "the closure `{}` implements the trait `{}`", - tcx.item_path_str(closure_def_id), kind) - }), - ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "the constant `")?; - cx.parameterized(f, substs, def_id, &[])?; - write!(f, "` can be evaluated") - } - } - } - debug { - match *self { - ty::Predicate::Trait(ref a) => a.print(f, cx), - ty::Predicate::Subtype(ref pair) => pair.print(f, cx), - ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx), - ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx), - ty::Predicate::Projection(ref pair) => pair.print(f, cx), - ty::Predicate::WellFormed(ty) => ty.print(f, cx), - ty::Predicate::ObjectSafe(trait_def_id) => { - write!(f, "ObjectSafe({:?})", trait_def_id) - } - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) - } - ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) - } - } - } - } -} diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index c134d48f987be..2739a30a29135 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fs; use std::io::{BufWriter, Write}; use std::mem; @@ -20,12 +21,12 @@ pub enum ProfileCategory { Other, } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum ProfilerEvent { QueryStart { query_name: &'static str, category: ProfileCategory, time: u64 }, QueryEnd { query_name: &'static str, category: ProfileCategory, time: u64 }, - GenericActivityStart { category: ProfileCategory, time: u64 }, - GenericActivityEnd { category: ProfileCategory, time: u64 }, + GenericActivityStart { category: ProfileCategory, label: Cow<'static, str>, time: u64 }, + GenericActivityEnd { category: ProfileCategory, label: Cow<'static, str>, time: u64 }, IncrementalLoadResultStart { query_name: &'static str, time: u64 }, IncrementalLoadResultEnd { query_name: &'static str, time: u64 }, QueryCacheHit { query_name: &'static str, category: ProfileCategory, time: u64 }, @@ -75,17 +76,27 @@ impl SelfProfiler { } #[inline] - pub fn start_activity(&mut self, category: ProfileCategory) { + pub fn start_activity( + &mut self, + category: ProfileCategory, + label: impl Into>, + ) { self.record(ProfilerEvent::GenericActivityStart { category, + label: label.into(), time: self.get_time_from_start(), }) } #[inline] - pub fn end_activity(&mut self, category: ProfileCategory) { + pub fn end_activity( + &mut self, + category: ProfileCategory, + label: impl Into>, + ) { self.record(ProfilerEvent::GenericActivityEnd { category, + label: label.into(), time: self.get_time_from_start(), }) } @@ -273,11 +284,12 @@ impl SelfProfiler { nanos, thread_id, ).unwrap(), - GenericActivityStart { category, time: _ } => + GenericActivityStart { category, label, time: _ } => write!(file, "{{ \"GenericActivityStart\": {{\ \"category\": \"{:?}\",\ + \"label\": \"{}\",\ \"time\": {{\ \"secs\": {},\ \"nanos\": {}\ @@ -286,15 +298,17 @@ impl SelfProfiler { }}\ }}", category, + label, secs, nanos, thread_id, ).unwrap(), - GenericActivityEnd { category, time: _ } => + GenericActivityEnd { category, label, time: _ } => write!(file, "{{\ \"GenericActivityEnd\": {{\ \"category\": \"{:?}\",\ + \"label\": \"{}\",\ \"time\": {{\ \"secs\": {},\ \"nanos\": {}\ @@ -303,6 +317,7 @@ impl SelfProfiler { }}\ }}", category, + label, secs, nanos, thread_id, @@ -418,7 +433,7 @@ impl SelfProfiler { secs, nanos, thread_id, - ).unwrap() + ).unwrap(), } } } diff --git a/src/librustc/util/time_graph.rs b/src/librustc/util/time_graph.rs deleted file mode 100644 index 4dd383fd234ac..0000000000000 --- a/src/librustc/util/time_graph.rs +++ /dev/null @@ -1,268 +0,0 @@ -use rustc_data_structures::fx::FxHashMap; -use std::fs::File; -use std::io::prelude::*; -use std::marker::PhantomData; -use std::mem; -use std::sync::{Arc, Mutex}; -use std::time::Instant; - -const OUTPUT_WIDTH_IN_PX: u64 = 1000; -const TIME_LINE_HEIGHT_IN_PX: u64 = 20; -const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30; - -#[derive(Clone)] -struct Timing { - start: Instant, - end: Instant, - work_package_kind: WorkPackageKind, - name: String, - events: Vec<(String, Instant)>, -} - -#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)] -pub struct TimelineId(pub usize); - -#[derive(Clone)] -struct PerThread { - timings: Vec, - open_work_package: Option<(Instant, WorkPackageKind, String)>, -} - -#[derive(Clone)] -pub struct TimeGraph { - data: Arc>>, -} - -#[derive(Clone, Copy)] -pub struct WorkPackageKind(pub &'static [&'static str]); - -pub struct Timeline { - token: Option, -} - -struct RaiiToken { - graph: TimeGraph, - timeline: TimelineId, - events: Vec<(String, Instant)>, - // The token must not be Send: - _marker: PhantomData<*const ()> -} - - -impl Drop for RaiiToken { - fn drop(&mut self) { - self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new())); - } -} - -impl TimeGraph { - pub fn new() -> TimeGraph { - TimeGraph { - data: Arc::new(Mutex::new(FxHashMap::default())) - } - } - - pub fn start(&self, - timeline: TimelineId, - work_package_kind: WorkPackageKind, - name: &str) -> Timeline { - { - let mut table = self.data.lock().unwrap(); - - let data = table.entry(timeline).or_insert(PerThread { - timings: Vec::new(), - open_work_package: None, - }); - - assert!(data.open_work_package.is_none()); - data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string())); - } - - Timeline { - token: Some(RaiiToken { - graph: self.clone(), - timeline, - events: Vec::new(), - _marker: PhantomData, - }), - } - } - - fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) { - let end = Instant::now(); - - let mut table = self.data.lock().unwrap(); - let data = table.get_mut(&timeline).unwrap(); - - if let Some((start, work_package_kind, name)) = data.open_work_package.take() { - data.timings.push(Timing { - start, - end, - work_package_kind, - name, - events, - }); - } else { - bug!("end timing without start?") - } - } - - pub fn dump(&self, output_filename: &str) { - let table = self.data.lock().unwrap(); - - for data in table.values() { - assert!(data.open_work_package.is_none()); - } - - let mut threads: Vec = - table.values().map(|data| data.clone()).collect(); - - threads.sort_by_key(|timeline| timeline.timings[0].start); - - let earliest_instant = threads[0].timings[0].start; - let latest_instant = threads.iter() - .map(|timeline| timeline.timings - .last() - .unwrap() - .end) - .max() - .unwrap(); - let max_distance = distance(earliest_instant, latest_instant); - - let mut file = File::create(format!("{}.html", output_filename)).unwrap(); - - writeln!(file, " - - - - - - - ").unwrap(); - - let mut idx = 0; - for thread in threads.iter() { - for timing in &thread.timings { - let colors = timing.work_package_kind.0; - let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len(); - writeln!(file, "
", - idx, - colors[idx % colors.len()], - height).unwrap(); - idx += 1; - let max = distance(timing.start, timing.end); - for (i, &(ref event, time)) in timing.events.iter().enumerate() { - let i = i as u64; - let time = distance(timing.start, time); - let at = normalize(time, max, OUTPUT_WIDTH_IN_PX); - writeln!(file, "{}", - at, - TIME_LINE_HEIGHT_IN_PX * i, - event).unwrap(); - } - writeln!(file, "
").unwrap(); - } - } - - writeln!(file, " - - - ").unwrap(); - } -} - -impl Timeline { - pub fn noop() -> Timeline { - Timeline { token: None } - } - - /// Record an event which happened at this moment on this timeline. - /// - /// Events are displayed in the eventual HTML output where you can click on - /// a particular timeline and it'll expand to all of the events that - /// happened on that timeline. This can then be used to drill into a - /// particular timeline and see what events are happening and taking the - /// most time. - pub fn record(&mut self, name: &str) { - if let Some(ref mut token) = self.token { - token.events.push((name.to_string(), Instant::now())); - } - } -} - -fn distance(zero: Instant, x: Instant) -> u64 { - - let duration = x.duration_since(zero); - (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div -} - -fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 { - (max_pixels * distance) / max -} - diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index da065f9e05d9e..01bfe5d5af706 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1406,7 +1406,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { out.push('('); self.append_loan_path_to_string(&lp_base, out); out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.item_path_str(variant_def_id)); + out.push_str(&self.tcx.def_path_str(variant_def_id)); out.push(')'); } @@ -1443,7 +1443,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { out.push('('); self.append_autoderefd_loan_path_to_string(&lp_base, out); out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.item_path_str(variant_def_id)); + out.push_str(&self.tcx.def_path_str(variant_def_id)); out.push(')'); } @@ -1523,7 +1523,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; @@ -1558,7 +1558,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 944569c8b744b..84c652ff238af 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -3,7 +3,6 @@ use crate::back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitc to_llvm_opt_settings}; use crate::llvm::archive_ro::ArchiveRO; use crate::llvm::{self, True, False}; -use crate::time_graph::Timeline; use crate::{ModuleLlvm, LlvmCodegenBackend}; use rustc_codegen_ssa::back::symbol_export; use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, FatLTOInput}; @@ -16,6 +15,7 @@ use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{self, Lto}; use rustc::util::common::time_ext; +use rustc::util::profiling::ProfileCategory; use rustc_data_structures::fx::FxHashMap; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; @@ -37,7 +37,6 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool { } fn prepare_lto(cgcx: &CodegenContext, - timeline: &mut Timeline, diag_handler: &Handler) -> Result<(Vec, Vec<(SerializedModule, CString)>), FatalError> { @@ -68,7 +67,8 @@ fn prepare_lto(cgcx: &CodegenContext, .iter() .filter_map(symbol_filter) .collect::>(); - timeline.record("whitelist"); + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "generate_symbol_white_list_for_thinlto"); info!("{} symbols to preserve in this crate", symbol_white_list.len()); // If we're performing LTO for the entire crate graph, then for each of our @@ -97,6 +97,8 @@ fn prepare_lto(cgcx: &CodegenContext, } for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + format!("load: {}", path.display())); let exported_symbols = cgcx.exported_symbols .as_ref().expect("needs exported symbols for LTO"); symbol_white_list.extend( @@ -121,7 +123,6 @@ fn prepare_lto(cgcx: &CodegenContext, let bc = SerializedModule::FromRlib(bc); upstream_modules.push((bc, CString::new(id).unwrap())); } - timeline.record(&format!("load: {}", path.display())); } } @@ -132,12 +133,11 @@ fn prepare_lto(cgcx: &CodegenContext, /// for further optimization. pub(crate) fn run_fat(cgcx: &CodegenContext, modules: Vec>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline) + cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); - let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?; + let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; let symbol_white_list = symbol_white_list.iter() .map(|c| c.as_ptr()) .collect::>(); @@ -148,7 +148,6 @@ pub(crate) fn run_fat(cgcx: &CodegenContext, cached_modules, upstream_modules, &symbol_white_list, - timeline, ) } @@ -157,12 +156,11 @@ pub(crate) fn run_fat(cgcx: &CodegenContext, /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin(cgcx: &CodegenContext, modules: Vec<(String, ThinBuffer)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline) + cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result<(Vec>, Vec), FatalError> { let diag_handler = cgcx.create_diag_handler(); - let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?; + let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; let symbol_white_list = symbol_white_list.iter() .map(|c| c.as_ptr()) .collect::>(); @@ -175,8 +173,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext, modules, upstream_modules, cached_modules, - &symbol_white_list, - timeline) + &symbol_white_list) } pub(crate) fn prepare_thin( @@ -192,8 +189,7 @@ fn fat_lto(cgcx: &CodegenContext, mut modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule, CString)>, - symbol_white_list: &[*const libc::c_char], - timeline: &mut Timeline) + symbol_white_list: &[*const libc::c_char]) -> Result, FatalError> { info!("going for a fat lto"); @@ -303,7 +299,6 @@ fn fat_lto(cgcx: &CodegenContext, write::llvm_err(&diag_handler, &msg) }) })?; - timeline.record(&format!("link {:?}", name)); serialized_bitcode.push(bc_decoded); } drop(linker); @@ -325,7 +320,6 @@ fn fat_lto(cgcx: &CodegenContext, } save_temp_bitcode(&cgcx, &module, "lto.after-nounwind"); } - timeline.record("passes"); } Ok(LtoModuleCodegen::Fat { @@ -395,8 +389,7 @@ fn thin_lto(cgcx: &CodegenContext, modules: Vec<(String, ThinBuffer)>, serialized_modules: Vec<(SerializedModule, CString)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - symbol_white_list: &[*const libc::c_char], - timeline: &mut Timeline) + symbol_white_list: &[*const libc::c_char]) -> Result<(Vec>, Vec), FatalError> { unsafe { @@ -422,7 +415,6 @@ fn thin_lto(cgcx: &CodegenContext, }); thin_buffers.push(buffer); module_names.push(cname); - timeline.record(&name); } // FIXME: All upstream crates are deserialized internally in the @@ -475,7 +467,6 @@ fn thin_lto(cgcx: &CodegenContext, })?; info!("thin LTO data created"); - timeline.record("data"); let import_map = if cgcx.incr_comp_session_dir.is_some() { ThinLTOImports::from_thin_lto_data(data) @@ -486,7 +477,6 @@ fn thin_lto(cgcx: &CodegenContext, ThinLTOImports::default() }; info!("thin LTO import map loaded"); - timeline.record("import-map-loaded"); let data = ThinData(data); @@ -691,7 +681,6 @@ impl Drop for ThinBuffer { pub unsafe fn optimize_thin_module( thin_module: &mut ThinModule, cgcx: &CodegenContext, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); let tm = (cgcx.tm_factory.0)().map_err(|e| { @@ -738,9 +727,10 @@ pub unsafe fn optimize_thin_module( // Like with "fat" LTO, get some better optimizations if landing pads // are disabled by removing all landing pads. if cgcx.no_landing_pads { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "LLVM_remove_landing_pads"); llvm::LLVMRustMarkAllFunctionsNounwind(llmod); save_temp_bitcode(&cgcx, &module, "thin-lto-after-nounwind"); - timeline.record("nounwind"); } // Up next comes the per-module local analyses that we do for Thin LTO. @@ -756,25 +746,21 @@ pub unsafe fn optimize_thin_module( return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); - timeline.record("rename"); if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); - timeline.record("resolve"); if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); - timeline.record("internalize"); if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); - timeline.record("import"); // Ok now this is a bit unfortunate. This is also something you won't // find upstream in LLVM's ThinLTO passes! This is a hack for now to @@ -807,7 +793,6 @@ pub unsafe fn optimize_thin_module( // fixed in LLVM. llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); - timeline.record("patch"); // Alright now that we've done everything related to the ThinLTO // analysis it's time to run some optimizations! Here we use the same @@ -818,7 +803,6 @@ pub unsafe fn optimize_thin_module( let config = cgcx.config(module.kind); run_pass_manager(cgcx, &module, config, true); save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); - timeline.record("thin-done"); } Ok(module) } diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index db5430a4219a0..dc4dd4e39e17b 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -3,7 +3,6 @@ use crate::back::bytecode::{self, RLIB_BYTECODE_EXTENSION}; use crate::back::lto::ThinBuffer; use crate::base; use crate::consts; -use crate::time_graph::Timeline; use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic}; use crate::llvm_util; use crate::ModuleLlvm; @@ -19,6 +18,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_codegen_ssa::{ModuleCodegen, CompiledModule}; use rustc::util::common::time_ext; +use rustc::util::profiling::ProfileCategory; use rustc_fs_util::{path_to_c_string, link_or_copy}; use rustc_data_structures::small_c_str::SmallCStr; use errors::{Handler, FatalError}; @@ -305,8 +305,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void pub(crate) unsafe fn optimize(cgcx: &CodegenContext, diag_handler: &Handler, module: &ModuleCodegen, - config: &ModuleConfig, - timeline: &mut Timeline) + config: &ModuleConfig) -> Result<(), FatalError> { let llmod = module.module_llvm.llmod(); @@ -415,19 +414,24 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, diag_handler.abort_if_errors(); // Finally, run the actual optimization passes - time_ext(config.time_passes, - None, - &format!("llvm function passes [{}]", module_name.unwrap()), - || { - llvm::LLVMRustRunFunctionPassManager(fpm, llmod) - }); - timeline.record("fpm"); - time_ext(config.time_passes, - None, - &format!("llvm module passes [{}]", module_name.unwrap()), - || { - llvm::LLVMRunPassManager(mpm, llmod) - }); + { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_function_passes"); + time_ext(config.time_passes, + None, + &format!("llvm function passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRustRunFunctionPassManager(fpm, llmod) + }); + } + { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_module_passes"); + time_ext(config.time_passes, + None, + &format!("llvm module passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRunPassManager(mpm, llmod) + }); + } // Deallocate managers that we're now done with llvm::LLVMDisposePassManager(fpm); @@ -439,11 +443,10 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, pub(crate) unsafe fn codegen(cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, - config: &ModuleConfig, - timeline: &mut Timeline) + config: &ModuleConfig) -> Result { - timeline.record("codegen"); + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "codegen"); { let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; @@ -494,29 +497,30 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, if write_bc || config.emit_bc_compressed || config.embed_bitcode { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_make_bitcode"); let thin = ThinBuffer::new(llmod); let data = thin.data(); - timeline.record("make-bc"); if write_bc { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode"); if let Err(e) = fs::write(&bc_out, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } - timeline.record("write-bc"); } if config.embed_bitcode { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_embed_bitcode"); embed_bitcode(cgcx, llcx, llmod, Some(data)); - timeline.record("embed-bc"); } if config.emit_bc_compressed { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "LLVM_compress_bitcode"); let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); let data = bytecode::encode(&module.name, data); if let Err(e) = fs::write(&dst, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } - timeline.record("compress-bc"); } } else if config.embed_bitcode_marker { embed_bitcode(cgcx, llcx, llmod, None); @@ -525,6 +529,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), || -> Result<(), FatalError> { if config.emit_ir { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir"); let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); let out = path_to_c_string(&out); @@ -563,10 +568,10 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback); llvm::LLVMDisposePassManager(cpm); }); - timeline.record("ir"); } if config.emit_asm || asm_to_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_asm"); let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); // We can't use the same module for asm and binary output, because that triggers @@ -581,19 +586,18 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) })?; - timeline.record("asm"); } if write_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_obj"); with_codegen(tm, llmod, config.no_builtins, |cpm| { write_output_file(diag_handler, tm, cpm, llmod, &obj_out, llvm::FileType::ObjectFile) })?; - timeline.record("obj"); } else if asm_to_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_asm_to_obj"); let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); run_assembler(cgcx, diag_handler, &assembly, &obj_out); - timeline.record("asm_to_obj"); if !config.emit_asm && !cgcx.save_temps { drop(fs::remove_file(&assembly)); diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 3268af396a2f4..ceb08f943678b 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -513,8 +513,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { }, "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { - let sty = &arg_tys[0].sty; - match float_type_width(sty) { + match float_type_width(arg_tys[0]) { Some(_width) => match name { "fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()), @@ -528,7 +527,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { span_invalid_monomorphization_error( tcx.sess, span, &format!("invalid monomorphization of `{}` intrinsic: \ - expected basic float type, found `{}`", name, sty)); + expected basic float type, found `{}`", name, arg_tys[0])); return; } } @@ -1473,8 +1472,8 @@ fn generic_simd_intrinsic( require!(false, "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*_ {}`", - arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx).sty, in_elem); + arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, + arg_tys[1].simd_type(tcx), in_elem); unreachable!(); } }; @@ -1488,7 +1487,7 @@ fn generic_simd_intrinsic( _ => { require!(false, "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx).sty, arg_tys[2]); + arg_tys[2].simd_type(tcx), arg_tys[2]); } } @@ -1573,8 +1572,8 @@ fn generic_simd_intrinsic( require!(false, "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*mut {}`", - arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx).sty, in_elem); + arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, + arg_tys[1].simd_type(tcx), in_elem); unreachable!(); } }; @@ -1588,7 +1587,7 @@ fn generic_simd_intrinsic( _ => { require!(false, "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx).sty, arg_tys[2]); + arg_tys[2].simd_type(tcx), arg_tys[2]); } } @@ -1904,7 +1903,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, return_error!( "expected element type `{}` of vector type `{}` \ to be a signed or unsigned integer type", - arg_tys[0].simd_type(tcx).sty, arg_tys[0] + arg_tys[0].simd_type(tcx), arg_tys[0] ); } }; @@ -1954,10 +1953,10 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo } } -// Returns the width of a float TypeVariant +// Returns the width of a float Ty // Returns None if the type is not a float -fn float_type_width<'tcx>(sty: &ty::TyKind<'tcx>) -> Option { - match *sty { +fn float_type_width(ty: Ty<'_>) -> Option { + match ty.sty { ty::Float(t) => Some(t.bit_width() as u64), _ => None, } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7b2b9ec24ea0f..c75788ecb4fbd 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -15,7 +15,6 @@ #![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(optin_builtin_traits)] #![feature(concat_idents)] @@ -53,7 +52,6 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModul use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; -use rustc::util::time_graph::Timeline; use syntax_pos::symbol::InternedString; use rustc::mir::mono::Stats; pub use llvm_util::target_features; @@ -66,7 +64,6 @@ use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; -use rustc::util::time_graph; use rustc::util::profiling::ProfileCategory; use rustc::util::common::ErrorReported; use rustc_mir::monomorphize; @@ -167,42 +164,37 @@ impl WriteBackendMethods for LlvmCodegenBackend { cgcx: &CodegenContext, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline ) -> Result, FatalError> { - back::lto::run_fat(cgcx, modules, cached_modules, timeline) + back::lto::run_fat(cgcx, modules, cached_modules) } fn run_thin_lto( cgcx: &CodegenContext, modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline ) -> Result<(Vec>, Vec), FatalError> { - back::lto::run_thin(cgcx, modules, cached_modules, timeline) + back::lto::run_thin(cgcx, modules, cached_modules) } unsafe fn optimize( cgcx: &CodegenContext, diag_handler: &Handler, module: &ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline ) -> Result<(), FatalError> { - back::write::optimize(cgcx, diag_handler, module, config, timeline) + back::write::optimize(cgcx, diag_handler, module, config) } unsafe fn optimize_thin( cgcx: &CodegenContext, thin: &mut ThinModule, - timeline: &mut Timeline ) -> Result, FatalError> { - back::lto::optimize_thin_module(thin, cgcx, timeline) + back::lto::optimize_thin_module(thin, cgcx) } unsafe fn codegen( cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline ) -> Result { - back::write::codegen(cgcx, diag_handler, module, config, timeline) + back::write::codegen(cgcx, diag_handler, module, config) } fn prepare_thin( module: ModuleCodegen @@ -336,12 +328,12 @@ impl CodegenBackend for LlvmCodegenBackend { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - sess.profiler(|p| p.start_activity(ProfileCategory::Linking)); + sess.profiler(|p| p.start_activity(ProfileCategory::Linking, "link_crate")); time(sess, "linking", || { back::link::link_binary(sess, &codegen_results, outputs, &codegen_results.crate_name.as_str()); }); - sess.profiler(|p| p.end_activity(ProfileCategory::Linking)); + sess.profiler(|p| p.end_activity(ProfileCategory::Linking, "link_crate")); // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 1f4c5543fa9aa..e6470dbb61ce1 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.target.options.is_like_osx { // Write a plain, newline-separated list of symbols - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); for sym in self.info.exports[&crate_type].iter() { debug!(" _{}", sym); writeln!(f, "_{}", sym)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } } else { // Write an LD version script - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); writeln!(f, "{{\n global:")?; for sym in self.info.exports[&crate_type].iter() { @@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {};", sym)?; } writeln!(f, "\n local:\n *;\n}};")?; - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write version script: {}", e)); } @@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> { tmpdir: &Path, crate_type: CrateType) { let path = tmpdir.join("lib.def"); - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); // Start off with the standard module name header and then go @@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } diff --git a/src/librustc_codegen_ssa/back/lto.rs b/src/librustc_codegen_ssa/back/lto.rs index 7f0eba7b0850b..47e5d9af33ba4 100644 --- a/src/librustc_codegen_ssa/back/lto.rs +++ b/src/librustc_codegen_ssa/back/lto.rs @@ -2,7 +2,6 @@ use super::write::CodegenContext; use crate::traits::*; use crate::ModuleCodegen; -use rustc::util::time_graph::Timeline; use rustc_errors::FatalError; use std::sync::Arc; @@ -67,7 +66,6 @@ impl LtoModuleCodegen { pub unsafe fn optimize( &mut self, cgcx: &CodegenContext, - timeline: &mut Timeline ) -> Result, FatalError> { match *self { LtoModuleCodegen::Fat { ref mut module, .. } => { @@ -75,11 +73,10 @@ impl LtoModuleCodegen { { let config = cgcx.config(module.kind); B::run_lto_pass_manager(cgcx, &module, config, false); - timeline.record("fat-done"); } Ok(module) } - LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin, timeline), + LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin), } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index c84b38cde8185..859dfb99d92b8 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -15,11 +15,10 @@ use rustc::middle::cstore::EncodedMetadata; use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Sanitizer, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use rustc::util::time_graph::{self, TimeGraph, Timeline}; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; -use rustc::util::profiling::SelfProfiler; +use rustc::util::profiling::{ProfileCategory, SelfProfiler}; use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; @@ -33,6 +32,7 @@ use jobserver::{Client, Acquired}; use parking_lot::Mutex as PlMutex; use std::any::Any; +use std::borrow::Cow; use std::fs; use std::io; use std::mem; @@ -197,6 +197,40 @@ impl Clone for TargetMachineFactory { } } +pub struct ProfileGenericActivityTimer { + profiler: Option>>, + category: ProfileCategory, + label: Cow<'static, str>, +} + +impl ProfileGenericActivityTimer { + pub fn start( + profiler: Option>>, + category: ProfileCategory, + label: Cow<'static, str>, + ) -> ProfileGenericActivityTimer { + if let Some(profiler) = &profiler { + let mut p = profiler.lock(); + p.start_activity(category, label.clone()); + } + + ProfileGenericActivityTimer { + profiler, + category, + label, + } + } +} + +impl Drop for ProfileGenericActivityTimer { + fn drop(&mut self) { + if let Some(profiler) = &self.profiler { + let mut p = profiler.lock(); + p.end_activity(self.category, self.label.clone()); + } + } +} + /// Additional resources used by optimize_and_codegen (not module specific) #[derive(Clone)] pub struct CodegenContext { @@ -238,9 +272,6 @@ pub struct CodegenContext { pub cgu_reuse_tracker: CguReuseTracker, // Channel back to the main control thread to send messages to pub coordinator_send: Sender>, - // A reference to the TimeGraph so we can register timings. None means that - // measuring is disabled. - pub time_graph: Option, // The assembler command if no_integrated_as option is enabled, None otherwise pub assembler_cmd: Option> } @@ -277,6 +308,14 @@ impl CodegenContext { self.profiler_active(f) } } + + pub fn profile_activity( + &self, + category: ProfileCategory, + label: impl Into>, + ) -> ProfileGenericActivityTimer { + ProfileGenericActivityTimer::start(self.profiler.clone(), category, label.into()) + } } fn generate_lto_work( @@ -285,11 +324,7 @@ fn generate_lto_work( needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule, WorkProduct)> ) -> Vec<(WorkItem, u64)> { - let mut timeline = cgcx.time_graph.as_ref().map(|tg| { - tg.start(CODEGEN_WORKER_TIMELINE, - CODEGEN_WORK_PACKAGE_KIND, - "generate lto") - }).unwrap_or(Timeline::noop()); + cgcx.profile(|p| p.start_activity(ProfileCategory::Linking, "codegen_run_lto")); let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); @@ -297,17 +332,16 @@ fn generate_lto_work( cgcx, needs_fat_lto, import_only_modules, - &mut timeline, ) .unwrap_or_else(|e| e.raise()); (vec![lto_module], vec![]) } else { assert!(needs_fat_lto.is_empty()); - B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline) + B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules) .unwrap_or_else(|e| e.raise()) }; - lto_modules.into_iter().map(|module| { + let result = lto_modules.into_iter().map(|module| { let cost = module.cost(); (WorkItem::LTO(module), cost) }).chain(copy_jobs.into_iter().map(|wp| { @@ -315,7 +349,11 @@ fn generate_lto_work( name: wp.cgu_name.clone(), source: wp, }), 0) - })).collect() + })).collect(); + + cgcx.profile(|p| p.end_activity(ProfileCategory::Linking, "codegen_run_lto")); + + result } pub struct CompiledModules { @@ -345,7 +383,6 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { pub fn start_async_codegen( backend: B, tcx: TyCtxt<'_, '_, '_>, - time_graph: Option, metadata: EncodedMetadata, coordinator_receive: Receiver>, total_cgus: usize @@ -469,7 +506,6 @@ pub fn start_async_codegen( coordinator_receive, total_cgus, sess.jobserver.clone(), - time_graph.clone(), Arc::new(modules_config), Arc::new(metadata_config), Arc::new(allocator_config)); @@ -483,7 +519,6 @@ pub fn start_async_codegen( linker_info, crate_info, - time_graph, coordinator_send: tcx.tx_to_llvm_workers.lock().clone(), codegen_worker_receive, shared_emitter_main, @@ -728,19 +763,18 @@ pub enum FatLTOInput { fn execute_work_item( cgcx: &CodegenContext, work_item: WorkItem, - timeline: &mut Timeline ) -> Result, FatalError> { let module_config = cgcx.config(work_item.module_kind()); match work_item { WorkItem::Optimize(module) => { - execute_optimize_work_item(cgcx, module, module_config, timeline) + execute_optimize_work_item(cgcx, module, module_config) } WorkItem::CopyPostLtoArtifacts(module) => { - execute_copy_from_cache_work_item(cgcx, module, module_config, timeline) + execute_copy_from_cache_work_item(cgcx, module, module_config) } WorkItem::LTO(module) => { - execute_lto_work_item(cgcx, module, module_config, timeline) + execute_lto_work_item(cgcx, module, module_config) } } } @@ -756,12 +790,11 @@ fn execute_optimize_work_item( cgcx: &CodegenContext, module: ModuleCodegen, module_config: &ModuleConfig, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); unsafe { - B::optimize(cgcx, &diag_handler, &module, module_config, timeline)?; + B::optimize(cgcx, &diag_handler, &module, module_config)?; } // After we've done the initial round of optimizations we need to @@ -818,7 +851,7 @@ fn execute_optimize_work_item( Ok(match lto_type { ComputedLtoType::No => { let module = unsafe { - B::codegen(cgcx, &diag_handler, module, module_config, timeline)? + B::codegen(cgcx, &diag_handler, module, module_config)? }; WorkItemResult::Compiled(module) } @@ -854,7 +887,6 @@ fn execute_copy_from_cache_work_item( cgcx: &CodegenContext, module: CachedModuleCodegen, module_config: &ModuleConfig, - _: &mut Timeline ) -> Result, FatalError> { let incr_comp_session_dir = cgcx.incr_comp_session_dir .as_ref() @@ -916,13 +948,12 @@ fn execute_lto_work_item( cgcx: &CodegenContext, mut module: lto::LtoModuleCodegen, module_config: &ModuleConfig, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); unsafe { - let module = module.optimize(cgcx, timeline)?; - let module = B::codegen(cgcx, &diag_handler, module, module_config, timeline)?; + let module = module.optimize(cgcx)?; + let module = B::codegen(cgcx, &diag_handler, module, module_config)?; Ok(WorkItemResult::Compiled(module)) } } @@ -977,7 +1008,6 @@ fn start_executing_work( coordinator_receive: Receiver>, total_cgus: usize, jobserver: Client, - time_graph: Option, modules_config: Arc, metadata_config: Arc, allocator_config: Arc @@ -1065,7 +1095,6 @@ fn start_executing_work( cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(), coordinator_send, diag_emitter: shared_emitter.clone(), - time_graph, output_filenames: tcx.output_filenames(LOCAL_CRATE), regular_module_config: modules_config, metadata_module_config: metadata_config, @@ -1570,12 +1599,6 @@ fn start_executing_work( } pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; -pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId = - time_graph::TimelineId(CODEGEN_WORKER_ID); -pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]); -const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]); fn spawn_work( cgcx: CodegenContext, @@ -1625,13 +1648,12 @@ fn spawn_work( // as a diagnostic was already sent off to the main thread - just // surface that there was an error in this worker. bomb.result = { - let timeline = cgcx.time_graph.as_ref().map(|tg| { - tg.start(time_graph::TimelineId(cgcx.worker), - LLVM_WORK_PACKAGE_KIND, - &work.name()) - }); - let mut timeline = timeline.unwrap_or(Timeline::noop()); - execute_work_item(&cgcx, work, &mut timeline).ok() + let label = work.name(); + cgcx.profile(|p| p.start_activity(ProfileCategory::Codegen, label.clone())); + let result = execute_work_item(&cgcx, work).ok(); + cgcx.profile(|p| p.end_activity(ProfileCategory::Codegen, label)); + + result }; }); } @@ -1785,7 +1807,6 @@ pub struct OngoingCodegen { pub windows_subsystem: Option, pub linker_info: LinkerInfo, pub crate_info: CrateInfo, - pub time_graph: Option, pub coordinator_send: Sender>, pub codegen_worker_receive: Receiver>, pub shared_emitter_main: SharedEmitterMain, @@ -1814,10 +1835,6 @@ impl OngoingCodegen { sess.abort_if_errors(); - if let Some(time_graph) = self.time_graph { - time_graph.dump(&format!("{}-timings", self.crate_name)); - } - let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 39ce15e477296..48743be3a2551 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -29,7 +29,6 @@ use rustc::util::profiling::ProfileCategory; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; use rustc_mir::monomorphize::item::DefPathBasedNames; -use rustc::util::time_graph; use rustc_mir::monomorphize::Instance; use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; use rustc::util::nodemap::FxHashMap; @@ -528,11 +527,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; -pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId = - time_graph::TimelineId(CODEGEN_WORKER_ID); -pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]); - pub fn codegen_crate( backend: B, @@ -545,7 +539,7 @@ pub fn codegen_crate( let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); // Codegen the metadata. - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate metadata")); let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], @@ -555,7 +549,7 @@ pub fn codegen_crate( let metadata = time(tcx.sess, "write metadata", || { backend.write_metadata(tcx, &mut metadata_llvm_module) }); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate metadata")); let metadata_module = ModuleCodegen { name: metadata_cgu_name, @@ -563,19 +557,12 @@ pub fn codegen_crate( kind: ModuleKind::Metadata, }; - let time_graph = if tcx.sess.opts.debugging_opts.codegen_time_graph { - Some(time_graph::TimeGraph::new()) - } else { - None - }; - // Skip crate items and just output metadata in -Z no-codegen mode. if tcx.sess.opts.debugging_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { let ongoing_codegen = start_async_codegen( backend, tcx, - time_graph, metadata, rx, 1); @@ -609,7 +596,6 @@ pub fn codegen_crate( let ongoing_codegen = start_async_codegen( backend.clone(), tcx, - time_graph.clone(), metadata, rx, codegen_units.len()); @@ -676,15 +662,14 @@ pub fn codegen_crate( match cgu_reuse { CguReuse::No => { - let _timing_guard = time_graph.as_ref().map(|time_graph| { - time_graph.start(CODEGEN_WORKER_TIMELINE, - CODEGEN_WORK_PACKAGE_KIND, - &format!("codegen {}", cgu.name())) - }); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, + format!("codegen {}", cgu.name()))); let start_time = Instant::now(); let stats = backend.compile_codegen_unit(tcx, *cgu.name()); all_stats.extend(stats); total_codegen_time += start_time.elapsed(); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, + format!("codegen {}", cgu.name()))); false } CguReuse::PreLto => { diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index fec41936a2384..fe9b88c85f009 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -7,6 +7,7 @@ #![feature(libc)] #![feature(rustc_diagnostic_macros)] #![feature(stmt_expr_attributes)] +#![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] #![allow(unused_attributes)] diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 349c9132842b8..2bb68dc687ca9 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let field_ty = c.ty.builtin_index().unwrap(); let fields = match c.ty.sty { ty::Array(_, n) => n.unwrap_usize(bx.tcx()), - ref other => bug!("invalid simd shuffle type: {}", other), + _ => bug!("invalid simd shuffle type: {}", c.ty), }; let values: Vec<_> = (0..fields).map(|field| { let field = const_field( diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 7c5e615f22452..fe00276a55a45 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -148,7 +148,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), + _ => bug!("unexpected unsized tail: {:?}", tail), } } } diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs index d8fb7c608c8af..23bb7179557b9 100644 --- a/src/librustc_codegen_ssa/traits/write.rs +++ b/src/librustc_codegen_ssa/traits/write.rs @@ -3,7 +3,6 @@ use crate::back::write::{CodegenContext, ModuleConfig, FatLTOInput}; use crate::{CompiledModule, ModuleCodegen}; use rustc::dep_graph::WorkProduct; -use rustc::util::time_graph::Timeline; use rustc_errors::{FatalError, Handler}; pub trait WriteBackendMethods: 'static + Sized + Clone { @@ -20,7 +19,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { cgcx: &CodegenContext, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline, ) -> Result, FatalError>; /// Performs thin LTO by performing necessary global analysis and returning two /// lists, one of the modules that need optimization and another for modules that @@ -29,7 +27,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { cgcx: &CodegenContext, modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline, ) -> Result<(Vec>, Vec), FatalError>; fn print_pass_timings(&self); unsafe fn optimize( @@ -37,19 +34,16 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { diag_handler: &Handler, module: &ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline, ) -> Result<(), FatalError>; unsafe fn optimize_thin( cgcx: &CodegenContext, thin: &mut ThinModule, - timeline: &mut Timeline, ) -> Result, FatalError>; unsafe fn codegen( cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline, ) -> Result; fn prepare_thin( module: ModuleCodegen diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 2b70141894be9..466cf40a15795 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -4,6 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 5de5c297c30e5..0fa935199f97b 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -87,14 +87,14 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; -use rustc::hir::map::definitions::DefPathData; +use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; use rustc::ich::NodeIdHashingMode; -use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; +use rustc::ty::print::{PrettyPrinter, Printer, Print}; use rustc::ty::query::Providers; -use rustc::ty::subst::SubstsRef; +use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::record_time; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -105,8 +105,8 @@ use syntax_pos::symbol::Symbol; use log::debug; -use std::fmt::Write; -use std::mem::discriminant; +use std::fmt::{self, Write}; +use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { @@ -223,11 +223,11 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - let mut buffer = SymbolPathBuffer::new(tcx); - item_path::with_forced_absolute_paths(|| { - tcx.push_item_path(&mut buffer, def_id, false); - }); - buffer.into_interned() + SymbolPrinter { + tcx, + path: SymbolPath::new(), + keep_within_component: false, + }.print_def_path(def_id, &[]).unwrap().path.into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -319,13 +319,17 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx); + let mut printer = SymbolPrinter { + tcx, + path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)), + keep_within_component: false, + }; if instance.is_vtable_shim() { - buf.push("{{vtable-shim}}"); + let _ = printer.write_str("{{vtable-shim}}"); } - buf.finish(hash) + printer.path.finish(hash) } // Follow C++ namespace-mangling style, see @@ -342,126 +346,312 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. #[derive(Debug)] -struct SymbolPathBuffer { +struct SymbolPath { result: String, temp_buf: String, - strict_naming: bool, } -impl SymbolPathBuffer { - fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { - let mut result = SymbolPathBuffer { +impl SymbolPath { + fn new() -> Self { + let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { - let mut result = SymbolPathBuffer { + fn from_interned(symbol: ty::SymbolName) -> Self { + let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str(&symbol.as_str()); result } - fn into_interned(self) -> ty::SymbolName { + fn into_interned(mut self) -> ty::SymbolName { + self.finalize_pending_component(); ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str(), } } + fn finalize_pending_component(&mut self) { + if !self.temp_buf.is_empty() { + let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf); + self.temp_buf.clear(); + } + } + fn finish(mut self, hash: u64) -> String { + self.finalize_pending_component(); // E = end name-sequence let _ = write!(self.result, "17h{:016x}E", hash); self.result } +} + +struct SymbolPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + path: SymbolPath, + + // When `true`, `finalize_pending_component` isn't used. + // This is needed when recursing into `path_qualified`, + // or `path_generic_args`, as any nested paths are + // logically within one component. + keep_within_component: bool, +} - // Name sanitation. LLVM will happily accept identifiers with weird names, but - // gas doesn't! - // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ - // NVPTX assembly has more strict naming rules than gas, so additionally, dots - // are replaced with '$' there. - fn sanitize_and_append(&mut self, s: &str) { - self.temp_buf.clear(); +// HACK(eddyb) this relies on using the `fmt` interface to get +// `PrettyPrinter` aka pretty printing of e.g. types in paths, +// symbol names should have their own printing machinery. + +impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { + type Error = fmt::Error; + + type Path = Self; + type Region = Self; + type Type = Self; + type DynExistential = Self; + + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + + fn print_region( + self, + _region: ty::Region<'_>, + ) -> Result { + Ok(self) + } + + fn print_type( + self, + ty: Ty<'tcx>, + ) -> Result { + match ty.sty { + // Print all nominal types as paths (unlike `pretty_print_type`). + ty::FnDef(def_id, substs) | + ty::Opaque(def_id, substs) | + ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) | + ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | + ty::Closure(def_id, ty::ClosureSubsts { substs }) | + ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { + self.print_def_path(def_id, substs) + } + _ => self.pretty_print_type(ty), + } + } + + fn print_dyn_existential( + mut self, + predicates: &'tcx ty::List>, + ) -> Result { + let mut first = false; + for p in predicates { + if !first { + write!(self, "+")?; + } + first = false; + self = p.print(self)?; + } + Ok(self) + } + + fn path_crate( + mut self, + cnum: CrateNum, + ) -> Result { + self.write_str(&self.tcx.original_crate_name(cnum).as_str())?; + Ok(self) + } + fn path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + // Similar to `pretty_path_qualified`, but for the other + // types that are printed as paths (see `print_type` above). + match self_ty.sty { + ty::FnDef(..) | + ty::Opaque(..) | + ty::Projection(_) | + ty::UnnormalizedProjection(_) | + ty::Closure(..) | + ty::Generator(..) + if trait_ref.is_none() => + { + self.print_type(self_ty) + } + + _ => self.pretty_path_qualified(self_ty, trait_ref) + } + } + + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self.pretty_path_append_impl( + |mut cx| { + cx = print_prefix(cx)?; + + if cx.keep_within_component { + // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. + cx.write_str("::")?; + } else { + cx.path.finalize_pending_component(); + } + + Ok(cx) + }, + self_ty, + trait_ref, + ) + } + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + self = print_prefix(self)?; + + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::StructCtor => return Ok(self), + _ => {} + } + + if self.keep_within_component { + // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. + self.write_str("::")?; + } else { + self.path.finalize_pending_component(); + } + + self.write_str(&disambiguated_data.data.as_interned_str().as_str())?; + Ok(self) + } + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + args: &[Kind<'tcx>], + ) -> Result { + self = print_prefix(self)?; + + let args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => false, + _ => true, + } + }); + + if args.clone().next().is_some() { + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + Ok(self) + } + } +} + +impl PrettyPrinter<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { + fn region_should_not_be_omitted( + &self, + _region: ty::Region<'_>, + ) -> bool { + false + } + fn comma_sep( + mut self, + mut elems: impl Iterator, + ) -> Result + where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error> + { + if let Some(first) = elems.next() { + self = first.print(self)?; + for elem in elems { + self.write_str(",")?; + self = elem.print(self)?; + } + } + Ok(self) + } + + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, + ) -> Result { + write!(self, "<")?; + + let kept_within_component = + mem::replace(&mut self.keep_within_component, true); + self = f(self)?; + self.keep_within_component = kept_within_component; + + write!(self, ">")?; + + Ok(self) + } +} + +impl fmt::Write for SymbolPrinter<'_, '_> { + fn write_str(&mut self, s: &str) -> fmt::Result { + // Name sanitation. LLVM will happily accept identifiers with weird names, but + // gas doesn't! + // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ + // NVPTX assembly has more strict naming rules than gas, so additionally, dots + // are replaced with '$' there. for c in s.chars() { + if self.path.temp_buf.is_empty() { + match c { + 'a'..='z' | 'A'..='Z' | '_' => {} + _ => { + // Underscore-qualify anything that didn't start as an ident. + self.path.temp_buf.push('_'); + } + } + } match c { // Escape these with $ sequences - '@' => self.temp_buf.push_str("$SP$"), - '*' => self.temp_buf.push_str("$BP$"), - '&' => self.temp_buf.push_str("$RF$"), - '<' => self.temp_buf.push_str("$LT$"), - '>' => self.temp_buf.push_str("$GT$"), - '(' => self.temp_buf.push_str("$LP$"), - ')' => self.temp_buf.push_str("$RP$"), - ',' => self.temp_buf.push_str("$C$"), - - '-' | ':' => if self.strict_naming { + '@' => self.path.temp_buf.push_str("$SP$"), + '*' => self.path.temp_buf.push_str("$BP$"), + '&' => self.path.temp_buf.push_str("$RF$"), + '<' => self.path.temp_buf.push_str("$LT$"), + '>' => self.path.temp_buf.push_str("$GT$"), + '(' => self.path.temp_buf.push_str("$LP$"), + ')' => self.path.temp_buf.push_str("$RP$"), + ',' => self.path.temp_buf.push_str("$C$"), + + '-' | ':' | '.' if self.tcx.has_strict_asm_symbol_naming() => { // NVPTX doesn't support these characters in symbol names. - self.temp_buf.push('$') - } - else { - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - self.temp_buf.push('.') - }, - - '.' => if self.strict_naming { - self.temp_buf.push('$') + self.path.temp_buf.push('$') } - else { - self.temp_buf.push('.') - }, + + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + '-' | ':' => self.path.temp_buf.push('.'), // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c), + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c), _ => { - self.temp_buf.push('$'); + self.path.temp_buf.push('$'); for c in c.escape_unicode().skip(1) { match c { '{' => {} - '}' => self.temp_buf.push('$'), - c => self.temp_buf.push(c), + '}' => self.path.temp_buf.push('$'), + c => self.path.temp_buf.push(c), } } } } } - let need_underscore = { - // Underscore-qualify anything that didn't start as an ident. - !self.temp_buf.is_empty() - && self.temp_buf.as_bytes()[0] != '_' as u8 - && !(self.temp_buf.as_bytes()[0] as char).is_xid_start() - }; - - let _ = write!( - self.result, - "{}", - self.temp_buf.len() + (need_underscore as usize) - ); - - if need_underscore { - self.result.push('_'); - } - - self.result.push_str(&self.temp_buf); - } -} - -impl ItemPathBuffer for SymbolPathBuffer { - fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &RootMode = &RootMode::Absolute; - ABSOLUTE - } - - fn push(&mut self, text: &str) { - self.sanitize_and_append(text); + Ok(()) } } diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index c495268154664..6a2b6f1321b88 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -1,7 +1,7 @@ //! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and +//! either a `rustc_symbol_name` or `rustc_def_path` attribute and //! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates +//! def-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. use rustc::hir; @@ -10,7 +10,7 @@ use rustc::ty::TyCtxt; use rustc_mir::monomorphize::Instance; const SYMBOL_NAME: &'static str = "rustc_symbol_name"; -const ITEM_PATH: &'static str = "rustc_item_path"; +const DEF_PATH: &'static str = "rustc_def_path"; pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // if the `rustc_attrs` feature is not enabled, then the @@ -41,9 +41,9 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { let instance = Instance::mono(tcx, def_id); let name = self.tcx.symbol_name(instance); tcx.sess.span_err(attr.span, &format!("symbol-name({})", name)); - } else if attr.check_name(ITEM_PATH) { - let path = tcx.item_path_str(def_id); - tcx.sess.span_err(attr.span, &format!("item-path({})", path)); + } else if attr.check_name(DEF_PATH) { + let path = tcx.def_path_str(def_id); + tcx.sess.span_err(attr.span, &format!("def-path({})", path)); } // (*) The formatting of `tag({})` is chosen so that tests can elect diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 3182b2ce30c6d..dde88a212408d 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -471,7 +471,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { } fn node_path(&self, id: ast::NodeId) -> Option { - Some(self.tcx.node_path_str(id)) + Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id))) } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7c7698ddd3d73..6b4b437930d26 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -2,7 +2,6 @@ #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 1f69d617c83b7..9fe9a60b9aaa9 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -206,7 +206,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.sess.span_err( target_span, &format!("no path from `{}` to `{}`", - tcx.item_path_str(source_def_id), + tcx.def_path_str(source_def_id), target_pass)); } else { tcx.sess.span_err( diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 2794b6c556ff2..633e61a0034ab 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -463,7 +463,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { if let Some(def_id) = dep_node.extract_def_id(self.tcx) { format!("{:?}({})", dep_node.kind, - self.tcx.item_path_str(def_id)) + self.tcx.def_path_str(def_id)) } else { format!("{:?}({:?})", dep_node.kind, dep_node.hash) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d61ccd5605b60..0c710fd283be8 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -67,7 +67,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { .set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error); hygiene::set_default_edition(sess.edition()); - sess.profiler(|p| p.start_activity(ProfileCategory::Parsing)); + sess.profiler(|p| p.start_activity(ProfileCategory::Parsing, "parsing")); let krate = time(sess, "parsing", || match *input { Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess), Input::Str { @@ -75,7 +75,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { ref name, } => parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess), })?; - sess.profiler(|p| p.end_activity(ProfileCategory::Parsing)); + sess.profiler(|p| p.end_activity(ProfileCategory::Parsing, "parsing")); sess.diagnostic().set_continue_after_error(true); @@ -243,6 +243,7 @@ pub fn register_plugins<'a>( krate, &sess.parse_sess, sess.edition(), + &sess.opts.debugging_opts.allow_features, ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); @@ -374,7 +375,7 @@ fn configure_and_expand_inner<'a>( syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts); // Expand all macros - sess.profiler(|p| p.start_activity(ProfileCategory::Expansion)); + sess.profiler(|p| p.start_activity(ProfileCategory::Expansion, "macro expansion")); krate = time(sess, "expansion", || { // Windows dlls do not have rpaths, so they don't know how to find their // dependencies. It's up to us to tell the system where to find all the @@ -449,7 +450,7 @@ fn configure_and_expand_inner<'a>( } krate }); - sess.profiler(|p| p.end_activity(ProfileCategory::Expansion)); + sess.profiler(|p| p.end_activity(ProfileCategory::Expansion, "macro expansion")); time(sess, "maybe building test harness", || { syntax::test::modify_for_testing( @@ -1018,9 +1019,9 @@ pub fn start_codegen<'tcx>( ::rustc::middle::dependency_format::calculate(tcx) }); - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate")); let codegen = time(tcx.sess, "codegen", move || codegen_backend.codegen_crate(tcx, rx)); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate")); if log_enabled!(::log::Level::Info) { println!("Post-codegen"); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 86b8b276eafe5..7d61547527f76 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { let msg = format!("unused {}`{}`{} that must be used", - descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path); + descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index fe07cc0698a0a..8613464732457 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -3,6 +3,7 @@ use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource}; use crate::borrow_check::prefixes::IsPrefixOf; use crate::borrow_check::WriteKind; use rustc::hir; +use rustc::hir::def::Namespace; use rustc::hir::def_id::DefId; use rustc::middle::region::ScopeTree; use rustc::mir::{ @@ -12,7 +13,7 @@ use rustc::mir::{ TerminatorKind, VarBindingForm, }; use rustc::ty::{self, DefIdTree}; -use rustc::util::ppaux::RegionHighlightMode; +use rustc::ty::print::Print; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; @@ -831,7 +832,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { - let region_name = annotation.emit(&mut err); + let region_name = annotation.emit(self, &mut err); err.span_label( borrow_span, @@ -1799,7 +1800,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // (https://github.com/rust-lang/rfcs/pull/1546) bug!( "End-user description not implemented for field access on `{:?}`", - ty.sty + ty ); } } @@ -1875,7 +1876,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn annotate_argument_and_return_for_borrow( &self, borrow: &BorrowData<'tcx>, - ) -> Option> { + ) -> Option> { // Define a fallback for when we can't match a closure. let fallback = || { let is_closure = self.infcx.tcx.is_closure(self.mir_def_id); @@ -2099,7 +2100,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { &self, did: DefId, sig: ty::PolyFnSig<'tcx>, - ) -> Option> { + ) -> Option> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure(did); let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(did)?; @@ -2245,7 +2246,11 @@ enum AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { /// Annotate the provided diagnostic with information about borrow from the fn signature that /// helps explain. - fn emit(&self, diag: &mut DiagnosticBuilder<'_>) -> String { + fn emit( + &self, + cx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + diag: &mut DiagnosticBuilder<'_>, + ) -> String { match self { AnnotatedBorrowFnSignature::Closure { argument_ty, @@ -2253,10 +2258,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } => { diag.span_label( *argument_span, - format!("has type `{}`", self.get_name_for_ty(argument_ty, 0)), + format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)), ); - self.get_region_name_for_ty(argument_ty, 0) + cx.get_region_name_for_ty(argument_ty, 0) } AnnotatedBorrowFnSignature::AnonymousFunction { argument_ty, @@ -2264,10 +2269,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { return_ty, return_span, } => { - let argument_ty_name = self.get_name_for_ty(argument_ty, 0); + let argument_ty_name = cx.get_name_for_ty(argument_ty, 0); diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name)); - let return_ty_name = self.get_name_for_ty(return_ty, 0); + let return_ty_name = cx.get_name_for_ty(return_ty, 0); let types_equal = return_ty_name == argument_ty_name; diag.span_label( *return_span, @@ -2286,7 +2291,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { lifetime-syntax.html#lifetime-elision>", ); - self.get_region_name_for_ty(return_ty, 0) + cx.get_region_name_for_ty(return_ty, 0) } AnnotatedBorrowFnSignature::NamedFunction { arguments, @@ -2294,7 +2299,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { return_span, } => { // Region of return type and arguments checked to be the same earlier. - let region_name = self.get_region_name_for_ty(return_ty, 0); + let region_name = cx.get_region_name_for_ty(return_ty, 0); for (_, argument_span) in arguments { diag.span_label(*argument_span, format!("has lifetime `{}`", region_name)); } @@ -2314,10 +2319,15 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } } } +} +impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime /// name where required. fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); + // We need to add synthesized lifetimes where appropriate. We do // this by hooking into the pretty printer and telling it to label the // lifetimes without names with the value `'0`. @@ -2327,28 +2337,37 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }), _, _, - ) => RegionHighlightMode::highlighting_bound_region(*br, counter, || ty.to_string()), - _ => ty.to_string(), + ) => printer.region_highlight_mode.highlighting_bound_region(*br, counter), + _ => {} } + + let _ = ty.print(printer); + s } /// Returns the name of the provided `Ty` (that must be a reference)'s region with a /// synthesized lifetime name where required. fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { - match ty.sty { - ty::TyKind::Ref(region, _, _) => match region { - ty::RegionKind::ReLateBound(_, br) - | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { - RegionHighlightMode::highlighting_bound_region( - *br, - counter, - || region.to_string(), - ) + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); + + let region = match ty.sty { + ty::TyKind::Ref(region, _, _) => { + match region { + ty::RegionKind::ReLateBound(_, br) + | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { + printer.region_highlight_mode.highlighting_bound_region(*br, counter) + } + _ => {} } - _ => region.to_string(), - }, + + region + } _ => bug!("ty for annotation of borrow region is not a reference"), - } + }; + + let _ = region.print(printer); + s } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0bdf44c2ae049..c4e371d5afedb 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -68,7 +68,7 @@ pub fn provide(providers: &mut Providers<'_>) { fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> { let input_mir = tcx.mir_validated(def_id); - debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id)); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id)); let mut return_early; diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 17f8c23f4fddc..dfa5af444d37e 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -93,7 +93,7 @@ impl BorrowExplanation { // simplify output by reporting just the ADT name. ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => ( "`Drop` code", - format!("type `{}`", tcx.item_path_str(adt.did)), + format!("type `{}`", tcx.def_path_str(adt.did)), ), // Otherwise, just report the whole type (and use diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index fdede054e15f3..362214d325712 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -8,7 +8,7 @@ use rustc::infer::InferCtxt; use rustc::mir::Mir; use rustc::ty::subst::{SubstsRef, UnpackedKind}; use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt}; -use rustc::util::ppaux::RegionHighlightMode; +use rustc::ty::print::RegionHighlightMode; use rustc_errors::DiagnosticBuilder; use syntax::ast::Name; use syntax::symbol::keywords; @@ -396,9 +396,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { argument_ty: Ty<'tcx>, counter: &mut usize, ) -> Option { - let type_name = RegionHighlightMode::highlighting_region_vid(needle_fr, *counter, || { - infcx.extract_type_name(&argument_ty) - }); + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(needle_fr, *counter); + let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)); debug!( "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", @@ -680,9 +680,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { return None; } - let type_name = RegionHighlightMode::highlighting_region_vid( - fr, *counter, || infcx.extract_type_name(&return_ty), - ); + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(fr, *counter); + let type_name = infcx.extract_type_name(&return_ty, Some(highlight)); let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir"); diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index d60a0941b5979..77978d7d38ff7 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); let max = truncate(u128::max_value(), size); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); let max = truncate(u128::max_value(), size); (Some((0, max, size)), 0) diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 4189e3e7ddbb6..4aa463b37ab77 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -82,7 +82,6 @@ use crate::hair::LintLevel; use rustc::middle::region; use rustc::ty::Ty; use rustc::hir; -use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::*; use syntax_pos::{Span}; use rustc_data_structures::fx::FxHashMap; @@ -309,16 +308,25 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_scope = self.source_scope; let tcx = self.hir.tcx(); if let LintLevel::Explicit(current_hir_id) = lint_level { - let same_lint_scopes = tcx.dep_graph.with_ignore(|| { - let sets = tcx.lint_levels(LOCAL_CRATE); - let parent_hir_id = self.source_scope_local_data[source_scope].lint_root; - sets.lint_level_set(parent_hir_id) == sets.lint_level_set(current_hir_id) - }); - - if !same_lint_scopes { - self.source_scope = - self.new_source_scope(region_scope.1.span, lint_level, - None); + // Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound + // to avoid adding Hir dependences on our parents. + // We estimate the true lint roots here to avoid creating a lot of source scopes. + + let parent_root = tcx.maybe_lint_level_root_bounded( + self.source_scope_local_data[source_scope].lint_root, + self.hir.root_lint_level, + ); + let current_root = tcx.maybe_lint_level_root_bounded( + current_hir_id, + self.hir.root_lint_level + ); + + if parent_root != current_root { + self.source_scope = self.new_source_scope( + region_scope.1.span, + LintLevel::Explicit(current_root), + None + ); } } self.push_scope(region_scope); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 365cb508b0925..71d9398c686b7 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( fn mplace_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, mplace: MPlaceTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { +) -> ty::Const<'tcx> { let MemPlace { ptr, align, meta } = *mplace; // extract alloc-offset pair assert!(meta.is_none()); - let ptr = ptr.to_ptr()?; - let alloc = ecx.memory.get(ptr.alloc_id)?; + let ptr = ptr.to_ptr().unwrap(); + let alloc = ecx.memory.get(ptr.alloc_id).unwrap(); assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes()); let mut alloc = alloc.clone(); @@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>( // interned this? I thought that is the entire point of that `FinishStatic` stuff? let alloc = ecx.tcx.intern_const_alloc(alloc); let val = ConstValue::ByRef(ptr, alloc); - Ok(ty::Const { val, ty: mplace.layout.ty }) + ty::Const { val, ty: mplace.layout.ty } } fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { - // We do not normalize just any data. Only scalar layout and slices. +) -> ty::Const<'tcx> { + // We do not normalize just any data. Only non-union scalars and slices. let normalize = match op.layout.abi { - layout::Abi::Scalar(..) => true, + layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()), layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(), _ => false, }; @@ -100,11 +100,11 @@ fn op_to_const<'tcx>( let val = match normalized_op { Ok(mplace) => return mplace_to_const(ecx, mplace), Err(Immediate::Scalar(x)) => - ConstValue::Scalar(x.not_undef()?), + ConstValue::Scalar(x.not_undef().unwrap()), Err(Immediate::ScalarPair(a, b)) => - ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?), + ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()), }; - Ok(ty::Const { val, ty: op.layout.ty }) + ty::Const { val, ty: op.layout.ty } } fn eval_body_and_ecx<'a, 'mir, 'tcx>( @@ -142,7 +142,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack); - let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id())); + let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id())); let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p)); trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom); assert!(mir.arg_count == 0); @@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>( let field = ecx.operand_field(down, field.index() as u64).unwrap(); // and finally move back to the const world, always normalizing because // this is not called for statics. - op_to_const(&ecx, field).unwrap() + op_to_const(&ecx, field) } // this function uses `unwrap` copiously, because an already validated constant must have valid @@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>( // Now that we validated, turn this into a proper constant. let def_id = cid.instance.def.def_id(); if tcx.is_static(def_id).is_some() || cid.promoted.is_some() { - mplace_to_const(&ecx, mplace) + Ok(mplace_to_const(&ecx, mplace)) } else { - op_to_const(&ecx, mplace.into()) + Ok(op_to_const(&ecx, mplace.into())) } })(); @@ -602,14 +602,15 @@ pub fn const_eval_raw_provider<'a, 'tcx>( other => return other, } } - // the first trace is for replicating an ice - // There's no tracking issue, but the next two lines concatenated link to the discussion on - // zulip. It's not really possible to test this, because it doesn't show up in diagnostics - // or MIR. - // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ - // subject/anon_const_instance_printing/near/135980032 - trace!("const eval: {}", key.value.instance); - trace!("const eval: {:?}", key); + if cfg!(debug_assertions) { + // Make sure we format the instance even if we do not print it. + // This serves as a regression test against an ICE on printing. + // The next two lines concatenated contain some discussion: + // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ + // subject/anon_const_instance_printing/near/135980032 + let instance = key.value.instance.to_string(); + trace!("const eval: {:?} ({})", key, instance); + } let cid = key.value; let def_id = cid.instance.def.def_id(); diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index f58e61915e8c9..17fab6c5ddcff 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -103,7 +103,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }, pattern, initializer: local.init.to_ref(), - lint_level: cx.lint_level_of(local.hir_id), + lint_level: LintLevel::Explicit(local.hir_id), }, opt_destruction_scope: opt_dxn_ext, span: stmt_span, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index ad0a22cc7827c..c8c6d73d4536a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -44,7 +44,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::Scope { region_scope: expr_scope, value: expr.to_ref(), - lint_level: cx.lint_level_of(self.hir_id), + lint_level: LintLevel::Explicit(self.hir_id), }, }; @@ -955,7 +955,8 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_provided_types = cx.tables.user_provided_types(); let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty); debug!("convert_path_expr: user_provided_type={:?}", user_provided_type); - match cx.tables().node_type(expr.hir_id).sty { + let ty = cx.tables().node_type(expr.hir_id); + match ty.sty { // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. ty::Adt(adt_def, substs) => { @@ -968,7 +969,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, base: None, } } - ref sty => bug!("unexpected sty: {:?}", sty), + _ => bug!("unexpected ty: {:?}", ty), } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 8b16eeeea23c0..c0f3989b4ba97 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -6,7 +6,7 @@ use crate::hair::*; use crate::hair::util::UserAnnotatedTyHelpers; use rustc_data_structures::indexed_vec::Idx; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::DefId; use rustc::hir::Node; use rustc::middle::region; use rustc::infer::InferCtxt; @@ -76,11 +76,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { // Constants always need overflow checks. check_overflow |= constness == hir::Constness::Const; - let lint_level = lint_level_for_hir_id(tcx, src_id); Cx { tcx, infcx, - root_lint_level: lint_level, + root_lint_level: src_id, param_env: tcx.param_env(src_def_id), identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id), region_scope_tree: tcx.region_scope_tree(src_def_id), @@ -197,18 +196,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { ty.needs_drop(self.tcx.global_tcx(), param_env) } - fn lint_level_of(&self, hir_id: hir::HirId) -> LintLevel { - let has_lint_level = self.tcx.dep_graph.with_ignore(|| { - self.tcx.lint_levels(LOCAL_CRATE).lint_level_set(hir_id).is_some() - }); - - if has_lint_level { - LintLevel::Explicit(hir_id) - } else { - LintLevel::Inherited - } - } - pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx } @@ -236,30 +223,6 @@ impl UserAnnotatedTyHelpers<'gcx, 'tcx> for Cx<'_, 'gcx, 'tcx> { } } -fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: hir::HirId) -> hir::HirId { - // Right now we insert a `with_ignore` node in the dep graph here to - // ignore the fact that `lint_levels` below depends on the entire crate. - // For now this'll prevent false positives of recompiling too much when - // anything changes. - // - // Once red/green incremental compilation lands we should be able to - // remove this because while the crate changes often the lint level map - // will change rarely. - tcx.dep_graph.with_ignore(|| { - let sets = tcx.lint_levels(LOCAL_CRATE); - loop { - if sets.lint_level_set(id).is_some() { - return id - } - let next = tcx.hir().get_parent_node_by_hir_id(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; - } - }) -} - mod block; mod expr; mod to_ref; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 586a3fdb907ee..44bcb9de0e157 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const}; use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size}; use rustc::mir::Field; -use rustc::mir::interpret::{ConstValue, Scalar}; +use rustc::mir::interpret::{ConstValue, Scalar, truncate}; use rustc::util::common::ErrorReported; use syntax::attr::{SignedInt, UnsignedInt}; @@ -678,16 +678,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ] } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; let min = 1u128 << (bits - 1); - let max = (1u128 << (bits - 1)) - 1; + let max = min - 1; vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. - let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128; - let max = !0u128 >> (128 - bits); + let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); + let max = truncate(u128::max_value(), size); vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)] } _ => { diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 41babc1ad12ef..49967df08891b 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -319,7 +319,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa if edef.is_enum() && edef.variants.iter().any(|variant| { variant.ident == ident && variant.ctor_kind == CtorKind::Const }) { - let ty_path = cx.tcx.item_path_str(edef.did); + let ty_path = cx.tcx.def_path_str(edef.did); let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, "pattern binding `{}` is named the same as one \ of the variants of the type `{}`", diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 67d40197290f1..ad7b45d89453a 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -13,7 +13,7 @@ use crate::hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; -use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; +use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{SubstsRef, Kind}; use rustc::ty::layout::VariantIdx; @@ -529,11 +529,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) }; } - ref sty => + _ => span_bug!( pat.span, "unexpanded type for vector pattern: {:?}", - sty), + ty), } } @@ -554,7 +554,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE (#50577) return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) }; } - ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty), + _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty), } } @@ -608,7 +608,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", - ty.sty), + ty), }; let variant_def = adt_def.variant_of_def(def); @@ -735,7 +735,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ) -> PatternKind<'tcx> { let mut kind = match def { Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { - let enum_id = self.tcx.parent_def_id(variant_id).unwrap(); + let enum_id = self.tcx.parent(variant_id).unwrap(); let adt_def = self.tcx.adt_def(enum_id); if adt_def.is_enum() { let substs = match ty.sty { @@ -744,7 +744,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE (#50585) return PatternKind::Wild; } - _ => bug!("inappropriate type for def: {:?}", ty.sty), + _ => bug!("inappropriate type for def: {:?}", ty), }; PatternKind::Variant { adt_def, @@ -969,8 +969,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => { let msg = format!("to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - self.tcx.item_path_str(adt_def.did), - self.tcx.item_path_str(adt_def.did)); + self.tcx.def_path_str(adt_def.did), + self.tcx.def_path_str(adt_def.did)); self.tcx.sess.span_err(span, &msg); PatternKind::Wild } diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index 4618cd42686fa..c9dae6990795b 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -16,7 +16,8 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { let user_provided_types = self.tables().user_provided_types(); let mut user_ty = *user_provided_types.get(hir_id)?; debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty); - match &self.tables().node_type(hir_id).sty { + let ty = self.tables().node_type(hir_id); + match ty.sty { ty::Adt(adt_def, ..) => { if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value { *did = adt_def.did; @@ -24,8 +25,11 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { Some(user_ty) } ty::FnDef(..) => Some(user_ty), - sty => - bug!("sty: {:?} should not have user provided type {:?} recorded ", sty, user_ty), + _ => bug!( + "ty: {:?} should not have user provided type {:?} recorded ", + ty, + user_ty + ), } } } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 73c73cc23dcf0..7543dd678d032 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -90,7 +90,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag(); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } - ref other => bug!("reify fn pointer on {:?}", other), + _ => bug!("reify fn pointer on {:?}", src.layout.ty), } } @@ -101,7 +101,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // No change to value self.write_immediate(*src, dest)?; } - ref other => bug!("fn to unsafe fn cast on {:?}", other), + _ => bug!("fn to unsafe fn cast on {:?}", dest.layout.ty), } } @@ -120,7 +120,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into()); self.write_immediate(val, dest)?; } - ref other => bug!("closure fn pointer on {:?}", other), + _ => bug!("closure fn pointer on {:?}", src.layout.ty), } } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 8a32c3b636c71..e81d0a56b2b05 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(NoMirFor(self.tcx.item_path_str(def_id))) + err!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -450,7 +450,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc return_place: Option>, return_to_block: StackPopCleanup, ) -> EvalResult<'tcx> { - if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc... + if self.stack.len() > 0 { info!("PAUSING({}) {}", self.cur_frame(), self.frame().instance); } ::log_settings::settings().indentation += 1; @@ -525,9 +525,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc self.frame_mut().locals = locals; } - if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE - info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); - } + info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { err!(StackFrameLimitReached) @@ -537,9 +535,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> { - if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE - info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance); - } + info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance); ::log_settings::settings().indentation -= 1; let frame = self.stack.pop().expect( "tried to pop a stack frame, but there were none", @@ -591,7 +587,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc StackPopCleanup::None { .. } => {} } - if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc... + if self.stack.len() > 0 { info!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance); } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 88b936afaa4c1..6ea200d4e4fad 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -700,24 +700,29 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // relocations overlapping the edges; those would not be handled correctly). let relocations = { let relocations = self.get(src.alloc_id)?.relocations(self, src, size); - let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); - for i in 0..length { - new_relocations.extend( - relocations - .iter() - .map(|&(offset, reloc)| { - // compute offset for current repetition - let dest_offset = dest.offset + (i * size); - ( - // shift offsets from source allocation to destination allocation - offset + dest_offset - src.offset, - reloc, - ) - }) - ); - } + if relocations.is_empty() { + // nothing to copy, ignore even the `length` loop + Vec::new() + } else { + let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); + for i in 0..length { + new_relocations.extend( + relocations + .iter() + .map(|&(offset, reloc)| { + // compute offset for current repetition + let dest_offset = dest.offset + (i * size); + ( + // shift offsets from source allocation to destination allocation + offset + dest_offset - src.offset, + reloc, + ) + }) + ); + } - new_relocations + new_relocations + } }; let tcx = self.tcx.tcx; @@ -784,20 +789,65 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // The bits have to be saved locally before writing to dest in case src and dest overlap. assert_eq!(size.bytes() as usize as u64, size.bytes()); - let undef_mask = self.get(src.alloc_id)?.undef_mask.clone(); - let dest_allocation = self.get_mut(dest.alloc_id)?; + let undef_mask = &self.get(src.alloc_id)?.undef_mask; + + // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`), + // a naive undef mask copying algorithm would repeatedly have to read the undef mask from + // the source and write it to the destination. Even if we optimized the memory accesses, + // we'd be doing all of this `repeat` times. + // Therefor we precompute a compressed version of the undef mask of the source value and + // then write it back `repeat` times without computing any more information from the source. + + // a precomputed cache for ranges of defined/undefined bits + // 0000010010001110 will become + // [5, 1, 2, 1, 3, 3, 1] + // where each element toggles the state + let mut ranges = smallvec::SmallVec::<[u64; 1]>::new(); + let first = undef_mask.get(src.offset); + let mut cur_len = 1; + let mut cur = first; + for i in 1..size.bytes() { + // FIXME: optimize to bitshift the current undef block's bits and read the top bit + if undef_mask.get(src.offset + Size::from_bytes(i)) == cur { + cur_len += 1; + } else { + ranges.push(cur_len); + cur_len = 1; + cur = !cur; + } + } - for i in 0..size.bytes() { - let defined = undef_mask.get(src.offset + Size::from_bytes(i)); + // now fill in all the data + let dest_allocation = self.get_mut(dest.alloc_id)?; + // an optimization where we can just overwrite an entire range of definedness bits if + // they are going to be uniformly `1` or `0`. + if ranges.is_empty() { + dest_allocation.undef_mask.set_range_inbounds( + dest.offset, + dest.offset + size * repeat, + first, + ); + return Ok(()) + } - for j in 0..repeat { - dest_allocation.undef_mask.set( - dest.offset + Size::from_bytes(i + (size.bytes() * j)), - defined + // remember to fill in the trailing bits + ranges.push(cur_len); + + for mut j in 0..repeat { + j *= size.bytes(); + j += dest.offset.bytes(); + let mut cur = first; + for range in &ranges { + let old_j = j; + j += range; + dest_allocation.undef_mask.set_range_inbounds( + Size::from_bytes(old_j), + Size::from_bytes(j), + cur, ); + cur = !cur; } } - Ok(()) } } diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b3b9c742d6c28..944e393d296fc 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -336,7 +336,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let layout = val.layout; let val = val.to_scalar()?; - trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty.sty); + trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty); match layout.ty.sty { ty::Bool => { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 4df274bc9df97..755bbd96b02f9 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -354,7 +354,7 @@ where ty::Ref(_, _, mutbl) => Some(mutbl), ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable), ty::RawPtr(_) => None, - _ => bug!("Unexpected pointer type {}", val.layout.ty.sty), + _ => bug!("Unexpected pointer type {}", val.layout.ty), }; place.mplace.ptr = M::tag_dereference(self, place, mutbl)?; Ok(place) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 0b735b4b39cf5..c45e694ebf832 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(const_fn)] #![feature(decl_macro)] #![feature(exhaustive_patterns)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_attrs)] #![feature(never_type)] diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 1e245faddf04c..307cee5d97217 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -198,6 +198,8 @@ use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; +use std::iter; + #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum MonoItemCollectionMode { Eager, @@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // We include the const length in the type length, as it's better // to be overly conservative. if type_length + const_length > type_length_limit { - // The instance name is already known to be too long for rustc. Use - // `{:.64}` to avoid blasting the user's terminal with thousands of - // lines of type-name. - let instance_name = instance.to_string(); - let msg = format!("reached the type-length limit while instantiating `{:.64}...`", - instance_name); - let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) { - tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg) - } else { - tcx.sess.struct_fatal(&msg) + // The instance name is already known to be too long for rustc. + // Show only the first and last 32 characters to avoid blasting + // the user's terminal with thousands of lines of type-name. + let shrink = |s: String, before: usize, after: usize| { + // An iterator of all byte positions including the end of the string. + let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len())); + + let shrunk = format!( + "{before}...{after}", + before = &s[..positions().nth(before).unwrap_or(s.len())], + after = &s[positions().rev().nth(after).unwrap_or(0)..], + ); + + // Only use the shrunk version if it's really shorter. + // This also avoids the case where before and after slices overlap. + if shrunk.len() < s.len() { + shrunk + } else { + s + } }; - + let msg = format!("reached the type-length limit while instantiating `{}`", + shrink(instance.to_string(), 32, 32)); + let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg); diag.note(&format!( "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate", - type_length_limit * 2)); + type_length)); diag.emit(); tcx.sess.abort_if_errors(); } @@ -836,7 +850,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), + _ => bug!("unexpected unsized tail: {:?}", tail), } }; if type_has_metadata(inner_source) { diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 211f9ad1735c3..68d13bf2dcb24 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -216,9 +216,8 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { // These keys are used by the handwritten auto-tests, so they need to be // predictable and human-readable. // -// Note: A lot of this could looks very similar to what's already in the -// ppaux module. It would be good to refactor things so we only have one -// parameterizable implementation for printing types. +// Note: A lot of this could looks very similar to what's already in `ty::print`. +// FIXME(eddyb) implement a custom `PrettyPrinter` for this. /// Same as `unique_type_name()` but with the result pushed onto the given /// `output` parameter. diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index c0e2186d9f34c..4a2c05b201328 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -104,7 +104,7 @@ use rustc::hir::map::DefPathData; use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder}; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::ty::{self, TyCtxt, InstanceDef}; -use rustc::ty::item_path::characteristic_def_id_of_type; +use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; use rustc::util::common::time; use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet}; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 97d566e586e86..001a61959c2dd 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if !self.span.allows_unstable(&feature.as_str()) { let mut err = self.tcx.sess.struct_span_err(self.span, &format!("`{}` is not yet stable as a const fn", - self.tcx.item_path_str(def_id))); + self.tcx.def_path_str(def_id))); if nightly_options::is_nightly_build() { help!(&mut err, "add `#![feature({})]` to the \ diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index f078316b97ce8..f9f8abbe6c065 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -29,10 +29,10 @@ impl MirPass for SanityCheck { let def_id = src.def_id(); let id = tcx.hir().as_local_hir_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir") { - debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); + debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); return; } else { - debug!("running rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); + debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); } let attributes = tcx.get_attrs(def_id); diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 61b1a5a850d28..69a2adcfce026 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -127,7 +127,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'_>, w: &mut W) -> io::Result<()> { - write!(w, " label=(tcx: TyCtxt<'a, 'gcx, 'tcx>, )?; } - write!(w, ") -> {}", escape(mir.return_ty()))?; + write!(w, ") -> {}", escape(&mir.return_ty()))?; write!(w, r#"
"#)?; for local in mir.vars_and_temps_iter() { diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index d08fb40966c49..cbdd50cf4052a 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -29,7 +29,7 @@ use rustc::mir::visit::{ }; use rustc::mir::Local; use rustc::mir::*; -use rustc::ty::{item_path, TyCtxt}; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; @@ -265,9 +265,9 @@ pub fn dump_mir<'a, 'tcx>( if !dump_enabled(tcx, pass_name, source) { return; } - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result); } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c3fbee3a2a6e5..c7c77d351a75f 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,8 +1,8 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def::CtorKind; use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; -use rustc::ty::item_path; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use std::fmt::Display; @@ -78,9 +78,9 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( return; } - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); dump_matched_mir_node( tcx, @@ -103,9 +103,9 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( None => return false, Some(ref filters) => filters, }; - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); filters.split('|').any(|or_filter| { or_filter.split('&').all(|and_filter| { @@ -115,7 +115,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( } // #41697 -- we use `with_forced_impl_filename_line()` because -// `item_path_str()` would otherwise trigger `type_of`, and this can +// `def_path_str()` would otherwise trigger `type_of`, and this can // run while we are already attempting to evaluate `type_of`. fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( @@ -597,7 +597,8 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()); let is_function = match descr { - Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true, + Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) | + Some(Def::StructCtor(_, CtorKind::Fn)) => true, _ => tcx.is_closure(src.def_id()), }; match (descr, src.promoted) { @@ -612,9 +613,9 @@ fn write_mir_sig( _ => bug!("Unexpected def description {:?}", descr), } - item_path::with_forced_impl_filename_line(|| { + ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere - write!(w, "{}", tcx.item_path_str(src.def_id())) + write!(w, " {}", tcx.def_path_str(src.def_id())) })?; if src.promoted.is_none() && is_function { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 52514a3ca97d6..5065c1de97bee 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -134,7 +134,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V> ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | ty::Generator(def_id, ..) => { - if self.def_id_visitor.visit_def_id(def_id, "type", ty) { + if self.def_id_visitor.visit_def_id(def_id, "type", &ty) { return true; } if self.def_id_visitor.shallow() { @@ -816,7 +816,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> { let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1; if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private", - field.ident, def.variant_descr(), self.tcx.item_path_str(def.did)) + field.ident, def.variant_descr(), self.tcx.def_path_str(def.did)) .span_label(span, format!("field `{}` is private", field.ident)) .emit(); } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index b82aee7c96ad2..3fea515ae401e 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -17,7 +17,7 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::def_id::DefId; use rustc::session::config::Input; use rustc::span_bug; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use std::path::Path; @@ -429,7 +429,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { vis: ast::Visibility, attrs: &'l [Attribute], ) { - let qualname = format!("::{}", self.tcx.node_path_str(id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(id))); if !self.span.filter_generated(ident.span) { let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt); @@ -470,7 +471,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { debug!("process_struct {:?} {:?}", item, item.span); let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let kind = match item.node { ast::ItemKind::Struct(_, _) => DefKind::Struct, @@ -682,7 +684,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { methods: &'l [ast::TraitItem], ) { let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let mut val = name.clone(); if !generics.params.is_empty() { val.push_str(&generic_params_to_string(&generics.params)); @@ -1093,7 +1096,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ast::TraitItemKind::Type(ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(trait_item.id))); if !self.span.filter_generated(trait_item.ident.span) { let span = self.span_from_span(trait_item.ident.span); @@ -1201,7 +1205,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) - .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) + .and_then(|id| self.save_ctxt.tcx.parent(id)) .map(id_from_def_id); match use_tree.kind { @@ -1300,7 +1304,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc // only get called for the root module of a crate. assert_eq!(id, ast::CRATE_NODE_ID); - let qualname = format!("::{}", self.tcx.node_path_str(id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(id))); let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(span); @@ -1350,7 +1355,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id) - .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) + .and_then(|id| self.save_ctxt.tcx.parent(id)) .map(id_from_def_id); self.dumper.import( &Access { @@ -1389,7 +1394,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.nest_scope(item.id, |v| visit::walk_mod(v, m)); } Ty(ref ty, ref ty_params) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let value = ty_to_string(&ty); if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); @@ -1418,7 +1424,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.process_generic_params(ty_params, &qualname, item.id); } Existential(ref _bounds, ref ty_params) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); // FIXME do something with _bounds let value = String::new(); if !self.span.filter_generated(item.ident.span) { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d80f3e5ce759c..7ad5b7ce8c73e 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -20,7 +20,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::privacy::AccessLevels; use rustc::middle::cstore::ExternCrate; use rustc::session::config::{CrateType, Input, OutputType}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc::{bug, span_bug}; use rustc_typeck::hir_ty_to_ty; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; @@ -134,7 +134,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { filter!(self.span_utils, item.ident.span); @@ -184,7 +185,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_item_data(&self, item: &ast::Item) -> Option { match item.node { ast::ItemKind::Fn(ref decl, .., ref generics, _) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Function, @@ -202,7 +204,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Static(ref typ, ..) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); @@ -225,7 +228,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Const(ref typ, _) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); @@ -247,7 +251,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Mod(ref m) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(m.inner); @@ -274,7 +279,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ItemKind::Enum(ref def, _) => { let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); let variants_str = def.variants .iter() @@ -358,7 +364,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option { if let Some(ident) = field.ident { let name = ident.to_string(); - let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); + let qualname = format!("::{}::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(scope)), + ident); filter!(self.span_utils, ident.span); let def_id = self.tcx.hir().local_def_id(field.id); let typ = self.tcx.type_of(def_id).to_string(); @@ -411,7 +419,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if let Some(def_id) = trait_id { // A method in a trait impl. qualname.push_str(" as "); - qualname.push_str(&self.tcx.item_path_str(def_id)); + qualname.push_str(&self.tcx.def_path_str(def_id)); self.tcx .associated_items(def_id) .find(|item| item.ident.name == ident.name) @@ -451,7 +459,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ( - format!("::{}", self.tcx.item_path_str(def_id)), + format!("::{}", self.tcx.def_path_str(def_id)), Some(def_id), None, docs, @@ -763,7 +771,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // This is a reference to a tuple struct where the def_id points // to an invisible constructor function. That is not a very useful // def, so adjust to point to the tuple struct itself. - let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); + let parent_def_id = self.tcx.parent(def_id).unwrap(); Some(Ref { kind: RefKind::Type, span, diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f47291458492e --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -0,0 +1,23 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f4f98d33571f0 --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..7faed3adc79cc --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..58a814a759eb8 --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 2824d9cb6c3bb..fdb1db645c3c4 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -335,6 +335,10 @@ supported_targets! { ("mips-unknown-linux-gnu", mips_unknown_linux_gnu), ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64), ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64), + ("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu), + ("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu), + ("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64), + ("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64), ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index 631966c09a498..956767a22a0e1 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -59,7 +59,7 @@ pub fn opts() -> TargetOptions { singlethread: true, emit_debug_gdb_scripts: false, - linker: Some("lld-link".to_string()), + linker: Some("rust-lld".to_string()), lld_flavor: LldFlavor::Link, pre_link_args, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 89ec92a652160..9ca75566b4280 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -12,7 +12,7 @@ use crate::middle::resolve_lifetime as rl; use crate::namespace::Namespace; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; -use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; +use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef}; use rustc::ty::wf::object_region_bounds; @@ -922,7 +922,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { "the value of the associated type `{}` (from the trait `{}`) \ is already specified", binding.item_name, - tcx.item_path_str(assoc_ty.container.id())) + tcx.def_path_str(assoc_ty.container.id())) .span_label(binding.span, "re-bound here") .span_label(*prev_span, format!("`{}` bound here first", binding.item_name)) .emit(); @@ -959,7 +959,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`). fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF); + if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF { + bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref); + } ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref) } @@ -1069,7 +1071,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { format!( "`{}` (from the trait `{}`)", assoc_item.ident, - tcx.item_path_str(trait_def_id), + tcx.def_path_str(trait_def_id), ) }).collect::>().join(", "); let mut err = struct_span_err!( @@ -1450,14 +1452,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { -> Ty<'tcx> { let tcx = self.tcx(); - let trait_def_id = tcx.parent_def_id(item_def_id).unwrap(); + let trait_def_id = tcx.parent(item_def_id).unwrap(); self.prohibit_generics(slice::from_ref(item_segment)); let self_ty = if let Some(ty) = opt_self_ty { ty } else { - let path_str = tcx.item_path_str(trait_def_id); + let path_str = tcx.def_path_str(trait_def_id); self.report_ambiguous_associated_type(span, "Type", &path_str, @@ -1619,7 +1621,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else if last >= 1 && segments[last - 1].args.is_some() { // Everything but the penultimate segment should have no // parameters at all. - let enum_def_id = tcx.parent_def_id(def_id).unwrap(); + let enum_def_id = tcx.parent(def_id).unwrap(); (enum_def_id, last - 1) } else { // FIXME: lint here recommending `Enum::<...>::Variant` form diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 1a3ade7f8baf6..c6b66393dd2f1 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // See the examples in `run-pass/match-defbm*.rs`. let mut pat_adjustments = vec![]; while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty { - debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty); + debug!("inspecting {:?}", exp_ty); debug!("current discriminant is Ref, inserting implicit deref"); // Preserve the reference type. We'll need it later during HAIR lowering. @@ -894,7 +894,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); subpats.len() < variant.fields.len() && ddpos.is_some() { let substs = match pat_ty.sty { ty::Adt(_, substs) => substs, - ref ty => bug!("unexpected pattern type {:?}", ty), + _ => bug!("unexpected pattern type {:?}", pat_ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); @@ -1001,13 +1001,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); E0026, "{} `{}` does not have {}", kind_name, - tcx.item_path_str(variant.did), + tcx.def_path_str(variant.did), field_names); if let Some((span, ident)) = inexistent_fields.last() { err.span_label(*span, format!("{} `{}` does not have {} field{}", kind_name, - tcx.item_path_str(variant.did), + tcx.def_path_str(variant.did), t, plural)); if plural == "" { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index f79bf4e999d54..e6e5c46c473d5 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -719,7 +719,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait `{}` has {}", trait_m.ident, potentially_plural_count(impl_number_args, "parameter"), - tcx.item_path_str(trait_m.def_id), + tcx.def_path_str(trait_m.def_id), trait_number_args); if let Some(trait_span) = trait_span { err.span_label(trait_span, format!("trait requires {}", diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 32ca854b27744..3a7308d09172e 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -130,7 +130,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let sole_field = &variant.fields[0]; let sole_field_ty = sole_field.ty(self.tcx, substs); if self.can_coerce(expr_ty, sole_field_ty) { - let variant_path = self.tcx.item_path_str(variant.did); + let variant_path = self.tcx.def_path_str(variant.did); // FIXME #56861: DRYer prelude filtering Some(variant_path.trim_start_matches("std::prelude::v1::").to_string()) } else { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index efae870c3c3a9..1f0ab3abb2836 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1195,7 +1195,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // `report_method_error()`. diag.help(&format!( "call with fully qualified syntax `{}(...)` to keep using the current method", - self.tcx.item_path_str(stable_pick.item.def_id), + self.tcx.def_path_str(stable_pick.item.def_id), )); if nightly_options::is_nightly_build() { @@ -1203,7 +1203,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { diag.help(&format!( "add #![feature({})] to the crate attributes to enable `{}`", feature, - self.tcx.item_path_str(candidate.item.def_id), + self.tcx.def_path_str(candidate.item.def_id), )); } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4bf6471a6293c..b4a1a2d76c262 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -15,7 +15,7 @@ use rustc::hir::print; use rustc::infer::type_variable::TypeVariableOrigin; use rustc::traits::Obligation; use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; -use rustc::ty::item_path::with_crate_prefix; +use rustc::ty::print::with_crate_prefix; use syntax_pos::{Span, FileName}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => String::new(), Some(trait_ref) => { format!(" of the trait `{}`", - self.tcx.item_path_str(trait_ref.def_id)) + self.tcx.def_path_str(trait_ref.def_id)) } }; @@ -135,16 +135,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { item_span, "candidate #{} is defined in the trait `{}`", idx + 1, - self.tcx.item_path_str(trait_did)); + self.tcx.def_path_str(trait_did)); } else { span_note!(err, item_span, "the candidate is defined in the trait `{}`", - self.tcx.item_path_str(trait_did)); + self.tcx.def_path_str(trait_did)); } err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \ instead", - self.tcx.item_path_str(trait_did), + self.tcx.def_path_str(trait_did), item_name, if rcvr_ty.is_region_ptr() && args.is_some() { if rcvr_ty.is_mutable_pointer() { @@ -516,7 +516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; format!( "use {};\n{}", - with_crate_prefix(|| self.tcx.item_path_str(*did)), + with_crate_prefix(|| self.tcx.def_path_str(*did)), additional_newline ) }); @@ -530,14 +530,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &format!( "\ncandidate #{}: `use {};`", i + 1, - with_crate_prefix(|| self.tcx.item_path_str(*trait_did)) + with_crate_prefix(|| self.tcx.def_path_str(*trait_did)) ) ); } else { msg.push_str( &format!( "\n`use {};`", - with_crate_prefix(|| self.tcx.item_path_str(*trait_did)) + with_crate_prefix(|| self.tcx.def_path_str(*trait_did)) ) ); } @@ -638,7 +638,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for (i, trait_info) in candidates.iter().enumerate() { msg.push_str(&format!("\ncandidate #{}: `{}`", i + 1, - self.tcx.item_path_str(trait_info.def_id))); + self.tcx.def_path_str(trait_info.def_id))); } err.note(&msg[..]); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 28c79ce0c74e8..fa4bb02189f20 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1328,7 +1328,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite debug!( "check_item_type(it.hir_id={}, it.name={})", it.hir_id, - tcx.item_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id)) + tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id)) ); let _indenter = indenter(); match it.node { @@ -3534,7 +3534,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { autoderef.unambiguous_final_ty(self); if let Some((did, field_ty)) = private_candidate { - let struct_path = self.tcx().item_path_str(did); + let struct_path = self.tcx().def_path_str(did); let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616, "field `{}` of struct `{}` is private", field, struct_path); @@ -3885,7 +3885,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(adt, substs) => { Some((adt.variant_of_def(def), adt.did, substs)) } - _ => bug!("unexpected type: {:?}", ty.sty) + _ => bug!("unexpected type: {:?}", ty) } } Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | @@ -5226,8 +5226,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node); let sp = ty.span; let ty = AstConv::ast_ty_to_ty(self, ty); - debug!("suggest_missing_return_type: return type sty {:?}", ty.sty); - debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty); + debug!("suggest_missing_return_type: return type {:?}", ty); + debug!("suggest_missing_return_type: expected type {:?}", ty); if ty.sty == expected.sty { err.span_label(sp, format!("expected `{}` because of return type", expected)); @@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(original_span.with_lo(original_span.hi() - BytePos(1))) } + // Rewrite `SelfCtor` to `StructCtor` + pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) { + let tcx = self.tcx; + if let Def::SelfCtor(impl_def_id) = def { + let ty = self.impl_self_ty(span, impl_def_id).ty; + let adt_def = ty.ty_adt_def(); + + match adt_def { + Some(adt_def) if adt_def.has_ctor() => { + let variant = adt_def.non_enum_variant(); + let def = Def::StructCtor(variant.did, variant.ctor_kind); + (def, variant.did, tcx.type_of(variant.did)) + } + _ => { + let mut err = tcx.sess.struct_span_err(span, + "the `Self` constructor can only be used with tuple or unit structs"); + if let Some(adt_def) = adt_def { + match adt_def.adt_kind() { + AdtKind::Enum => { + err.help("did you mean to use one of the enum's variants?"); + }, + AdtKind::Struct | + AdtKind::Union => { + err.span_suggestion( + span, + "use curly brackets", + String::from("Self { /* fields */ }"), + Applicability::HasPlaceholders, + ); + } + } + } + err.emit(); + + (def, impl_def_id, tcx.types.err) + } + } + } else { + let def_id = def.def_id(); + + // The things we are substituting into the type should not contain + // escaping late-bound regions, and nor should the base type scheme. + let ty = tcx.type_of(def_id); + (def, def_id, ty) + } + } + // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; + match def { + Def::Local(nid) | Def::Upvar(nid, ..) => { + let hid = self.tcx.hir().node_to_hir_id(nid); + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, def); + } + _ => {} + } + + let (def, def_id, ty) = self.rewrite_self_ctor(def, span); let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; @@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty = None; } - match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, def); - } - _ => {} - } - // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user // did not provide any types, then we want to substitute inference @@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.generics_of(*def_id).has_self }).unwrap_or(false); - let mut new_def = def; - let (def_id, ty) = match def { - Def::SelfCtor(impl_def_id) => { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - - match adt_def { - Some(adt_def) if adt_def.has_ctor() => { - let variant = adt_def.non_enum_variant(); - new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, tcx.type_of(variant.did)) - } - _ => { - let mut err = tcx.sess.struct_span_err(span, - "the `Self` constructor can only be used with tuple or unit structs"); - if let Some(adt_def) = adt_def { - match adt_def.adt_kind() { - AdtKind::Enum => { - err.help("did you mean to use one of the enum's variants?"); - }, - AdtKind::Struct | - AdtKind::Union => { - err.span_suggestion( - span, - "use curly brackets", - String::from("Self { /* fields */ }"), - Applicability::HasPlaceholders, - ); - } - } - } - err.emit(); - - (impl_def_id, tcx.types.err) - } - } - } - _ => { - let def_id = def.def_id(); - - // The things we are substituting into the type should not contain - // escaping late-bound regions, and nor should the base type scheme. - let ty = tcx.type_of(def_id); - (def_id, ty) - } - }; - let substs = AstConv::create_substs_for_generic_args( tcx, def_id, @@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted); self.write_substs(hir_id, substs); - (ty_substituted, new_def) + (ty_substituted, def) } fn check_rustc_args_require_const(&self, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 3e6e6576b63ba..a76dfdd69ba97 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -93,19 +93,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); // Extract the type of the closure. - let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty { + let ty = self.node_ty(closure_hir_id); + let (closure_def_id, substs) = match ty.sty { ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)), ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)), ty::Error => { // #51714: skip analysis when we have already encountered type errors return; } - ref t => { + _ => { span_bug!( span, "type of closure expr {:?} is not a closure {:?}", closure_hir_id, - t + ty ); } }; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index fde940eb2c111..1f7e05de18bcf 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -68,7 +68,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def debug!("check_item_well_formed(it.hir_id={:?}, it.name={})", item.hir_id, - tcx.item_path_str(def_id)); + tcx.def_path_str(def_id)); match item.node { // Right now we check that every default trait implementation @@ -618,7 +618,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( span: Span, ty: Ty<'tcx>, ) -> Vec> { - trace!("check_existential_types: {:?}, {:?}", ty, ty.sty); + trace!("check_existential_types: {:?}", ty); let mut substituted_predicates = Vec::new(); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.tcx, @@ -976,7 +976,7 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(def_id) = suggested_marker_id { err.help(&format!("consider removing `{}` or using a marker such as `{}`", param_name, - tcx.item_path_str(def_id))); + tcx.def_path_str(def_id))); } err.emit(); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index d001545d1d915..4a3d4f31a2473 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -472,7 +472,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { instantiated_ty.fold_with(&mut BottomUpFolder { tcx: self.tcx().global_tcx(), fldop: |ty| { - trace!("checking type {:?}: {:#?}", ty, ty.sty); + trace!("checking type {:?}", ty); // find a type parameter if let ty::Param(..) = ty.sty { // look it up in the substitution list diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 5d86bc5409532..a2b01e3843ff2 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -198,8 +198,8 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>( if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = tcx.item_path_str(def_a.did); - let target_path = tcx.item_path_str(def_b.did); + let source_path = tcx.def_path_str(def_a.did); + let target_path = tcx.def_path_str(def_b.did); create_err( &format!( @@ -388,8 +388,8 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>, (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = gcx.item_path_str(def_a.did); - let target_path = gcx.item_path_str(def_b.did); + let source_path = gcx.def_path_str(def_a.did); + let target_path = gcx.def_path_str(def_b.did); span_err!(gcx.sess, span, E0377, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 39a2f5d37bd7a..a5452b4db2a20 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -28,7 +28,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { debug!("(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, - tcx.item_path_str(impl_def_id)); + tcx.def_path_str(impl_def_id)); // Skip impls where one of the self type is an error type. // This occurs with e.g., resolve failures (#30589). @@ -204,10 +204,10 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI E0371, "the object type `{}` automatically implements the trait `{}`", trait_ref.self_ty(), - tcx.item_path_str(trait_def_id)) + tcx.def_path_str(trait_def_id)) .span_label(sp, format!("`{}` automatically implements trait `{}`", trait_ref.self_ty(), - tcx.item_path_str(trait_def_id))) + tcx.def_path_str(trait_def_id))) .emit(); } } diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index c875b856f3a4f..7e1c38e051542 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -121,7 +121,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { format!("cross-crate traits with a default impl, like `{}`, \ can only be implemented for a struct/enum type \ defined in the current crate", - self.tcx.item_path_str(trait_def_id)), + self.tcx.def_path_str(trait_def_id)), "can't implement cross-crate trait for type in another crate" )) } @@ -129,7 +129,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { _ => { Some((format!("cross-crate traits with a default impl, like `{}`, can \ only be implemented for a struct/enum type, not `{}`", - self.tcx.item_path_str(trait_def_id), + self.tcx.def_path_str(trait_def_id), self_ty), "can't implement cross-crate trait with a default impl for \ non-struct/enum type")) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ebb617c23c6ca..cbed7d26a9950 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -317,7 +317,7 @@ pub fn provide(providers: &mut Providers<'_>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking, "type-check crate")); // this ensures that later parts of type checking can assume that items // have valid types and not error @@ -368,7 +368,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) check_unused::check_crate(tcx); check_for_entry_fn(tcx); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking, "type-check crate")); if tcx.sess.err_count() == 0 { Ok(()) diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 49d11150689a9..c18f9fd102f10 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn build_constraints_for_item(&mut self, def_id: DefId) { let tcx = self.tcx(); - debug!("build_constraints_for_item({})", tcx.item_path_str(def_id)); + debug!("build_constraints_for_item({})", tcx.def_path_str(def_id)); // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(def_id).count() == 0 { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f2bf7ead5619b..c80fd8fcd812f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,8 +20,9 @@ use rustc::mir::interpret::GlobalId; use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc::ty::subst::{InternalSubsts, SubstsRef}; -use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind}; +use rustc::hir::map::DisambiguatedDefPathData; +use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef}; +use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; use rustc::ty::layout::VariantIdx; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -3971,7 +3972,7 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId { Def::ForeignTy(i) => (i, TypeKind::Foreign), Def::Const(i) => (i, TypeKind::Const), Def::Static(i, _) => (i, TypeKind::Static), - Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"), + Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"), TypeKind::Enum), Def::Macro(i, mac_kind) => match mac_kind { MacroKind::Bang => (i, TypeKind::Macro), @@ -4223,32 +4224,113 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { } } -pub fn get_path_for_type(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path -where F: Fn(DefId) -> Def { - #[derive(Debug)] - struct AbsolutePathBuffer { - names: Vec, +pub fn get_path_for_type( + tcx: TyCtxt<'_, '_, '_>, + def_id: DefId, + def_ctor: impl Fn(DefId) -> Def, +) -> hir::Path { + use rustc::ty::print::Printer; + + struct AbsolutePathPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, } - impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer { - fn root_mode(&self) -> &ty::item_path::RootMode { - const ABSOLUTE: &'static ty::item_path::RootMode = &ty::item_path::RootMode::Absolute; - ABSOLUTE + impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { + type Error = !; + + type Path = Vec; + type Region = (); + type Type = (); + type DynExistential = (); + + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx } - fn push(&mut self, text: &str) { - self.names.push(text.to_owned()); + fn print_region( + self, + _region: ty::Region<'_>, + ) -> Result { + Ok(()) } - } - let mut apb = AbsolutePathBuffer { names: vec![] }; + fn print_type( + self, + _ty: Ty<'tcx>, + ) -> Result { + Ok(()) + } + + fn print_dyn_existential( + self, + _predicates: &'tcx ty::List>, + ) -> Result { + Ok(()) + } + + fn path_crate( + self, + cnum: CrateNum, + ) -> Result { + Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) + } + fn path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + // This shouldn't ever be needed, but just in case: + Ok(vec![match trait_ref { + Some(trait_ref) => format!("{:?}", trait_ref), + None => format!("<{}>", self_ty), + }]) + } + + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + let mut path = print_prefix(self)?; + + // This shouldn't ever be needed, but just in case: + path.push(match trait_ref { + Some(trait_ref) => { + format!("", trait_ref, self_ty) + } + None => format!("", self_ty), + }); + + Ok(path) + } + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, + ) -> Result { + let mut path = print_prefix(self)?; + path.push(disambiguated_data.data.as_interned_str().to_string()); + Ok(path) + } + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, + _args: &[Kind<'tcx>], + ) -> Result { + print_prefix(self) + } + } - tcx.push_item_path(&mut apb, def_id, false); + let names = AbsolutePathPrinter { tcx: tcx.global_tcx() } + .print_def_path(def_id, &[]) + .unwrap(); hir::Path { span: DUMMY_SP, def: def_ctor(def_id), - segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment { + segments: hir::HirVec::from_vec(names.iter().map(|s| hir::PathSegment { ident: ast::Ident::from_str(&s), hir_id: None, def: None, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d711e4514a049..5109e775ebf81 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1117,11 +1117,7 @@ themePicker.onblur = handleThemeButtonsBlur; // with rustdoc running in parallel. all_indexes.sort(); let mut w = try_err!(File::create(&dst), &dst); - if options.enable_minification { - try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); - } else { - try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst); - } + try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); try_err!(write_minify_replacer(&mut w, &format!("{}\n{}", variables.join(""), all_indexes.join("\n")), options.enable_minification), diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1849e53d937ad..fef6910f40a57 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2077,16 +2077,22 @@ if (!DOMTokenList.prototype.remove) { } var toggle = createSimpleToggle(false); + var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false"; + var pageId = getPageId(); var func = function(e) { var next = e.nextElementSibling; if (!next) { return; } - if (hasClass(next, "docblock") || - (hasClass(next, "stability") && - hasClass(next.nextElementSibling, "docblock"))) { - insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); + if (hasClass(next, "docblock") === true || + (hasClass(next, "stability") === true && + hasClass(next.nextElementSibling, "docblock") === true)) { + var newToggle = toggle.cloneNode(true); + insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); + if (hideMethodDocs === true && hasClass(e, "method") === true) { + collapseDocs(newToggle, "hide", pageId); + } } }; @@ -2107,17 +2113,16 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("associatedconstant"), func); onEachLazy(document.getElementsByClassName("impl"), funcImpl); var impl_call = function() {}; - if (getCurrentValue("rustdoc-method-docs") !== "false") { + if (hideMethodDocs === true) { impl_call = function(e, newToggle, pageId) { if (e.id.match(/^impl(?:-\d+)?$/) === null) { // Automatically minimize all non-inherent impls - if (hasClass(e, "impl")) { + if (hasClass(e, "impl") === true) { collapseDocs(newToggle, "hide", pageId); } } }; } - var pageId = getPageId(); var newToggle = document.createElement("a"); newToggle.href = "javascript:void(0)"; newToggle.className = "collapse-toggle hidden-default collapsed"; @@ -2163,7 +2168,7 @@ if (!DOMTokenList.prototype.remove) { var inner_toggle = newToggle.cloneNode(true); inner_toggle.onclick = toggleClicked; e.insertBefore(inner_toggle, e.firstChild); - impl_call(e, inner_toggle, pageId); + impl_call(e.previousSibling, inner_toggle, pageId); } }); @@ -2265,30 +2270,6 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); - // In the search display, allows to switch between tabs. - function printTab(nb) { - if (nb === 0 || nb === 1 || nb === 2) { - currentTab = nb; - } - var nb_copy = nb; - onEachLazy(document.getElementById("titles").childNodes, function(elem) { - if (nb_copy === 0) { - addClass(elem, "selected"); - } else { - removeClass(elem, "selected"); - } - nb_copy -= 1; - }); - onEachLazy(document.getElementById("results").childNodes, function(elem) { - if (nb === 0) { - elem.style.display = ""; - } else { - elem.style.display = "none"; - } - nb -= 1; - }); - } - function createToggleWrapper(tog) { var span = document.createElement("span"); span.className = "toggle-label"; @@ -2374,6 +2355,30 @@ if (!DOMTokenList.prototype.remove) { }; }); + // In the search display, allows to switch between tabs. + function printTab(nb) { + if (nb === 0 || nb === 1 || nb === 2) { + currentTab = nb; + } + var nb_copy = nb; + onEachLazy(document.getElementById("titles").childNodes, function(elem) { + if (nb_copy === 0) { + addClass(elem, "selected"); + } else { + removeClass(elem, "selected"); + } + nb_copy -= 1; + }); + onEachLazy(document.getElementById("results").childNodes, function(elem) { + if (nb === 0) { + elem.style.display = ""; + } else { + elem.style.display = "none"; + } + nb -= 1; + }); + } + function putBackSearch(search_input) { if (search_input.value !== "") { addClass(main, "hidden"); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f11e268b9092c..fccf5a67ad465 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -5,8 +5,10 @@ #![feature(bind_by_move_pattern_guards)] #![feature(rustc_private)] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(in_band_lifetimes)] #![feature(nll)] #![feature(set_stdio)] #![feature(test)] @@ -16,6 +18,7 @@ #![feature(const_fn)] #![feature(drain_filter)] #![feature(inner_deref)] +#![feature(never_type)] #![recursion_limit="256"] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fefff1f3a7593..0f8e8894c04ab 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -288,6 +288,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { if ori_link.contains('/') { continue; } + + // [] is mostly likely not supposed to be a link + if ori_link.is_empty() { + continue; + } + let link = ori_link.replace("`", ""); let (def, fragment) = { let mut kind = PathKind::Unknown; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 928de29b297fc..1d45df499d86b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke use super::table::BucketState::{Empty, Full}; use super::table::Fallibility::{Fallible, Infallible}; -const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two +const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two /// The default behavior of HashMap implements a maximum load factor of 90.9%. #[derive(Clone)] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index f2111f2d9e028..c026de35da63d 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -8,7 +8,7 @@ use super::Recover; use super::map::{self, HashMap, Keys, RandomState}; // Future Optimization (FIXME!) -// ============================= +// ============================ // // Iteration over zero sized values is a noop. There is no need // for `bucket.val` in the case of HashSet. I suppose we would need HKT diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index f6cd9e82abd40..a2b12d00a78c2 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -956,6 +956,27 @@ impl f32 { pub fn atanh(self) -> f32 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp)] + /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32); + /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32); + /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + #[inline] + pub fn clamp(self, min: f32, max: f32) -> f32 { + assert!(min <= max); + let mut x = self; + if x < min { x = min; } + if x > max { x = max; } + x + } + } #[cfg(test)] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 8ff97ab828a73..be5cd92d4167b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -878,6 +878,27 @@ impl f64 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp)] + /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64); + /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64); + /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + #[inline] + pub fn clamp(self, min: f64, max: f64) -> f64 { + assert!(min <= max); + let mut x = self; + if x < min { x = min; } + if x > max { x = max; } + x + } + // Solaris/Illumos requires a wrapper around log, log2, and log10 functions // because of their non-standard behavior (e.g., log(-n) returns -Inf instead // of expected NaN). diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..8c3d0da0a7e40 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,7 +211,7 @@ pub struct DirBuilder { recursive: bool, } -/// How large a buffer to pre-allocate before reading the entire file. +/// Indicates how large a buffer to pre-allocate before reading the entire file. fn initial_buffer_size(file: &File) -> usize { // Allocate one extra byte so the buffer doesn't need to grow before the // final `read` call at the end of the file. Don't worry about `usize` @@ -1581,7 +1581,8 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// `O_CLOEXEC` is set for returned file descriptors. /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate /// NTFS streams are copied but only the size of the main stream is returned by -/// this function. +/// this function. On MacOS, this function corresponds to `copyfile` with +/// `COPYFILE_ALL`. /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior @@ -2836,6 +2837,26 @@ mod tests { assert_eq!(check!(out_path.metadata()).len(), copied_len); } + #[test] + fn copy_file_follows_dst_symlink() { + let tmp = tmpdir(); + if !got_symlink_permission(&tmp) { return }; + + let in_path = tmp.join("in.txt"); + let out_path = tmp.join("out.txt"); + let out_path_symlink = tmp.join("out_symlink.txt"); + + check!(fs::write(&in_path, "foo")); + check!(fs::write(&out_path, "bar")); + check!(symlink_file(&out_path, &out_path_symlink)); + + check!(fs::copy(&in_path, &out_path_symlink)); + + assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink()); + assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec()); + assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec()); + } + #[test] fn symlinks_work() { let tmpdir = tmpdir(); diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e3e2754a7aa09..1a2152a79af5a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -390,6 +390,28 @@ fn read_to_end_with_reservation(r: &mut R, ret } +pub(crate) fn default_read_vectored(read: F, bufs: &mut [IoVecMut<'_>]) -> Result +where + F: FnOnce(&mut [u8]) -> Result +{ + let buf = bufs + .iter_mut() + .find(|b| !b.is_empty()) + .map_or(&mut [][..], |b| &mut **b); + read(buf) +} + +pub(crate) fn default_write_vectored(write: F, bufs: &[IoVec<'_>]) -> Result +where + F: FnOnce(&[u8]) -> Result +{ + let buf = bufs + .iter() + .find(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); + write(buf) +} + /// The `Read` trait allows for reading bytes from a source. /// /// Implementors of the `Read` trait are called 'readers'. @@ -528,14 +550,11 @@ pub trait Read { /// written to possibly being only partially filled. This method must behave /// as a single call to `read` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `read`. + /// The default implementation calls `read` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + default_read_vectored(|b| self.read(b), bufs) } /// Determines if this `Read`er can work with buffers of uninitialized @@ -1107,14 +1126,11 @@ pub trait Write { /// read from possibly being only partially consumed. This method must /// behave as a call to `write` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `write`. + /// The default implementation calls `write` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + default_write_vectored(|b| self.write(b), bufs) } /// Flush this output stream, ensuring that all intermediately buffered diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e31680f23f1da..fc8ac9a0b3e00 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -221,7 +221,7 @@ #![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, + feature(global_asm, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] // std is implemented with unstable features, many of which are internal @@ -245,6 +245,7 @@ #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] #![feature(checked_duration_since)] +#![feature(clamp)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] #![feature(const_cstr_unchecked)] diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index bca22e717d724..4e30b1edd15e8 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -43,3 +43,8 @@ pub mod mem { } pub use crate::sys::ext::{io, arch, ffi}; + +/// Functions for querying thread-related information. +pub mod thread { + pub use crate::sys::abi::thread::current; +} diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 568400093440c..ad86acbb47de4 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -8,7 +8,7 @@ //! //! The [`Command`] struct is used to configure and spawn processes: //! -//! ``` +//! ```no_run //! use std::process::Command; //! //! let output = Command::new("echo") diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 5ebb61754e1ff..c383f21dcd752 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is false, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index 5081c3de73c5a..3f2f6166a791a 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -35,10 +35,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> Result { @@ -46,10 +43,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn take_error(&self) -> Result> { diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs index 86fe09d003520..c17fa2d00159e 100644 --- a/src/libstd/sys/sgx/abi/thread.rs +++ b/src/libstd/sys/sgx/abi/thread.rs @@ -4,6 +4,7 @@ use fortanix_sgx_abi::Tcs; /// all currently running threads in the enclave, and it is guaranteed to be /// constant for the lifetime of the thread. More specifically for SGX, there /// is a one-to-one correspondence of the ID to the address of the TCS. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn current() -> Tcs { extern "C" { fn get_tcs_addr() -> Tcs; } unsafe { get_tcs_addr() } diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index e5e42e3d0b048..e167e917957f3 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -103,24 +103,16 @@ impl TcpStream { self.inner.inner.read(buf) } - pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result { - let buf = match buf.get_mut(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.read(buf) + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> io::Result { self.inner.inner.write(buf) } - pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result { - let buf = match buf.get(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.write(buf) + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + io::default_write_vectored(|b| self.write(b), bufs) } pub fn peer_addr(&self) -> io::Result { diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 3b80b475a93db..7ff098bc9e123 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result { Ok(PathBuf::from(OsString::from_vec(buf))) } -#[cfg(not(any(target_os = "linux", target_os = "android")))] +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "macos", + target_os = "ios")))] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::fs::File; if !from.is_file() { @@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { writer.set_permissions(perm)?; Ok(written) } + +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn copy(from: &Path, to: &Path) -> io::Result { + const COPYFILE_ACL: u32 = 1 << 0; + const COPYFILE_STAT: u32 = 1 << 1; + const COPYFILE_XATTR: u32 = 1 << 2; + const COPYFILE_DATA: u32 = 1 << 3; + + const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL; + const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR; + const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA; + + const COPYFILE_STATE_COPIED: u32 = 8; + + #[allow(non_camel_case_types)] + type copyfile_state_t = *mut libc::c_void; + #[allow(non_camel_case_types)] + type copyfile_flags_t = u32; + + extern "C" { + fn copyfile( + from: *const libc::c_char, + to: *const libc::c_char, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> libc::c_int; + fn copyfile_state_alloc() -> copyfile_state_t; + fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int; + fn copyfile_state_get( + state: copyfile_state_t, + flag: u32, + dst: *mut libc::c_void, + ) -> libc::c_int; + } + + struct FreeOnDrop(copyfile_state_t); + impl Drop for FreeOnDrop { + fn drop(&mut self) { + // The code below ensures that `FreeOnDrop` is never a null pointer + unsafe { + // `copyfile_state_free` returns -1 if the `to` or `from` files + // cannot be closed. However, this is not considerd this an + // error. + copyfile_state_free(self.0); + } + } + } + + if !from.is_file() { + return Err(Error::new(ErrorKind::InvalidInput, + "the source path is not an existing regular file")) + } + + // We ensure that `FreeOnDrop` never contains a null pointer so it is + // always safe to call `copyfile_state_free` + let state = unsafe { + let state = copyfile_state_alloc(); + if state.is_null() { + return Err(crate::io::Error::last_os_error()); + } + FreeOnDrop(state) + }; + + cvt(unsafe { + copyfile( + cstr(from)?.as_ptr(), + cstr(to)?.as_ptr(), + state.0, + COPYFILE_ALL, + ) + })?; + + let mut bytes_copied: libc::off_t = 0; + cvt(unsafe { + copyfile_state_get( + state.0, + COPYFILE_STATE_COPIED, + &mut bytes_copied as *mut libc::off_t as *mut libc::c_void, + ) + })?; + Ok(bytes_copied as u64) +} diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs index b9098548b9c1e..c1af6ec12623c 100644 --- a/src/libstd/sys/wasm/alloc.rs +++ b/src/libstd/sys/wasm/alloc.rs @@ -49,7 +49,6 @@ unsafe impl GlobalAlloc for System { #[cfg(target_feature = "atomics")] mod lock { - use crate::arch::wasm32; use crate::sync::atomic::{AtomicI32, Ordering::SeqCst}; static LOCKED: AtomicI32 = AtomicI32::new(0); @@ -61,14 +60,76 @@ mod lock { if LOCKED.swap(1, SeqCst) == 0 { return DropLock } - unsafe { - let r = wasm32::i32_atomic_wait( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } + // Ok so here's where things get a little depressing. At this point + // in time we need to synchronously acquire a lock, but we're + // contending with some other thread. Typically we'd execute some + // form of `i32.atomic.wait` like so: + // + // unsafe { + // let r = core::arch::wasm32::i32_atomic_wait( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // expected value + // -1, // timeout + // ); + // debug_assert!(r == 0 || r == 1); + // } + // + // Unfortunately though in doing so we would cause issues for the + // main thread. The main thread in a web browser *cannot ever + // block*, no exceptions. This means that the main thread can't + // actually execute the `i32.atomic.wait` instruction. + // + // As a result if we want to work within the context of browsers we + // need to figure out some sort of allocation scheme for the main + // thread where when there's contention on the global malloc lock we + // do... something. + // + // Possible ideas include: + // + // 1. Attempt to acquire the global lock. If it fails, fall back to + // memory allocation via `memory.grow`. Later just ... somehow + // ... inject this raw page back into the main allocator as it + // gets sliced up over time. This strategy has the downside of + // forcing allocation of a page to happen whenever the main + // thread contents with other threads, which is unfortunate. + // + // 2. Maintain a form of "two level" allocator scheme where the main + // thread has its own allocator. Somehow this allocator would + // also be balanced with a global allocator, not only to have + // allocations cross between threads but also to ensure that the + // two allocators stay "balanced" in terms of free'd memory and + // such. This, however, seems significantly complicated. + // + // Out of a lack of other ideas, the current strategy implemented + // here is to simply spin. Typical spin loop algorithms have some + // form of "hint" here to the CPU that it's what we're doing to + // ensure that the CPU doesn't get too hot, but wasm doesn't have + // such an instruction. + // + // To be clear, spinning here is not a great solution. + // Another thread with the lock may take quite a long time to wake + // up. For example it could be in `memory.grow` or it could be + // evicted from the CPU for a timeslice like 10ms. For these periods + // of time our thread will "helpfully" sit here and eat CPU time + // until it itself is evicted or the lock holder finishes. This + // means we're just burning and wasting CPU time to no one's + // benefit. + // + // Spinning does have the nice properties, though, of being + // semantically correct, being fair to all threads for memory + // allocation, and being simple enough to implement. + // + // This will surely (hopefully) be replaced in the future with a + // real memory allocator that can handle the restriction of the main + // thread. + // + // + // FIXME: We can also possibly add an optimization here to detect + // when a thread is the main thread or not and block on all + // non-main-thread threads. Currently, however, we have no way + // of knowing which wasm thread is on the browser main thread, but + // if we could figure out we could at least somewhat mitigate the + // cost of this spinning. } } @@ -76,12 +137,16 @@ mod lock { fn drop(&mut self) { let r = LOCKED.swap(0, SeqCst); debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic_notify( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } + + // Note that due to the above logic we don't actually need to wake + // anyone up, but if we did it'd likely look something like this: + // + // unsafe { + // core::arch::wasm32::atomic_notify( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // only one thread + // ); + // } } } } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 07f4f5f0e58c4..b38727830f37f 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -37,9 +37,9 @@ pub struct Pipes { /// /// The ours/theirs pipes are *not* specifically readable or writable. Each /// one only supports a read or a write, but which is which depends on the -/// boolean flag given. If `ours_readable` is true then `ours` is readable where -/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is -/// writable where `theirs` is readable. +/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and +/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours` +/// is writable and `theirs` is readable. /// /// Also note that the `ours` pipe is always a handle opened up in overlapped /// mode. This means that technically speaking it should only ever be used diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6d7093ac33ea7..4c86f70ad871d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -712,13 +712,6 @@ mod tests { 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) && crate::mem::size_of::() <= 4) { - let eighty_years = second * 60 * 60 * 24 * 365 * 80; - assert_almost_eq!(a - eighty_years + eighty_years, a); - assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); - } - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); @@ -747,8 +740,8 @@ mod tests { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH).unwrap(); - let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); assert_eq!(b - a, Duration::new(1, 0)); diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4e4432a3f334d..2abb7e407eb02 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) - -> (ast::Crate, Features) { +pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition, + allow_features: &Option>) -> (ast::Crate, Features) { let features; { let mut strip_unconfigured = StripUnconfigured { @@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, edition); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2c367f1f40242..ac24475cab89f 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -378,6 +378,21 @@ Erroneous code example: "##, +E0725: r##" +A feature attribute named a feature that was disallowed in the compiler +command line flags. + +Erroneous code example: + +```ignore (can't specify compiler flags from doctests) +#![feature(never_type)] // error: the feature `never_type` is not in + // the list of allowed features +``` + +Delete the offending feature attribute, or add it to the list of allowed +features in the `-Z allow_features` flag. +"##, + } register_diagnostics! { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 279e2089f5d71..280b17da0be3f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1042,7 +1042,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), - ("rustc_item_path", Whitelisted, template!(Word), Gated(Stability::Unstable, + ("rustc_def_path", Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), @@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - crate_edition: Edition) -> Features { + crate_edition: Edition, allow_features: &Option>) -> Features { fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); if let Some(reason) = reason { @@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|f| *f == name.as_str()).is_none() { + span_err!(span_handler, mi.span, E0725, + "the feature `{}` is not in the list of allowed features", + name); + continue; + } + } + set(&mut features, mi.span); features.declared_lang_features.push((name, mi.span, None)); continue diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe31311094b89..22af7d47fd0a1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - let msg = "macros that expand to items must either \ - be surrounded with braces or followed by a semicolon"; - self.span_err(self.prev_span, msg); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } (ident, ast::MacroDef { tokens: tokens, legacy: true }) @@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> { // if it has a special ident, it's definitely an item // // Require a semicolon or braces. - if style != MacStmtStyle::Braces { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must \ - either be surrounded with braces or \ - followed by a semicolon"); - } + if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let span = lo.to(hi); Stmt { @@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> { }; // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must either \ - be surrounded with braces or followed by \ - a semicolon"); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; @@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> { } } } + + fn report_invalid_macro_expansion_item(&self) { + self.struct_span_err( + self.prev_span, + "macros that expand to items must be delimited with braces or followed by a semicolon", + ).multipart_suggestion( + "change the delimiters to curly braces", + vec![ + (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")), + (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()), + ], + Applicability::MaybeIncorrect, + ).span_suggestion( + self.sess.source_map.next_point(self.prev_span), + "add a semicolon", + ';'.to_string(), + Applicability::MaybeIncorrect, + ).emit(); + } } pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, handler: &errors::Handler) { diff --git a/src/llvm-project b/src/llvm-project index 38ad31bde8ff6..4fc9fb8245abe 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 38ad31bde8ff681d862dc0f96930a5dd9b7a472e +Subproject commit 4fc9fb8245abe24680192535870c4522644a4212 diff --git a/src/test/debuginfo/auxiliary/issue13213aux.rs b/src/test/debuginfo/auxiliary/issue-13213-aux.rs similarity index 100% rename from src/test/debuginfo/auxiliary/issue13213aux.rs rename to src/test/debuginfo/auxiliary/issue-13213-aux.rs diff --git a/src/test/debuginfo/issue-13213.rs b/src/test/debuginfo/issue-13213.rs index 898ebe547b360..3c9a365fd4f7b 100644 --- a/src/test/debuginfo/issue-13213.rs +++ b/src/test/debuginfo/issue-13213.rs @@ -1,8 +1,8 @@ // min-lldb-version: 310 -// aux-build:issue13213aux.rs +// aux-build:issue-13213-aux.rs -extern crate issue13213aux; +extern crate issue_13213_aux; // compile-flags:-g @@ -10,6 +10,6 @@ extern crate issue13213aux; // statics that are marked with AvailableExternallyLinkage in the importing crate, may actually not // be available because they have been optimized out from the exporting crate. fn main() { - let b: issue13213aux::S = issue13213aux::A; + let b: issue_13213_aux::S = issue_13213_aux::A; println!("Nothing to do here..."); } diff --git a/src/test/incremental/auxiliary/issue_49482_macro_def.rs b/src/test/incremental/auxiliary/issue-49482-macro-def.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_49482_macro_def.rs rename to src/test/incremental/auxiliary/issue-49482-macro-def.rs diff --git a/src/test/incremental/auxiliary/issue_49482_reexport.rs b/src/test/incremental/auxiliary/issue-49482-reexport.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_49482_reexport.rs rename to src/test/incremental/auxiliary/issue-49482-reexport.rs diff --git a/src/test/incremental/auxiliary/issue_54059.rs b/src/test/incremental/auxiliary/issue-54059.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_54059.rs rename to src/test/incremental/auxiliary/issue-54059.rs diff --git a/src/test/incremental/issue-49482.rs b/src/test/incremental/issue-49482.rs index 67d2c3876d70f..042ecc0f27954 100644 --- a/src/test/incremental/issue-49482.rs +++ b/src/test/incremental/issue-49482.rs @@ -1,5 +1,5 @@ -// aux-build:issue_49482_macro_def.rs -// aux-build:issue_49482_reexport.rs +// aux-build:issue-49482-macro-def.rs +// aux-build:issue-49482-reexport.rs // revisions: rpass1 extern crate issue_49482_reexport; diff --git a/src/test/incremental/issue-49595/issue_49595.rs b/src/test/incremental/issue-49595/issue-49595.rs similarity index 100% rename from src/test/incremental/issue-49595/issue_49595.rs rename to src/test/incremental/issue-49595/issue-49595.rs diff --git a/src/test/incremental/issue-54059.rs b/src/test/incremental/issue-54059.rs index d78bbccf1bcca..0a5a547509f69 100644 --- a/src/test/incremental/issue-54059.rs +++ b/src/test/incremental/issue-54059.rs @@ -1,4 +1,4 @@ -// aux-build:issue_54059.rs +// aux-build:issue-54059.rs // ignore-wasm32-bare no libc for ffi testing // ignore-windows - dealing with weird symbols issues on dylibs isn't worth it // revisions: rpass1 diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index 1bbbe67a12cb8..3ce43cc4a224f 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -35,7 +35,7 @@ fn main() { // _2 = move _3; // StorageDead(_3); // StorageLive(_4); -// _4 = std::option::Option>::None; +// _4 = std::option::Option::>::None; // FakeRead(ForLet, _4); // AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // StorageLive(_5); diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index 9db25b15f6835..5a461d6148254 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -1,7 +1,7 @@ // Regression test for #41697. Using dump-mir was triggering // artificial cycles: during type-checking, we had to get the MIR for // the constant expressions in `[u8; 2]`, which in turn would trigger -// an attempt to get the item-path, which in turn would request the +// an attempt to get the def-path, which in turn would request the // types of the impl, which would trigger a cycle. We suppressed this // cycle now by forcing mir-dump to avoid asking for types of an impl. diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index ab6de71d2894d..9eeef8570a37a 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -42,7 +42,7 @@ fn main() { // START rustc.full_tested_match.QualifyAndPromoteConstants.after.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 42i32,); +// _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb7]; @@ -111,7 +111,7 @@ fn main() { // START rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 42i32,); +// _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb7]; @@ -180,7 +180,7 @@ fn main() { // START rustc.main.QualifyAndPromoteConstants.before.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 1i32,); +// _2 = std::option::Option::::Some(const 1i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [1isize: bb2, otherwise: bb3]; diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index cdf635567378e..3b333b5431c3e 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -98,7 +98,7 @@ fn main() { // } // END rustc.main.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 { +// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 { // ... // bb0: { // Retag([fn entry] _1); diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index a5d6ced2b1772..9a22f57116ed8 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -18,7 +18,7 @@ fn main() { // StorageLive(_4); // StorageLive(_5); // _5 = _1; -// _4 = std::option::Option::Some(move _5,); +// _4 = std::option::Option::::Some(move _5,); // StorageDead(_5); // _3 = &_4; // FakeRead(ForLet, _3); diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index fe85baa048e39..ced30381fda68 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -7,11 +7,18 @@ impl A { const ASSOCIATED_CONSTANT: i32 = 2; } +// See #59021 +enum Test { + X(usize), + Y { a: usize }, +} + enum E { V = 5, } fn main() { + let f = Test::X as fn(usize) -> Test; let v = Vec::::new(); } @@ -64,3 +71,14 @@ fn main() { // _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5]; // } // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir + +// START rustc.Test-X.mir_map.0.mir +// fn Test::X(_1: usize) -> Test { +// let mut _0: Test; +// +// bb0: { +// _0 = Test::X(move _1,); +// return; +// } +// } +// END rustc.Test-X.mir_map.0.mir diff --git a/src/test/pretty/issue_12590_a.rs b/src/test/pretty/issue-12590-a.rs similarity index 75% rename from src/test/pretty/issue_12590_a.rs rename to src/test/pretty/issue-12590-a.rs index 1ddd3c0426371..1a9e85c42d8fb 100644 --- a/src/test/pretty/issue_12590_a.rs +++ b/src/test/pretty/issue-12590-a.rs @@ -2,6 +2,7 @@ // The next line should not be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b; fn main() { } diff --git a/src/test/pretty/issue-12590-b.rs b/src/test/pretty/issue-12590-b.rs new file mode 100644 index 0000000000000..b14c7afa22142 --- /dev/null +++ b/src/test/pretty/issue-12590-b.rs @@ -0,0 +1,5 @@ +// Second part of two-file test + +fn b() { } + +fn main() { } diff --git a/src/test/pretty/issue_12590_c.pp b/src/test/pretty/issue-12590-c.pp similarity index 82% rename from src/test/pretty/issue_12590_c.pp rename to src/test/pretty/issue-12590-c.pp index 2418283530375..1761c0653ce86 100644 --- a/src/test/pretty/issue_12590_c.pp +++ b/src/test/pretty/issue-12590-c.pp @@ -6,10 +6,11 @@ extern crate std; // pretty-compare-only // pretty-mode:expanded -// pp-exact:issue_12590_c.pp +// pp-exact:issue-12590-c.pp // The next line should be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b { fn b() { } diff --git a/src/test/pretty/issue_12590_c.rs b/src/test/pretty/issue-12590-c.rs similarity index 67% rename from src/test/pretty/issue_12590_c.rs rename to src/test/pretty/issue-12590-c.rs index c0da36c2100ef..2cc444edda3d7 100644 --- a/src/test/pretty/issue_12590_c.rs +++ b/src/test/pretty/issue-12590-c.rs @@ -1,9 +1,10 @@ // pretty-compare-only // pretty-mode:expanded -// pp-exact:issue_12590_c.pp +// pp-exact:issue-12590-c.pp // The next line should be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b; fn main() { } diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index b529beba78367..ad663412e7776 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -32,27 +32,27 @@ (($crate::fmt::format as for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<$crate::fmt::Arguments>::new_v1 as - fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test" + fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test" + as + &'static str)] as - &'static str)] + [&str; 1]) as - [&str; 1]) - as - &[&str; 1]), - (&(match (() + &[&str; 1]), + (&(match (() + as + ()) + { + () + => + ([] as - ()) - { - () - => - ([] - as - [std::fmt::ArgumentV1<'_>; 0]), - } + [std::fmt::ArgumentV1<'_>; 0]), + } + as + [std::fmt::ArgumentV1<'_>; 0]) as - [std::fmt::ArgumentV1<'_>; 0]) - as - &[std::fmt::ArgumentV1<'_>; 0])) + &[std::fmt::ArgumentV1<'_>; 0])) as std::fmt::Arguments<'_>)) as std::string::String); diff --git a/src/test/pretty/issue_12590_b.rs b/src/test/pretty/issue_12590_b.rs deleted file mode 100644 index f188f7bca6983..0000000000000 --- a/src/test/pretty/issue_12590_b.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Second part of two file test -fn b() { } - -fn main() { } diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/issue_24106.rs b/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/issue_24106.rs rename to src/test/run-pass-fulldeps/auxiliary/issue-24106.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs rename to src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs rename to src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs rename to src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/plugin_args.rs rename to src/test/run-pass-fulldeps/auxiliary/plugin-args.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs rename to src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs b/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs rename to src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs index 21b8ec7be9892..ac8fff4f6bfad 100644 --- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs +++ b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_partial_eq.rs +// aux-build:custom-derive-partial-eq.rs // ignore-stage1 #![feature(plugin)] #![plugin(custom_derive_partial_eq)] diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs index 769861e7c94ad..38eaa71dd6aba 100644 --- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs +++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_plugin_attr.rs +// aux-build:custom-derive-plugin-attr.rs // ignore-stage1 #![feature(plugin, rustc_attrs)] diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs index be26943b6dc16..2b0bb51d90aec 100644 --- a/src/test/run-pass-fulldeps/derive-totalsum.rs +++ b/src/test/run-pass-fulldeps/derive-totalsum.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_plugin.rs +// aux-build:custom-derive-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs index 50e9b14b26832..2add3ccbe36f2 100644 --- a/src/test/run-pass-fulldeps/issue-15778-pass.rs +++ b/src/test/run-pass-fulldeps/issue-15778-pass.rs @@ -1,4 +1,4 @@ -// aux-build:lint_for_crate.rs +// aux-build:lint-for-crate.rs // ignore-stage1 // compile-flags: -D crate-not-okay diff --git a/src/test/run-pass-fulldeps/issue_24106.rs b/src/test/run-pass-fulldeps/issue-24106.rs similarity index 71% rename from src/test/run-pass-fulldeps/issue_24106.rs rename to src/test/run-pass-fulldeps/issue-24106.rs index a497d9f33ae81..e8e85ff33772e 100644 --- a/src/test/run-pass-fulldeps/issue_24106.rs +++ b/src/test/run-pass-fulldeps/issue-24106.rs @@ -1,4 +1,4 @@ -// aux-build:issue_24106.rs +// aux-build:issue-24106.rs extern crate issue_24106; diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs index cb01eddd7e49e..133f6302bde57 100644 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ b/src/test/run-pass-fulldeps/issue-40663.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -// aux-build:custom_derive_plugin.rs +// aux-build:custom-derive-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs index 3aad40ecfe8aa..411631104a4bc 100644 --- a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs +++ b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs @@ -1,4 +1,4 @@ -// aux-build:llvm_pass_plugin.rs +// aux-build:llvm-pass-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs index dcac160c4c974..573bfca31683f 100644 --- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs +++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_imports)] -// aux-build:macro_crate_test.rs +// aux-build:macro-crate-test.rs // ignore-stage1 #![feature(rustc_attrs)] diff --git a/src/test/run-pass-fulldeps/plugin-args-1.rs b/src/test/run-pass-fulldeps/plugin-args-1.rs index 0111af1c76804..1bdf004e3052f 100644 --- a/src/test/run-pass-fulldeps/plugin-args-1.rs +++ b/src/test/run-pass-fulldeps/plugin-args-1.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/plugin-args-2.rs b/src/test/run-pass-fulldeps/plugin-args-2.rs index e4a3dfab5668d..83091df058283 100644 --- a/src/test/run-pass-fulldeps/plugin-args-2.rs +++ b/src/test/run-pass-fulldeps/plugin-args-2.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/plugin-args-3.rs b/src/test/run-pass-fulldeps/plugin-args-3.rs index 4696233f2818e..9cd9bee5a0fe9 100644 --- a/src/test/run-pass-fulldeps/plugin-args-3.rs +++ b/src/test/run-pass-fulldeps/plugin-args-3.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/roman-numerals-macro.rs b/src/test/run-pass-fulldeps/roman-numerals-macro.rs index 59a2d132cdc26..49c12e426fee2 100644 --- a/src/test/run-pass-fulldeps/roman-numerals-macro.rs +++ b/src/test/run-pass-fulldeps/roman-numerals-macro.rs @@ -1,4 +1,4 @@ -// aux-build:roman_numerals.rs +// aux-build:roman-numerals.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs new file mode 100644 index 0000000000000..cf6e6f7231638 --- /dev/null +++ b/src/test/run-pass-fulldeps/undef_mask.rs @@ -0,0 +1,26 @@ +// ignore-cross-compile +// ignore-stage1 + +#![feature(rustc_private)] + +extern crate rustc; + +use rustc::mir::interpret::UndefMask; +use rustc::ty::layout::Size; + +fn main() { + let mut mask = UndefMask::new(Size::from_bytes(500), false); + assert!(!mask.get(Size::from_bytes(499))); + mask.set(Size::from_bytes(499), true); + assert!(mask.get(Size::from_bytes(499))); + mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true); + for i in 0..100 { + assert!(!mask.get(Size::from_bytes(i))); + } + for i in 100..256 { + assert!(mask.get(Size::from_bytes(i))); + } + for i in 256..499 { + assert!(!mask.get(Size::from_bytes(i))); + } +} diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs index 02b88f6a7abfc..cd2c17220655a 100644 --- a/src/test/run-pass/array-slice-vec/estr-slice.rs +++ b/src/test/run-pass/array-slice-vec/estr-slice.rs @@ -14,7 +14,7 @@ pub fn main() { let z : &str = "thing"; assert_eq!(v, x); - assert!(x != z); + assert_ne!(x, z); let a = "aaaa"; let b = "bbbb"; @@ -26,7 +26,7 @@ pub fn main() { assert!(a < b); assert!(a <= b); - assert!(a != b); + assert_ne!(a, b); assert!(b >= a); assert!(b > a); @@ -34,7 +34,7 @@ pub fn main() { assert!(a < c); assert!(a <= c); - assert!(a != c); + assert_ne!(a, c); assert!(c >= a); assert!(c > a); @@ -42,7 +42,7 @@ pub fn main() { assert!(c < cc); assert!(c <= cc); - assert!(c != cc); + assert_ne!(c, cc); assert!(cc >= c); assert!(cc > c); diff --git a/src/test/run-pass/auxiliary/rmeta_rlib.rs b/src/test/run-pass/auxiliary/rmeta-rlib.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta_rlib.rs rename to src/test/run-pass/auxiliary/rmeta-rlib.rs diff --git a/src/test/run-pass/auxiliary/rmeta_rmeta.rs b/src/test/run-pass/auxiliary/rmeta-rmeta.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta_rmeta.rs rename to src/test/run-pass/auxiliary/rmeta-rmeta.rs diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs new file mode 100644 index 0000000000000..86b0977bebe1d --- /dev/null +++ b/src/test/run-pass/issue-55809.rs @@ -0,0 +1,30 @@ +// edition:2018 +// run-pass + +#![feature(async_await, await_macro, futures_api)] + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad(v: T) -> u8 where T: Foo { + await!(foo_async(v)) +} + +async fn async_main() { + let mut v = (); + + let _ = await!(bad(&mut v)); + let _ = await!(foo_async(&mut v)); + let _ = await!(bad(v)); +} + +fn main() { + let _ = async_main(); +} diff --git a/src/test/run-pass/issues/auxiliary/issue_10031_aux.rs b/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_10031_aux.rs rename to src/test/run-pass/issues/auxiliary/issue-10031-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_1.rs b/src/test/run-pass/issues/auxiliary/issue-12612-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_12612_1.rs rename to src/test/run-pass/issues/auxiliary/issue-12612-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_2.rs b/src/test/run-pass/issues/auxiliary/issue-12612-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_12612_2.rs rename to src/test/run-pass/issues/auxiliary/issue-12612-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue13507.rs b/src/test/run-pass/issues/auxiliary/issue-13507.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue13507.rs rename to src/test/run-pass/issues/auxiliary/issue-13507.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_19293.rs b/src/test/run-pass/issues/auxiliary/issue-19293.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_19293.rs rename to src/test/run-pass/issues/auxiliary/issue-19293.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_20389.rs b/src/test/run-pass/issues/auxiliary/issue-20389.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_20389.rs rename to src/test/run-pass/issues/auxiliary/issue-20389.rs diff --git a/src/test/run-pass/issues/auxiliary/issue2170lib.rs b/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue2170lib.rs rename to src/test/run-pass/issues/auxiliary/issue-2170-lib.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_a.rs b/src/test/run-pass/issues/auxiliary/issue-2316-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2316_a.rs rename to src/test/run-pass/issues/auxiliary/issue-2316-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_b.rs b/src/test/run-pass/issues/auxiliary/issue-2316-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2316_b.rs rename to src/test/run-pass/issues/auxiliary/issue-2316-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2472_b.rs b/src/test/run-pass/issues/auxiliary/issue-2472-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2472_b.rs rename to src/test/run-pass/issues/auxiliary/issue-2472-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2723_a.rs b/src/test/run-pass/issues/auxiliary/issue-2723-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2723_a.rs rename to src/test/run-pass/issues/auxiliary/issue-2723-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc similarity index 62% rename from src/test/run-pass/issues/auxiliary/issue_3136_a.rc rename to src/test/run-pass/issues/auxiliary/issue-3136-a.rc index 46da4132b82d7..cd5fd3145055c 100644 --- a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc +++ b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc @@ -1,3 +1,4 @@ #![crate_type = "lib"] +#[path = "issue-3136-a.rs"] pub mod issue_3136_a; diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rs b/src/test/run-pass/issues/auxiliary/issue-3136-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_3136_a.rs rename to src/test/run-pass/issues/auxiliary/issue-3136-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue34796aux.rs b/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue34796aux.rs rename to src/test/run-pass/issues/auxiliary/issue-34796-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38190.rs b/src/test/run-pass/issues/auxiliary/issue-38190.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38190.rs rename to src/test/run-pass/issues/auxiliary/issue-38190.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38226_aux.rs b/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38226_aux.rs rename to src/test/run-pass/issues/auxiliary/issue-38226-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38715-modern.rs b/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38715-modern.rs rename to src/test/run-pass/issues/auxiliary/issue-38715-modern.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38715.rs b/src/test/run-pass/issues/auxiliary/issue-38715.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38715.rs rename to src/test/run-pass/issues/auxiliary/issue-38715.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_3979_traits.rs b/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_3979_traits.rs rename to src/test/run-pass/issues/auxiliary/issue-3979-traits.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_39823.rs b/src/test/run-pass/issues/auxiliary/issue-39823.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_39823.rs rename to src/test/run-pass/issues/auxiliary/issue-39823.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_40469.rs b/src/test/run-pass/issues/auxiliary/issue-40469.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_40469.rs rename to src/test/run-pass/issues/auxiliary/issue-40469.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_41053.rs b/src/test/run-pass/issues/auxiliary/issue-41053.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_41053.rs rename to src/test/run-pass/issues/auxiliary/issue-41053.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_42007_s.rs b/src/test/run-pass/issues/auxiliary/issue-42007-s.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_42007_s.rs rename to src/test/run-pass/issues/auxiliary/issue-42007-s.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_8401.rs b/src/test/run-pass/issues/auxiliary/issue-8401.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_8401.rs rename to src/test/run-pass/issues/auxiliary/issue-8401.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9123.rs b/src/test/run-pass/issues/auxiliary/issue-9123.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9123.rs rename to src/test/run-pass/issues/auxiliary/issue-9123.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9155.rs b/src/test/run-pass/issues/auxiliary/issue-9155.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9155.rs rename to src/test/run-pass/issues/auxiliary/issue-9155.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9188.rs b/src/test/run-pass/issues/auxiliary/issue-9188.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9188.rs rename to src/test/run-pass/issues/auxiliary/issue-9188.rs diff --git a/src/test/run-pass/issues/issue-10031.rs b/src/test/run-pass/issues/issue-10031.rs index ba1fbac48453a..136df05c2397a 100644 --- a/src/test/run-pass/issues/issue-10031.rs +++ b/src/test/run-pass/issues/issue-10031.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_10031_aux.rs +// aux-build:issue-10031-aux.rs // pretty-expanded FIXME #23616 extern crate issue_10031_aux; diff --git a/src/test/run-pass/issues/issue-12612.rs b/src/test/run-pass/issues/issue-12612.rs index 158c2aed13724..d254f6941a339 100644 --- a/src/test/run-pass/issues/issue-12612.rs +++ b/src/test/run-pass/issues/issue-12612.rs @@ -1,7 +1,7 @@ // run-pass #![allow(unused_imports)] -// aux-build:issue_12612_1.rs -// aux-build:issue_12612_2.rs +// aux-build:issue-12612-1.rs +// aux-build:issue-12612-2.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-13507-2.rs b/src/test/run-pass/issues/issue-13507-2.rs index 4ea95149dc6b5..ce920a3ccab9d 100644 --- a/src/test/run-pass/issues/issue-13507-2.rs +++ b/src/test/run-pass/issues/issue-13507-2.rs @@ -1,14 +1,14 @@ // run-pass #![allow(unused_imports)] -// aux-build:issue13507.rs +// aux-build:issue-13507.rs -extern crate issue13507; -use issue13507::testtypes; +extern crate issue_13507; +use issue_13507::testtypes; use std::any::TypeId; pub fn type_ids() -> Vec { - use issue13507::testtypes::*; + use issue_13507::testtypes::*; vec![ TypeId::of::(), TypeId::of::(), @@ -30,7 +30,7 @@ pub fn type_ids() -> Vec { } pub fn main() { - let othercrate = issue13507::testtypes::type_ids(); + let othercrate = issue_13507::testtypes::type_ids(); let thiscrate = type_ids(); assert_eq!(thiscrate, othercrate); } diff --git a/src/test/run-pass/issue-18952.rs b/src/test/run-pass/issues/issue-18952.rs similarity index 100% rename from src/test/run-pass/issue-18952.rs rename to src/test/run-pass/issues/issue-18952.rs diff --git a/src/test/run-pass/issues/issue-19293.rs b/src/test/run-pass/issues/issue-19293.rs index 90f96566f382b..b6e9e3d065a48 100644 --- a/src/test/run-pass/issues/issue-19293.rs +++ b/src/test/run-pass/issues/issue-19293.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_19293.rs +// aux-build:issue-19293.rs // pretty-expanded FIXME #23616 extern crate issue_19293; diff --git a/src/test/run-pass/issues/issue-20389.rs b/src/test/run-pass/issues/issue-20389.rs index 9c5a1844e293b..9bc3efcc1c4bf 100644 --- a/src/test/run-pass/issues/issue-20389.rs +++ b/src/test/run-pass/issues/issue-20389.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_20389.rs +// aux-build:issue-20389.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-2170-exe.rs b/src/test/run-pass/issues/issue-2170-exe.rs new file mode 100644 index 0000000000000..a89579706c8dc --- /dev/null +++ b/src/test/run-pass/issues/issue-2170-exe.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-2170-lib.rs +// pretty-expanded FIXME #23616 + +extern crate issue_2170_lib; + +pub fn main() { + // let _ = issue_2170_lib::rsrc(2); +} diff --git a/src/test/run-pass/issues/issue-2316-c.rs b/src/test/run-pass/issues/issue-2316-c.rs index 6783f3fcfc691..d975aa695c836 100644 --- a/src/test/run-pass/issues/issue-2316-c.rs +++ b/src/test/run-pass/issues/issue-2316-c.rs @@ -1,6 +1,6 @@ // run-pass -// aux-build:issue_2316_a.rs -// aux-build:issue_2316_b.rs +// aux-build:issue-2316-a.rs +// aux-build:issue-2316-b.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs similarity index 62% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs index 3ae53baa82a5a..2275a8da696dd 100644 --- a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs +++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs @@ -4,7 +4,8 @@ // that separate file has many multi-byte characters, to try to // encourage the compiler to trip on them. -mod issue24687_mbcs_in_comments; +#[path = "issue-24687-mbcs-in-comments.rs"] +mod issue_24687_mbcs_in_comments; -pub use issue24687_mbcs_in_comments::D; +pub use issue_24687_mbcs_in_comments::D; diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs similarity index 100% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs similarity index 62% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs index a0cda4fad26f5..773792c7a3f1f 100644 --- a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs +++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs @@ -1,11 +1,11 @@ // run-pass -// aux-build:issue24687_lib.rs +// aux-build:issue-24687-lib.rs // compile-flags:-g -extern crate issue24687_lib as d; +extern crate issue_24687_lib as d; fn main() { - // Create a d, which has a destructor whose body will be codegen'ed + // Create a `D`, which has a destructor whose body will be codegen'ed // into the generated code here, and thus the local debuginfo will // need references into the original source locations from // `importer` above. diff --git a/src/test/run-pass/issues/issue-2472.rs b/src/test/run-pass/issues/issue-2472.rs index cadd0151b4e81..c790bc2d09548 100644 --- a/src/test/run-pass/issues/issue-2472.rs +++ b/src/test/run-pass/issues/issue-2472.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_2472_b.rs +// aux-build:issue-2472-b.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-26873-multifile.rs b/src/test/run-pass/issues/issue-26873-multifile.rs index 7b19713fcc661..da2acf6c9f704 100644 --- a/src/test/run-pass/issues/issue-26873-multifile.rs +++ b/src/test/run-pass/issues/issue-26873-multifile.rs @@ -5,6 +5,7 @@ // ignore-pretty issue #37195 -mod issue_26873_multifile; +#[path = "issue-26873-multifile/mod.rs"] +mod multifile; fn main() {} diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/B.rs b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/B.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/B.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/C.rs b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/C.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/C.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/mod.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/mod.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir b/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir rename to src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir diff --git a/src/test/run-pass/issues/issue_26873_multifile/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/mod.rs rename to src/test/run-pass/issues/issue-26873-multifile/mod.rs diff --git a/src/test/run-pass/issues/issue-2723-b.rs b/src/test/run-pass/issues/issue-2723-b.rs index 41f264b6dc075..1910561d0ba43 100644 --- a/src/test/run-pass/issues/issue-2723-b.rs +++ b/src/test/run-pass/issues/issue-2723-b.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_2723_a.rs +// aux-build:issue-2723-a.rs extern crate issue_2723_a; use issue_2723_a::f; diff --git a/src/test/run-pass/issues/issue28498-must-work-ex1.rs b/src/test/run-pass/issues/issue-28498-must-work-ex1.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-must-work-ex1.rs rename to src/test/run-pass/issues/issue-28498-must-work-ex1.rs diff --git a/src/test/run-pass/issues/issue28498-must-work-ex2.rs b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-must-work-ex2.rs rename to src/test/run-pass/issues/issue-28498-must-work-ex2.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-ex1.rs rename to src/test/run-pass/issues/issue-28498-ugeh-ex1.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs diff --git a/src/test/run-pass/issues/issue29927-1.rs b/src/test/run-pass/issues/issue-29927-1.rs similarity index 100% rename from src/test/run-pass/issues/issue29927-1.rs rename to src/test/run-pass/issues/issue-29927-1.rs diff --git a/src/test/run-pass/issues/issue_3136_b.rs b/src/test/run-pass/issues/issue-3136-b.rs similarity index 75% rename from src/test/run-pass/issues/issue_3136_b.rs rename to src/test/run-pass/issues/issue-3136-b.rs index f0bdd2b5ec050..c4ca7236e7615 100644 --- a/src/test/run-pass/issues/issue_3136_b.rs +++ b/src/test/run-pass/issues/issue-3136-b.rs @@ -1,7 +1,8 @@ // run-pass -// aux-build:issue_3136_a.rc +// aux-build:issue-3136-a.rc // pretty-expanded FIXME #23616 extern crate issue_3136_a; + pub fn main() {} diff --git a/src/test/run-pass/issues/issue-34796.rs b/src/test/run-pass/issues/issue-34796.rs index a81040b8f4db3..88d5c50a27d29 100644 --- a/src/test/run-pass/issues/issue-34796.rs +++ b/src/test/run-pass/issues/issue-34796.rs @@ -8,8 +8,8 @@ // the symbol name. // The fix was to make the order in which predicates get encoded stable. -// aux-build:issue34796aux.rs -extern crate issue34796aux; +// aux-build:issue-34796-aux.rs +extern crate issue_34796_aux; fn mk() -> T { loop {} } @@ -19,7 +19,7 @@ struct Data { } fn main() { - issue34796aux::bar(|()| { + issue_34796_aux::bar(|()| { Data::<(), std::io::Error> { data: mk(), error: mk(), diff --git a/src/test/run-pass/issues/issue-38190.rs b/src/test/run-pass/issues/issue-38190.rs index 4f83dd263830e..cfa0420c80d1d 100644 --- a/src/test/run-pass/issues/issue-38190.rs +++ b/src/test/run-pass/issues/issue-38190.rs @@ -1,12 +1,15 @@ // run-pass -// aux-build:issue_38190.rs +// aux-build:issue-38190.rs // ignore-pretty issue #37195 #[macro_use] extern crate issue_38190; mod auxiliary { - m!([mod issue_38190;]); + m!([ + #[path = "issue-38190.rs"] + mod issue_38190; + ]); } fn main() {} diff --git a/src/test/run-pass/issues/issue-38226.rs b/src/test/run-pass/issues/issue-38226.rs index cd569c583f3a7..3213e3618a88b 100644 --- a/src/test/run-pass/issues/issue-38226.rs +++ b/src/test/run-pass/issues/issue-38226.rs @@ -2,7 +2,7 @@ // This test makes sure that we don't run into a linker error because of the // middle::reachable pass missing trait methods with default impls. -// aux-build:issue_38226_aux.rs +// aux-build:issue-38226-aux.rs // Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty // code gets optimized out: diff --git a/src/test/run-pass/issues/issue-38715.rs b/src/test/run-pass/issues/issue-38715.rs index 9d793147e2475..e3c3a027f3cd0 100644 --- a/src/test/run-pass/issues/issue-38715.rs +++ b/src/test/run-pass/issues/issue-38715.rs @@ -1,6 +1,6 @@ // run-pass -// aux-build:issue_38715.rs -// aux-build:issue_38715-modern.rs +// aux-build:issue-38715.rs +// aux-build:issue-38715-modern.rs // Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!` diff --git a/src/test/run-pass/issues/issue-3979-xcrate.rs b/src/test/run-pass/issues/issue-3979-xcrate.rs index 0e47dee5b65be..fcb1f55c32f9c 100644 --- a/src/test/run-pass/issues/issue-3979-xcrate.rs +++ b/src/test/run-pass/issues/issue-3979-xcrate.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_3979_traits.rs +// aux-build:issue-3979-traits.rs extern crate issue_3979_traits; use issue_3979_traits::{Positioned, Movable}; diff --git a/src/test/run-pass/issues/issue-39823.rs b/src/test/run-pass/issues/issue-39823.rs index 8a52399273b9f..0dfa8a75c4f00 100644 --- a/src/test/run-pass/issues/issue-39823.rs +++ b/src/test/run-pass/issues/issue-39823.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_39823.rs +// aux-build:issue-39823.rs extern crate issue_39823; use issue_39823::{RemoteC, RemoteG}; diff --git a/src/test/run-pass/issues/issue-40469.rs b/src/test/run-pass/issues/issue-40469.rs index 2e8247e032b02..25e08ef85e967 100644 --- a/src/test/run-pass/issues/issue-40469.rs +++ b/src/test/run-pass/issues/issue-40469.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] -include!("auxiliary/issue_40469.rs"); +include!("auxiliary/issue-40469.rs"); fn f() { m!(); } fn main() {} diff --git a/src/test/run-pass/issues/issue-41053.rs b/src/test/run-pass/issues/issue-41053.rs index b9d8f00ff21d6..cd7a0a22623a8 100644 --- a/src/test/run-pass/issues/issue-41053.rs +++ b/src/test/run-pass/issues/issue-41053.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_41053.rs +// aux-build:issue-41053.rs pub trait Trait { fn foo(&self) {} } diff --git a/src/test/run-pass/issues/issue-42007.rs b/src/test/run-pass/issues/issue-42007.rs index de1367ec80f17..a477e476eb9f6 100644 --- a/src/test/run-pass/issues/issue-42007.rs +++ b/src/test/run-pass/issues/issue-42007.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_42007_s.rs +// aux-build:issue-42007-s.rs extern crate issue_42007_s; diff --git a/src/test/run-pass/issue-45510.rs b/src/test/run-pass/issues/issue-45510.rs similarity index 100% rename from src/test/run-pass/issue-45510.rs rename to src/test/run-pass/issues/issue-45510.rs diff --git a/src/test/run-pass/issue-48006.rs b/src/test/run-pass/issues/issue-48006.rs similarity index 100% rename from src/test/run-pass/issue-48006.rs rename to src/test/run-pass/issues/issue-48006.rs diff --git a/src/test/run-pass/issue-53728.rs b/src/test/run-pass/issues/issue-53728.rs similarity index 100% rename from src/test/run-pass/issue-53728.rs rename to src/test/run-pass/issues/issue-53728.rs diff --git a/src/test/run-pass/issue-53843.rs b/src/test/run-pass/issues/issue-53843.rs similarity index 100% rename from src/test/run-pass/issue-53843.rs rename to src/test/run-pass/issues/issue-53843.rs diff --git a/src/test/run-pass/issue-54462-mutable-noalias-correctness.rs b/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs similarity index 100% rename from src/test/run-pass/issue-54462-mutable-noalias-correctness.rs rename to src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs diff --git a/src/test/run-pass/issue-54467.rs b/src/test/run-pass/issues/issue-54467.rs similarity index 100% rename from src/test/run-pass/issue-54467.rs rename to src/test/run-pass/issues/issue-54467.rs diff --git a/src/test/run-pass/issue-55376.rs b/src/test/run-pass/issues/issue-55376.rs similarity index 100% rename from src/test/run-pass/issue-55376.rs rename to src/test/run-pass/issues/issue-55376.rs diff --git a/src/test/run-pass/issue-55380.rs b/src/test/run-pass/issues/issue-55380.rs similarity index 100% rename from src/test/run-pass/issue-55380.rs rename to src/test/run-pass/issues/issue-55380.rs diff --git a/src/test/run-pass/issue-56237.rs b/src/test/run-pass/issues/issue-56237.rs similarity index 100% rename from src/test/run-pass/issue-56237.rs rename to src/test/run-pass/issues/issue-56237.rs diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs new file mode 100644 index 0000000000000..232596334b0ed --- /dev/null +++ b/src/test/run-pass/issues/issue-57924.rs @@ -0,0 +1,9 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) + } +} + +fn main() {} diff --git a/src/test/run-pass/issues/issue-8401.rs b/src/test/run-pass/issues/issue-8401.rs index 97d66c5e40f04..1257bab6c0cd6 100644 --- a/src/test/run-pass/issues/issue-8401.rs +++ b/src/test/run-pass/issues/issue-8401.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_8401.rs +// aux-build:issue-8401.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9123.rs b/src/test/run-pass/issues/issue-9123.rs index 5072ca6ba5374..8c21d06c4776f 100644 --- a/src/test/run-pass/issues/issue-9123.rs +++ b/src/test/run-pass/issues/issue-9123.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9123.rs +// aux-build:issue-9123.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue_9155.rs b/src/test/run-pass/issues/issue-9155.rs similarity index 83% rename from src/test/run-pass/issues/issue_9155.rs rename to src/test/run-pass/issues/issue-9155.rs index 87c453be1420b..4b5c451e853ed 100644 --- a/src/test/run-pass/issues/issue_9155.rs +++ b/src/test/run-pass/issues/issue-9155.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9155.rs +// aux-build:issue-9155.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9188.rs b/src/test/run-pass/issues/issue-9188.rs index d7c39e9d50556..34e61fdf68bc0 100644 --- a/src/test/run-pass/issues/issue-9188.rs +++ b/src/test/run-pass/issues/issue-9188.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9188.rs +// aux-build:issue-9188.rs extern crate issue_9188; diff --git a/src/test/run-pass/issues/issue2170exe.rs b/src/test/run-pass/issues/issue2170exe.rs deleted file mode 100644 index 4169ddf9bb7f7..0000000000000 --- a/src/test/run-pass/issues/issue2170exe.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// aux-build:issue2170lib.rs -// pretty-expanded FIXME #23616 - -extern crate issue2170lib; - -pub fn main() { - // let _ = issue2170lib::rsrc(2); -} diff --git a/src/test/run-pass/rmeta.rs b/src/test/run-pass/rmeta.rs index bd8125bbb5648..cbbdd78dc204b 100644 --- a/src/test/run-pass/rmeta.rs +++ b/src/test/run-pass/rmeta.rs @@ -1,8 +1,8 @@ // Test that using rlibs and rmeta dep crates work together. Specifically, that // there can be both an rmeta and an rlib file and rustc will prefer the rlib. -// aux-build:rmeta_rmeta.rs -// aux-build:rmeta_rlib.rs +// aux-build:rmeta-rmeta.rs +// aux-build:rmeta-rlib.rs extern crate rmeta_aux; use rmeta_aux::Foo; diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs index 0a537071a3c63..556013788c335 100644 --- a/src/test/run-pass/simd/simd-size-align.rs +++ b/src/test/run-pass/simd/simd-size-align.rs @@ -37,6 +37,22 @@ fn main() { check::(); check::(); check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); } #[repr(simd)] struct u8x2(u8, u8); @@ -62,3 +78,19 @@ fn main() { #[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + +#[repr(simd)] struct usizex2(usize, usize); +#[repr(simd)] struct usizex3(usize, usize, usize); +#[repr(simd)] struct usizex4(usize, usize, usize, usize); +#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize); + +#[repr(simd)] struct isizex2(isize, isize); +#[repr(simd)] struct isizex3(isize, isize, isize); +#[repr(simd)] struct isizex4(isize, isize, isize, isize); +#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize); diff --git a/src/test/rustdoc/auxiliary/enum_primitive.rs b/src/test/rustdoc/auxiliary/enum-primitive.rs similarity index 100% rename from src/test/rustdoc/auxiliary/enum_primitive.rs rename to src/test/rustdoc/auxiliary/enum-primitive.rs diff --git a/src/test/rustdoc/auxiliary/reexp_stripped.rs b/src/test/rustdoc/auxiliary/reexp-stripped.rs similarity index 100% rename from src/test/rustdoc/auxiliary/reexp_stripped.rs rename to src/test/rustdoc/auxiliary/reexp-stripped.rs diff --git a/src/test/rustdoc/no-stack-overflow-25295.rs b/src/test/rustdoc/no-stack-overflow-25295.rs index 7e5c0279031b9..dd79f1e4baaa0 100644 --- a/src/test/rustdoc/no-stack-overflow-25295.rs +++ b/src/test/rustdoc/no-stack-overflow-25295.rs @@ -1,5 +1,5 @@ -// ensure this code doesn't stack overflow -// aux-build:enum_primitive.rs +// Ensure this code doesn't stack overflow. +// aux-build:enum-primitive.rs #[macro_use] extern crate enum_primitive; @@ -33,4 +33,3 @@ enum_from_primitive! { Z1,Z2,Z3,Z4,Z5,Z6, } } - diff --git a/src/test/rustdoc/redirect.rs b/src/test/rustdoc/redirect.rs index 65c57ab65bee9..e3a14c7a74a00 100644 --- a/src/test/rustdoc/redirect.rs +++ b/src/test/rustdoc/redirect.rs @@ -1,4 +1,4 @@ -// aux-build:reexp_stripped.rs +// aux-build:reexp-stripped.rs // build-aux-docs // ignore-cross-compile diff --git a/src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_for_crate.rs rename to src/test/ui-fulldeps/auxiliary/lint-for-crate.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_tool_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-tool-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs rename to src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs similarity index 100% rename from src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs rename to src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr similarity index 88% rename from src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr rename to src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr index 37d8b964c2428..b6d5ee0cafef6 100644 --- a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr +++ b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr @@ -1,5 +1,5 @@ error[E0597]: `arena` does not live long enough - --> $DIR/dropck_tarena_cycle_checked.rs:116:8 + --> $DIR/dropck-tarena-cycle-checked.rs:116:8 | LL | f(&arena); | ^^^^^ borrowed value does not live long enough diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs similarity index 100% rename from src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs rename to src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr similarity index 89% rename from src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr rename to src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr index c791b8b451e50..1e612f049837d 100644 --- a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr +++ b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr @@ -1,5 +1,5 @@ error[E0597]: `arena` does not live long enough - --> $DIR/dropck_tarena_unsound_drop.rs:41:8 + --> $DIR/dropck-tarena-unsound-drop.rs:41:8 | LL | f(&arena); | ^^^^^ borrowed value does not live long enough diff --git a/src/test/ui-fulldeps/gated-plugin.rs b/src/test/ui-fulldeps/gated-plugin.rs index a647585e621fe..be1ec0614803b 100644 --- a/src/test/ui-fulldeps/gated-plugin.rs +++ b/src/test/ui-fulldeps/gated-plugin.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs #![plugin(attr_plugin_test)] //~^ ERROR compiler plugins are experimental and possibly buggy diff --git a/src/test/ui-fulldeps/issue-15778-fail.rs b/src/test/ui-fulldeps/issue-15778-fail.rs index 91c379673b3da..75c52fdb4bd28 100644 --- a/src/test/ui-fulldeps/issue-15778-fail.rs +++ b/src/test/ui-fulldeps/issue-15778-fail.rs @@ -1,4 +1,4 @@ -// aux-build:lint_for_crate.rs +// aux-build:lint-for-crate.rs // ignore-stage1 // compile-flags: -D crate-not-okay diff --git a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs index 75e0a8fc31f7c..c9d8654a90974 100644 --- a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs +++ b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_group_plugin_test.rs +// aux-build:lint-group-plugin-test.rs // ignore-stage1 // compile-flags: -D lint-me diff --git a/src/test/ui-fulldeps/lint-group-plugin.rs b/src/test/ui-fulldeps/lint-group-plugin.rs index 7a650afe5f8fa..55a880be0f985 100644 --- a/src/test/ui-fulldeps/lint-group-plugin.rs +++ b/src/test/ui-fulldeps/lint-group-plugin.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_group_plugin_test.rs +// aux-build:lint-group-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs index 21042c5e7d084..8017379ab3d44 100644 --- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -A test-lint diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs index 0dca00040bfe6..fd681536b5b2b 100644 --- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -Z extra-plugins=lint_plugin_test diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs index 65a3623618020..2d424af870707 100644 --- a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs +++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs index b0c4dc0bce516..87324e85b3be7 100644 --- a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -D test-lint diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs index 964fed3b37d11..c7f7f2be99ed5 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs index 07bd785ee7137..91fe3b65be6fc 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -F test-lint diff --git a/src/test/ui-fulldeps/lint-plugin.rs b/src/test/ui-fulldeps/lint-plugin.rs index 031f3b86b1438..5f8bc16301a74 100644 --- a/src/test/ui-fulldeps/lint-plugin.rs +++ b/src/test/ui-fulldeps/lint-plugin.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] #![plugin(lint_plugin_test)] diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs similarity index 66% rename from src/test/ui-fulldeps/lint_tool_cmdline_allow.rs rename to src/test/ui-fulldeps/lint-tool-cmdline-allow.rs index d60f41dd5a327..529f04c6fc4dd 100644 --- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs +++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_tool_test.rs +// aux-build:lint-tool-test.rs // ignore-stage1 // compile-flags: -A test-lint @@ -7,7 +7,6 @@ #![warn(unused)] #![plugin(lint_tool_test)] -fn lintme() { } +fn lintme() {} -pub fn main() { -} +pub fn main() {} diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr similarity index 71% rename from src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr rename to src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr index 9634f1d572fca..1d85101383136 100644 --- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr +++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr @@ -3,21 +3,21 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore = note: requested on the command line with `-A test_lint` warning: item is named 'lintme' - --> $DIR/lint_tool_cmdline_allow.rs:10:1 + --> $DIR/lint-tool-cmdline-allow.rs:10:1 | -LL | fn lintme() { } - | ^^^^^^^^^^^^^^^ +LL | fn lintme() {} + | ^^^^^^^^^^^^^^ | = note: #[warn(clippy::test_lint)] on by default warning: function is never used: `lintme` - --> $DIR/lint_tool_cmdline_allow.rs:10:1 + --> $DIR/lint-tool-cmdline-allow.rs:10:1 | -LL | fn lintme() { } +LL | fn lintme() {} | ^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_cmdline_allow.rs:7:9 + --> $DIR/lint-tool-cmdline-allow.rs:7:9 | LL | #![warn(unused)] | ^^^^^^ diff --git a/src/test/ui-fulldeps/lint_tool_test.rs b/src/test/ui-fulldeps/lint-tool-test.rs similarity index 96% rename from src/test/ui-fulldeps/lint_tool_test.rs rename to src/test/ui-fulldeps/lint-tool-test.rs index 04608b62f43c1..8bd06d1f1e34f 100644 --- a/src/test/ui-fulldeps/lint_tool_test.rs +++ b/src/test/ui-fulldeps/lint-tool-test.rs @@ -1,4 +1,4 @@ -// aux-build:lint_tool_test.rs +// aux-build:lint-tool-test.rs // ignore-stage1 // compile-flags: --cfg foo diff --git a/src/test/ui-fulldeps/lint_tool_test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr similarity index 85% rename from src/test/ui-fulldeps/lint_tool_test.stderr rename to src/test/ui-fulldeps/lint-tool-test.stderr index cec8800a25c7f..67e55e65c7e77 100644 --- a/src/test/ui-fulldeps/lint_tool_test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr @@ -1,5 +1,5 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:8:23 + --> $DIR/lint-tool-test.rs:8:23 | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` @@ -7,19 +7,19 @@ LL | #![cfg_attr(foo, warn(test_lint))] = note: #[warn(renamed_and_removed_lints)] on by default warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:25:9 + --> $DIR/lint-tool-test.rs:25:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` warning: unknown lint: `this_lint_does_not_exist` - --> $DIR/lint_tool_test.rs:27:8 + --> $DIR/lint-tool-test.rs:27:8 | LL | #[deny(this_lint_does_not_exist)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,32 +27,32 @@ LL | #[deny(this_lint_does_not_exist)] = note: #[warn(unknown_lints)] on by default warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:8:23 + --> $DIR/lint-tool-test.rs:8:23 | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` error: item is named 'lintme' - --> $DIR/lint_tool_test.rs:14:1 + --> $DIR/lint-tool-test.rs:14:1 | LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: #[deny(clippy::test_lint)] implied by #[deny(clippy::group)] error: item is named 'lintmetoo' - --> $DIR/lint_tool_test.rs:22:5 + --> $DIR/lint-tool-test.rs:22:5 | LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ diff --git a/src/test/ui-fulldeps/macro-crate-rlib.rs b/src/test/ui-fulldeps/macro-crate-rlib.rs index 21e62171f0f0d..2962bb51fc418 100644 --- a/src/test/ui-fulldeps/macro-crate-rlib.rs +++ b/src/test/ui-fulldeps/macro-crate-rlib.rs @@ -1,4 +1,4 @@ -// aux-build:rlib_crate_test.rs +// aux-build:rlib-crate-test.rs // ignore-tidy-linelength // ignore-cross-compile gives a different error message diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs index 37ac8dfa39101..c671ab581efbe 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs // ignore-cross-compile // // attr_plugin_test will not compile on a cross-compiled target because diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.rs b/src/test/ui-fulldeps/plugin-attr-register-deny.rs index f9922f7f6060e..8be73e330abf7 100644 --- a/src/test/ui-fulldeps/plugin-attr-register-deny.rs +++ b/src/test/ui-fulldeps/plugin-attr-register-deny.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index c1a8e2002be61..31d2c5f318e50 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -29,7 +29,7 @@ LL | baz(&a); | = note: expected type `usize` found type `Bar` - = note: required for the cast to the object type `dyn Foo` + = note: required for the cast to the object type `dyn Foo` error: aborting due to 3 previous errors diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr index 8c0e5570d198d..ad0b6515490b9 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -6,7 +6,7 @@ LL | let _: &I32Iterator = &vec![42].into_iter(); | = note: expected type `u32` found type `i32` - = note: required for the cast to the object type `dyn I32Iterator` + = note: required for the cast to the object type `dyn I32Iterator` error: aborting due to previous error diff --git a/src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs similarity index 100% rename from src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs rename to src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs diff --git a/src/test/ui/auxiliary/define_macro.rs b/src/test/ui/auxiliary/define-macro.rs similarity index 100% rename from src/test/ui/auxiliary/define_macro.rs rename to src/test/ui/auxiliary/define-macro.rs diff --git a/src/test/ui/auxiliary/orphan_check_diagnostics.rs b/src/test/ui/auxiliary/orphan-check-diagnostics.rs similarity index 100% rename from src/test/ui/auxiliary/orphan_check_diagnostics.rs rename to src/test/ui/auxiliary/orphan-check-diagnostics.rs diff --git a/src/test/ui/auxiliary/pub_and_stability.rs b/src/test/ui/auxiliary/pub-and-stability.rs similarity index 100% rename from src/test/ui/auxiliary/pub_and_stability.rs rename to src/test/ui/auxiliary/pub-and-stability.rs diff --git a/src/test/ui/auxiliary/rmeta_meta.rs b/src/test/ui/auxiliary/rmeta-meta.rs similarity index 100% rename from src/test/ui/auxiliary/rmeta_meta.rs rename to src/test/ui/auxiliary/rmeta-meta.rs diff --git a/src/test/ui/auxiliary/rmeta_rlib.rs b/src/test/ui/auxiliary/rmeta-rlib.rs similarity index 100% rename from src/test/ui/auxiliary/rmeta_rlib.rs rename to src/test/ui/auxiliary/rmeta-rlib.rs diff --git a/src/test/ui/auxiliary/stability_cfg2.rs b/src/test/ui/auxiliary/stability-cfg2.rs similarity index 100% rename from src/test/ui/auxiliary/stability_cfg2.rs rename to src/test/ui/auxiliary/stability-cfg2.rs diff --git a/src/test/ui/auxiliary/xc_private_method_lib.rs b/src/test/ui/auxiliary/xc-private-method-lib.rs similarity index 100% rename from src/test/ui/auxiliary/xc_private_method_lib.rs rename to src/test/ui/auxiliary/xc-private-method-lib.rs diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr index 9565888dcc022..51b8474555293 100644 --- a/src/test/ui/bad/bad-sized.stderr +++ b/src/test/ui/bad/bad-sized.stderr @@ -22,7 +22,7 @@ LL | let x: Vec = Vec::new(); | = help: the trait `std::marker::Sized` is not implemented for `dyn Trait` = note: to learn more, visit - = note: required by `>::new` + = note: required by `std::vec::Vec::::new` error: aborting due to 3 previous errors diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 7cd1941d80e83..456a4c18e2b30 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -75,7 +75,7 @@ LL | w.wrap.not_closure(); | = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`? -error[E0599]: no method named `closure` found for type `Obj + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for type `Obj + 'static)>>` in the current scope --> $DIR/issue-2392.rs:62:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 8f8eb38e93873..3762f5e3d6ad8 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -1,22 +1,22 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}` +error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` --> $DIR/const-size_of-cycle.rs:6:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... --> $SRC_DIR/libcore/mem.rs:LL:COL | LL | intrinsics::size_of::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... -note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... --> $DIR/const-size_of-cycle.rs:6:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle + = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle note: cycle used when processing `Foo` --> $DIR/const-size_of-cycle.rs:5:1 | diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr index 1fe3d33322fd1..7ede44c65b83a 100644 --- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr @@ -4,7 +4,7 @@ error[E0493]: destructors cannot be evaluated at compile-time LL | const F: u32 = (U::X, 42).1; | ^^^^^^^^^^ constants cannot evaluate destructors -error: `>::new` is not yet stable as a const fn +error: `std::vec::Vec::::new` is not yet stable as a const fn --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25 | LL | const X: Vec = Vec::new(); diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs new file mode 100644 index 0000000000000..074014908bad4 --- /dev/null +++ b/src/test/ui/consts/union_constant.rs @@ -0,0 +1,11 @@ +// compile-pass + +union Uninit { + _never_use: *const u8, + uninit: (), +} + +const UNINIT: Uninit = Uninit { uninit: () }; + +fn main() {} + diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs index 033d6eebbb219..26271395005a7 100644 --- a/src/test/ui/deprecation/deprecation-lint.rs +++ b/src/test/ui/deprecation/deprecation-lint.rs @@ -314,7 +314,7 @@ mod this_crate { let _ = || { #[deprecated] fn bar() { } - bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar' + bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' }; } diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index 50cbe3846bba6..ffbcb259754e7 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -298,7 +298,7 @@ error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar' +error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' --> $DIR/deprecation-lint.rs:317:13 | LL | bar(); diff --git a/src/test/ui/e0119/auxiliary/issue_23563_a.rs b/src/test/ui/e0119/auxiliary/issue-23563-a.rs similarity index 100% rename from src/test/ui/e0119/auxiliary/issue_23563_a.rs rename to src/test/ui/e0119/auxiliary/issue-23563-a.rs diff --git a/src/test/ui/e0119/issue-23563.rs b/src/test/ui/e0119/issue-23563.rs index a2804fcf1cc55..f578560c552a8 100644 --- a/src/test/ui/e0119/issue-23563.rs +++ b/src/test/ui/e0119/issue-23563.rs @@ -1,4 +1,4 @@ -// aux-build:issue_23563_a.rs +// aux-build:issue-23563-a.rs // Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672 diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs index 2f248bf14c151..383c6868ce2fe 100644 --- a/src/test/ui/enable-unstable-lib-feature.rs +++ b/src/test/ui/enable-unstable-lib-feature.rs @@ -1,6 +1,6 @@ // Test that enabling an unstable feature disables warnings -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs #![feature(unstable_test_feature)] #![deny(non_snake_case)] // To trigger a hard error diff --git a/src/test/ui/explore-issue-38412.rs b/src/test/ui/explore-issue-38412.rs index cd0a69b0d8b8e..e7bcd7c6bfe65 100644 --- a/src/test/ui/explore-issue-38412.rs +++ b/src/test/ui/explore-issue-38412.rs @@ -1,4 +1,4 @@ -// aux-build:pub_and_stability.rs +// aux-build:pub-and-stability.rs #![feature(unused_feature)] @@ -63,5 +63,4 @@ fn main() { t.pub_crate(); //~ ERROR `pub_crate` is private t.pub_mod(); //~ ERROR `pub_mod` is private t.private(); //~ ERROR `private` is private - } diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs new file mode 100644 index 0000000000000..83250052cb506 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features= +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] //~ ERROR + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] //~ ERROR + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr new file mode 100644 index 0000000000000..cce2c4078c242 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.stderr @@ -0,0 +1,21 @@ +error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:4:12 + | +LL | #![feature(rustc_diagnostic_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `lang_items` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:8:12 + | +LL | #![feature(lang_items)] + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs new file mode 100644 index 0000000000000..1cebc8f34f26f --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr new file mode 100644 index 0000000000000..b13560fb81c6a --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.stderr @@ -0,0 +1,9 @@ +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index b936fed85f48e..4e79dfc3f7c01 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}` +error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0` --> $DIR/auto-trait-leak.rs:14:16 | LL | fn cycle1() -> impl Clone { @@ -10,7 +10,7 @@ note: ...which requires processing `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires processing `cycle2::{{impl-Trait}}`... +note: ...which requires processing `cycle2::{{opaque}}#0`... --> $DIR/auto-trait-leak.rs:23:16 | LL | fn cycle2() -> impl Clone { @@ -21,7 +21,7 @@ note: ...which requires processing `cycle2`... LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... - = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle + = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:3:1 | @@ -34,7 +34,7 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}` +error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0` --> $DIR/auto-trait-leak.rs:14:16 | LL | fn cycle1() -> impl Clone { @@ -46,7 +46,7 @@ note: ...which requires processing `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires processing `cycle2::{{impl-Trait}}`... +note: ...which requires processing `cycle2::{{opaque}}#0`... --> $DIR/auto-trait-leak.rs:23:16 | LL | fn cycle2() -> impl Clone { @@ -56,7 +56,7 @@ note: ...which requires processing `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle + = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:3:1 | diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index 95c8c2b0585b6..ceb44ecf7f583 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -12,7 +12,7 @@ pub fn main() { foo!(); assert!({one! two()}); - //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a + //~^ ERROR macros that expand to items //~| ERROR cannot find macro `one!` in this scope //~| ERROR mismatched types diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index d5caf777cd45e..584cdf43a8f4b 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,8 +1,16 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/issue-10536.rs:14:22 | LL | assert!({one! two()}); | ^^ +help: change the delimiters to curly braces + | +LL | assert!({one! two {}}); + | ^^ +help: add a semicolon + | +LL | assert!({one! two();}); + | ^ error: expected `(` or `{`, found `}` --> $DIR/issue-10536.rs:21:22 diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index c993588f55314..da3e2e763af58 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -5,7 +5,7 @@ LL | const FOO: usize = FOO; | ^^^ | = note: ...which again requires processing `FOO`, completing the cycle -note: cycle used when processing `main::{{constant}}` +note: cycle used when processing `main::{{constant}}#0` --> $DIR/issue-17252.rs:4:18 | LL | let _x: [u8; FOO]; // caused stack overflow prior to fix diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr index 72c40ff4b3a0c..ce9af1524b087 100644 --- a/src/test/ui/issues/issue-17651.stderr +++ b/src/test/ui/issues/issue-17651.stderr @@ -6,7 +6,7 @@ LL | (|| Box::new(*(&[0][..])))(); | = help: the trait `std::marker::Sized` is not implemented for `[{integer}]` = note: to learn more, visit - = note: required by `>::new` + = note: required by `std::boxed::Box::::new` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr index f185f49b9b922..e3909e0c1253f 100644 --- a/src/test/ui/issues/issue-17905-2.stderr +++ b/src/test/ui/issues/issue-17905-2.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched method receiver LL | fn say(self: &Pair<&str, isize>) { | ^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Pair<&'_ str, _>` + = note: expected type `Pair<&str, _>` found type `Pair<&str, _>` note: the anonymous lifetime #2 defined on the method body at 8:5... --> $DIR/issue-17905-2.rs:8:5 @@ -27,7 +27,7 @@ error[E0308]: mismatched method receiver LL | fn say(self: &Pair<&str, isize>) { | ^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Pair<&'_ str, _>` + = note: expected type `Pair<&str, _>` found type `Pair<&str, _>` note: the lifetime '_ as defined on the impl at 5:5... --> $DIR/issue-17905-2.rs:5:5 diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index f779fe51bf2d1..89df58dd2dc1b 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -1,10 +1,10 @@ -error[E0277]: the size for values of type `dyn std::iter::Iterator` cannot be known at compilation time +error[E0277]: the size for values of type `dyn std::iter::Iterator` cannot be known at compilation time --> $DIR/issue-20605.rs:2:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator` + = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator` = note: to learn more, visit = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index b2a05551837ce..e20869a6f3a75 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -11,7 +11,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 | @@ -42,7 +42,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the lifetime 'a as defined on the impl at 26:6... --> $DIR/issue-20831-debruijn.rs:26:6 | diff --git a/src/test/ui/issues/issue-22312.stderr b/src/test/ui/issues/issue-22312.stderr index d8987a37f7e46..6a012b214c504 100644 --- a/src/test/ui/issues/issue-22312.stderr +++ b/src/test/ui/issues/issue-22312.stderr @@ -1,4 +1,4 @@ -error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index>::Output>` +error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index>::Output>` --> $DIR/issue-22312.rs:11:24 | LL | let indexer = &(*self as &Index>::Output>); diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr index aff968f3618c1..b60e1c29ec0ee 100644 --- a/src/test/ui/issues/issue-22638.stderr +++ b/src/test/ui/issues/issue-22638.stderr @@ -8,7 +8,7 @@ LL | | a.matches(f) LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="40000000"]` attribute to your crate + = note: consider adding a `#![type_length_limit="26214380"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index 5fa82f8b78635..43effc0b3b974 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,11 +1,11 @@ -error[E0391]: cycle detected when processing `X::A::{{constant}}` +error[E0391]: cycle detected when processing `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires processing `X::A::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `X::A::{{constant}}` + = note: ...which again requires processing `X::A::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index 5b77baed73c3d..707d4fa7ed3f7 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,11 +1,11 @@ -error[E0391]: cycle detected when processing `Y::A::{{constant}}` +error[E0391]: cycle detected when processing `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires processing `Y::A::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `Y::A::{{constant}}` + = note: ...which again requires processing `Y::A::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, diff --git a/src/test/ui/issues/issue-36163.stderr b/src/test/ui/issues/issue-36163.stderr index 94de4c76927a5..4c3f726180dfe 100644 --- a/src/test/ui/issues/issue-36163.stderr +++ b/src/test/ui/issues/issue-36163.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when processing `Foo::B::{{constant}}` +error[E0391]: cycle detected when processing `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, @@ -9,8 +9,8 @@ note: ...which requires processing `A`... | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^ - = note: ...which again requires processing `Foo::B::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `Foo::B::{{constant}}` + = note: ...which again requires processing `Foo::B::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index 24b31f43a85aa..aead415d23f84 100644 --- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&()...` +error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse` --> $DIR/issue-37311.rs:13:5 | LL | / fn recurse(&self) { @@ -6,7 +6,7 @@ LL | | (self, self).recurse(); LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate + = note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/issue-42944.rs b/src/test/ui/issues/issue-42944.rs similarity index 100% rename from src/test/ui/issue-42944.rs rename to src/test/ui/issues/issue-42944.rs diff --git a/src/test/ui/issue-42944.stderr b/src/test/ui/issues/issue-42944.stderr similarity index 100% rename from src/test/ui/issue-42944.stderr rename to src/test/ui/issues/issue-42944.stderr diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr index 3f377fd27e7db..df8e804c87a3f 100644 --- a/src/test/ui/issues/issue-44415.stderr +++ b/src/test/ui/issues/issue-44415.stderr @@ -1,22 +1,22 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}` +error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` --> $DIR/issue-44415.rs:6:17 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^ | -note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... --> $DIR/issue-44415.rs:6:26 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... -note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... --> $DIR/issue-44415.rs:6:17 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^ - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle + = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle note: cycle used when processing `Foo` --> $DIR/issue-44415.rs:5:1 | diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs similarity index 100% rename from src/test/ui/issue-53787-inline-assembler-macro.rs rename to src/test/ui/issues/issue-53787-inline-assembler-macro.rs diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr similarity index 100% rename from src/test/ui/issue-53787-inline-assembler-macro.stderr rename to src/test/ui/issues/issue-53787-inline-assembler-macro.stderr diff --git a/src/test/ui/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs similarity index 100% rename from src/test/ui/issue-54943-1.rs rename to src/test/ui/issues/issue-54943-1.rs diff --git a/src/test/ui/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs similarity index 100% rename from src/test/ui/issue-54943-2.rs rename to src/test/ui/issues/issue-54943-2.rs diff --git a/src/test/ui/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs similarity index 100% rename from src/test/ui/issue-54943-3.rs rename to src/test/ui/issues/issue-54943-3.rs diff --git a/src/test/ui/issue-54943.rs b/src/test/ui/issues/issue-54943.rs similarity index 100% rename from src/test/ui/issue-54943.rs rename to src/test/ui/issues/issue-54943.rs diff --git a/src/test/ui/issue-54943.stderr b/src/test/ui/issues/issue-54943.stderr similarity index 100% rename from src/test/ui/issue-54943.stderr rename to src/test/ui/issues/issue-54943.stderr diff --git a/src/test/ui/issue-55511.nll.stderr b/src/test/ui/issues/issue-55511.nll.stderr similarity index 100% rename from src/test/ui/issue-55511.nll.stderr rename to src/test/ui/issues/issue-55511.nll.stderr diff --git a/src/test/ui/issue-55511.rs b/src/test/ui/issues/issue-55511.rs similarity index 100% rename from src/test/ui/issue-55511.rs rename to src/test/ui/issues/issue-55511.rs diff --git a/src/test/ui/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr similarity index 100% rename from src/test/ui/issue-55511.stderr rename to src/test/ui/issues/issue-55511.stderr diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index c05f8b85d0e98..7cf597d3a98f8 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -16,8 +16,8 @@ LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/issue-55796.rs:21:9 @@ -37,8 +37,8 @@ LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-55846.rs b/src/test/ui/issues/issue-55846.rs similarity index 100% rename from src/test/ui/issue-55846.rs rename to src/test/ui/issues/issue-55846.rs diff --git a/src/test/ui/issues/issue_56411_aux.rs b/src/test/ui/issues/issue-56411-aux.rs similarity index 100% rename from src/test/ui/issues/issue_56411_aux.rs rename to src/test/ui/issues/issue-56411-aux.rs diff --git a/src/test/ui/issues/issue-56411.rs b/src/test/ui/issues/issue-56411.rs index 3561c21cc7ee3..163651a7ef607 100644 --- a/src/test/ui/issues/issue-56411.rs +++ b/src/test/ui/issues/issue-56411.rs @@ -1,6 +1,7 @@ macro_rules! import { - ( $($name:ident),* ) => { + ( $(($path:expr, $name:ident)),* ) => { $( + #[path = $path] mod $name; pub use self::$name; //~^ ERROR the name `issue_56411_aux` is defined multiple times @@ -10,7 +11,7 @@ macro_rules! import { } } -import!(issue_56411_aux); +import!(("issue-56411-aux.rs", issue_56411_aux)); fn main() { println!("Hello, world!"); diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr index dd05852c09159..7b23b3766bed5 100644 --- a/src/test/ui/issues/issue-56411.stderr +++ b/src/test/ui/issues/issue-56411.stderr @@ -1,5 +1,5 @@ error[E0255]: the name `issue_56411_aux` is defined multiple times - --> $DIR/issue-56411.rs:5:21 + --> $DIR/issue-56411.rs:6:21 | LL | mod $name; | ---------- previous definition of the module `issue_56411_aux` here @@ -9,19 +9,19 @@ LL | pub use self::$name; | `issue_56411_aux` reimported here | you can use `as` to change the binding name of the import ... -LL | import!(issue_56411_aux); - | ------------------------- in this macro invocation +LL | import!(("issue-56411-aux.rs", issue_56411_aux)); + | ------------------------------------------------- in this macro invocation | = note: `issue_56411_aux` must be defined only once in the type namespace of this module error[E0365]: `issue_56411_aux` is private, and cannot be re-exported - --> $DIR/issue-56411.rs:5:21 + --> $DIR/issue-56411.rs:6:21 | LL | pub use self::$name; | ^^^^^^^^^^^ re-export of private `issue_56411_aux` ... -LL | import!(issue_56411_aux); - | ------------------------- in this macro invocation +LL | import!(("issue-56411-aux.rs", issue_56411_aux)); + | ------------------------------------------------- in this macro invocation | = note: consider declaring type or module `issue_56411_aux` with `pub` diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs new file mode 100644 index 0000000000000..e98a4d0e491a3 --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where Self::Res: Svc; +//~^ ERROR associated type `Res` not found for `Self` + +fn main() {} diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr new file mode 100644 index 0000000000000..ed1d98c40d18a --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Res` not found for `Self` + --> $DIR/issue-59029-1.rs:5:46 + | +LL | trait MkSvc = Svc where Self::Res: Svc; + | ^^^^^^^^^ associated type `Res` not found + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs new file mode 100644 index 0000000000000..2bdb128d8c4c8 --- /dev/null +++ b/src/test/ui/issues/issue-59029-2.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where >::Res: Svc; + +fn main() {} diff --git a/src/test/ui/lint/auxiliary/stability-cfg2.rs b/src/test/ui/lint/auxiliary/stability-cfg2.rs new file mode 100644 index 0000000000000..8a2899584b903 --- /dev/null +++ b/src/test/ui/lint/auxiliary/stability-cfg2.rs @@ -0,0 +1,5 @@ +// compile-flags:--cfg foo + +#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "0"))] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 8f6425bcc77f6..bf574d7144d06 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -2,7 +2,7 @@ // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs // ignore-tidy-linelength #![warn(deprecated)] #![allow(dead_code, unused_extern_crates)] diff --git a/src/test/ui/lint/lint-stability.rs b/src/test/ui/lint/lint-stability.rs index 6ff79083f46ff..3e4a3874d2c4a 100644 --- a/src/test/ui/lint/lint-stability.rs +++ b/src/test/ui/lint/lint-stability.rs @@ -1,7 +1,7 @@ // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs #![allow(deprecated)] #![allow(dead_code)] diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 22c871dd3c04e..99fa3b9679482 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -462,11 +462,11 @@ note: required by `check` LL | fn check(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}: Impossible` is not satisfied +error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}: Impossible` is not satisfied --> $DIR/namespace-mix.rs:128:5 | LL | check(xm9::TV); - | ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}` + | ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}` | note: required by `check` --> $DIR/namespace-mix.rs:21:1 diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 8e407070342cf..46de13dbbbd9b 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -16,7 +16,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | - - ^^^^^^ assignment requires that `'1` must outlive `'2` | | | | | has type `&'1 i32` - | has type `&mut &'2 i32` + | has type `&'_#2r mut &'2 i32` note: No external requirements --> $DIR/escape-argument-callee.rs:20:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 067bd08220df4..7eb4d96fc5f75 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- has type `std::cell::Cell<&'2 &u32>` + | ---------- ---------- has type `std::cell::Cell<&'2 &'_#3r u32>` | | - | has type `std::cell::Cell<&&'1 u32>` + | has type `std::cell::Cell<&'_#1r &'1 u32>` ... LL | demand_y(x, y, p) | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 5cf37bedb8853..f8b6bfa003b32 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | --------- - has type `&std::cell::Cell<&'1 u32>` + | --------- - has type `&'_#7r std::cell::Cell<&'1 u32>` | | - | has type `&std::cell::Cell<&'2 &u32>` + | has type `&'_#5r std::cell::Cell<&'2 &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 671a8b9a93575..7e7429405fa06 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ---------- ---------- has type `&std::cell::Cell<&'2 &u32>` + | ---------- ---------- has type `&'_#8r std::cell::Cell<&'2 &'_#2r u32>` | | - | has type `&std::cell::Cell<&'1 &u32>` + | has type `&'_#6r std::cell::Cell<&'1 &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/orphan-check-diagnostics.rs b/src/test/ui/orphan-check-diagnostics.rs index 9a29620ae6532..c8803b9ae5d82 100644 --- a/src/test/ui/orphan-check-diagnostics.rs +++ b/src/test/ui/orphan-check-diagnostics.rs @@ -1,5 +1,6 @@ -// aux-build:orphan_check_diagnostics.rs -// see #22388 +// aux-build:orphan-check-diagnostics.rs + +// See issue #22388. extern crate orphan_check_diagnostics; diff --git a/src/test/ui/orphan-check-diagnostics.stderr b/src/test/ui/orphan-check-diagnostics.stderr index 4bd6aa2c154bd..3f868422c7fcb 100644 --- a/src/test/ui/orphan-check-diagnostics.stderr +++ b/src/test/ui/orphan-check-diagnostics.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) - --> $DIR/orphan-check-diagnostics.rs:10:1 + --> $DIR/orphan-check-diagnostics.rs:11:1 | LL | impl RemoteTrait for T where T: LocalTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/out-of-order-shadowing.rs index b4cb6a2383013..a0d1a973764ad 100644 --- a/src/test/ui/out-of-order-shadowing.rs +++ b/src/test/ui/out-of-order-shadowing.rs @@ -1,4 +1,4 @@ -// aux-build:define_macro.rs +// aux-build:define-macro.rs macro_rules! bar { () => {} } define_macro!(bar); diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs index a727cafcab023..3afc275d61a2b 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.rs +++ b/src/test/ui/parser/macros-no-semicolon-items.rs @@ -1,4 +1,15 @@ macro_rules! foo() //~ ERROR semicolon + //~| ERROR unexpected end of macro + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) fn main() { } diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr index a869a53c1eee2..5276aa6f5e9e9 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.stderr +++ b/src/test/ui/parser/macros-no-semicolon-items.stderr @@ -1,8 +1,45 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/macros-no-semicolon-items.rs:1:17 | LL | macro_rules! foo() | ^^ +help: change the delimiters to curly braces + | +LL | macro_rules! foo {} + | ^^ +help: add a semicolon + | +LL | macro_rules! foo(); + | ^ + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ +help: change the delimiters to curly braces + | +LL | bar! { +LL | blah +LL | blah +LL | blah +LL | } + | +help: add a semicolon + | +LL | ); + | ^ + +error: unexpected end of macro invocation + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments -error: aborting due to previous error +error: aborting due to 3 previous errors diff --git a/src/test/ui/privacy/private-inferred-type-3.rs b/src/test/ui/privacy/private-inferred-type-3.rs index d885407a1cd37..39f2e5d4af2aa 100644 --- a/src/test/ui/privacy/private-inferred-type-3.rs +++ b/src/test/ui/privacy/private-inferred-type-3.rs @@ -6,7 +6,7 @@ // error-pattern:type `fn() {::method}` is private // error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private // error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private -// error-pattern:type `for<'r> fn(&'r ext::Pub) {>::priv_method}` is private +// error-pattern:type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private #![feature(decl_macro)] diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr index f8b757ea09820..61cd84762978c 100644 --- a/src/test/ui/privacy/private-inferred-type-3.stderr +++ b/src/test/ui/privacy/private-inferred-type-3.stderr @@ -46,7 +46,7 @@ LL | ext::m!(); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: type `for<'r> fn(&'r ext::Pub) {>::priv_method}` is private +error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private --> $DIR/private-inferred-type-3.rs:16:5 | LL | ext::m!(); diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs index d98cf5991efeb..d9bb421b53f8c 100644 --- a/src/test/ui/privacy/private-inferred-type.rs +++ b/src/test/ui/privacy/private-inferred-type.rs @@ -47,7 +47,7 @@ mod m { PubTupleStruct; //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private Pub(0u8).priv_method(); - //~^ ERROR type `for<'r> fn(&'r m::Pub) {>::priv_method}` is private + //~^ ERROR type `for<'r> fn(&'r m::Pub) {m::Pub::::priv_method}` is private } trait Trait {} diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr index baa98292b67b5..4d40b6b7cab32 100644 --- a/src/test/ui/privacy/private-inferred-type.stderr +++ b/src/test/ui/privacy/private-inferred-type.stderr @@ -151,7 +151,7 @@ LL | PubTupleStruct; LL | m::m!(); | -------- in this macro invocation -error: type `for<'r> fn(&'r m::Pub) {>::priv_method}` is private +error: type `for<'r> fn(&'r m::Pub) {m::Pub::::priv_method}` is private --> $DIR/private-inferred-type.rs:49:18 | LL | Pub(0u8).priv_method(); diff --git a/src/test/ui/proc-macro/auxiliary/issue_38586.rs b/src/test/ui/proc-macro/auxiliary/issue-38586.rs similarity index 100% rename from src/test/ui/proc-macro/auxiliary/issue_38586.rs rename to src/test/ui/proc-macro/auxiliary/issue-38586.rs diff --git a/src/test/ui/proc-macro/auxiliary/issue_50493.rs b/src/test/ui/proc-macro/auxiliary/issue-50493.rs similarity index 100% rename from src/test/ui/proc-macro/auxiliary/issue_50493.rs rename to src/test/ui/proc-macro/auxiliary/issue-50493.rs diff --git a/src/test/ui/proc-macro/issue-38586.rs b/src/test/ui/proc-macro/issue-38586.rs index 4f291ba990ab7..24e88ed93caaf 100644 --- a/src/test/ui/proc-macro/issue-38586.rs +++ b/src/test/ui/proc-macro/issue-38586.rs @@ -1,4 +1,4 @@ -// aux-build:issue_38586.rs +// aux-build:issue-38586.rs #[macro_use] extern crate issue_38586; diff --git a/src/test/ui/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs index f504dbdfce247..eeb08f5eebdcc 100644 --- a/src/test/ui/proc-macro/issue-50493.rs +++ b/src/test/ui/proc-macro/issue-50493.rs @@ -1,4 +1,4 @@ -// aux-build:issue_50493.rs +// aux-build:issue-50493.rs #[macro_use] extern crate issue_50493; diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr index 01b2631a53717..ac5e5e9aabc5b 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 9:18... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18... --> $DIR/regions-addr-of-upvar-self.rs:9:18 | LL | let _f = || { diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr index 9cf0b0ffabde5..be441bc48082e 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let mut f = || &mut x; | ^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 7:21... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21... --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21 | LL | let mut f = || &mut x; diff --git a/src/test/ui/resolve/auxiliary/issue_19452_aux.rs b/src/test/ui/resolve/auxiliary/issue-19452-aux.rs similarity index 100% rename from src/test/ui/resolve/auxiliary/issue_19452_aux.rs rename to src/test/ui/resolve/auxiliary/issue-19452-aux.rs diff --git a/src/test/ui/resolve/auxiliary/issue_3907.rs b/src/test/ui/resolve/auxiliary/issue-3907.rs similarity index 100% rename from src/test/ui/resolve/auxiliary/issue_3907.rs rename to src/test/ui/resolve/auxiliary/issue-3907.rs diff --git a/src/test/ui/resolve/issue-19452.rs b/src/test/ui/resolve/issue-19452.rs index 5c58cabb3cdd8..1d3aa49eac67f 100644 --- a/src/test/ui/resolve/issue-19452.rs +++ b/src/test/ui/resolve/issue-19452.rs @@ -1,4 +1,5 @@ -// aux-build:issue_19452_aux.rs +// aux-build:issue-19452-aux.rs + extern crate issue_19452_aux; enum Homura { diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index ef96fffee926b..56a0e397b854c 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -1,11 +1,11 @@ error[E0423]: expected value, found struct variant `Homura::Madoka` - --> $DIR/issue-19452.rs:9:18 + --> $DIR/issue-19452.rs:10:18 | LL | let homura = Homura::Madoka; | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` - --> $DIR/issue-19452.rs:12:18 + --> $DIR/issue-19452.rs:13:18 | LL | let homura = issue_19452_aux::Homura::Madoka; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? diff --git a/src/test/ui/resolve/issue-3907-2.rs b/src/test/ui/resolve/issue-3907-2.rs index 89e10ca4f2c91..dc9624698dfdd 100644 --- a/src/test/ui/resolve/issue-3907-2.rs +++ b/src/test/ui/resolve/issue-3907-2.rs @@ -1,4 +1,5 @@ -// aux-build:issue_3907.rs +// aux-build:issue-3907.rs + extern crate issue_3907; type Foo = issue_3907::Foo+'static; diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 4fce898dfa96c..968c1f3e463d0 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object - --> $DIR/issue-3907-2.rs:10:1 + --> $DIR/issue-3907-2.rs:11:1 | LL | fn bar(_x: Foo) {} | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object diff --git a/src/test/ui/resolve/issue-3907.rs b/src/test/ui/resolve/issue-3907.rs index a76c3134c0ca3..87e465489a481 100644 --- a/src/test/ui/resolve/issue-3907.rs +++ b/src/test/ui/resolve/issue-3907.rs @@ -1,4 +1,5 @@ -// aux-build:issue_3907.rs +// aux-build:issue-3907.rs + extern crate issue_3907; type Foo = issue_3907::Foo; diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 49f7ae844910e..384df571e2a80 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -1,5 +1,5 @@ error[E0404]: expected trait, found type alias `Foo` - --> $DIR/issue-3907.rs:10:6 + --> $DIR/issue-3907.rs:11:6 | LL | impl Foo for S { | ^^^ type aliases cannot be used as traits diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr index 3c58285bdb352..a1169910ae7e2 100644 --- a/src/test/ui/retslot-cast.stderr +++ b/src/test/ui/retslot-cast.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/retslot-cast.rs:13:5 | LL | inner(x) - | ^^^^^^^^ expected trait `std::iter::Iterator`, found trait `std::iter::Iterator + std::marker::Send` + | ^^^^^^^^ expected trait `std::iter::Iterator`, found trait `std::iter::Iterator + std::marker::Send` | - = note: expected type `std::option::Option<&dyn std::iter::Iterator>` - found type `std::option::Option<&dyn std::iter::Iterator + std::marker::Send>` + = note: expected type `std::option::Option<&dyn std::iter::Iterator>` + found type `std::option::Option<&dyn std::iter::Iterator + std::marker::Send>` error: aborting due to previous error diff --git a/src/test/ui/rmeta-lib-pass.rs b/src/test/ui/rmeta-lib-pass.rs index 6149b1685f5c7..4ab4117dd6ccd 100644 --- a/src/test/ui/rmeta-lib-pass.rs +++ b/src/test/ui/rmeta-lib-pass.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_rlib.rs +// aux-build:rmeta-rlib.rs // no-prefer-dynamic // compile-pass diff --git a/src/test/ui/rmeta-pass.rs b/src/test/ui/rmeta-pass.rs index bcd40144f7216..9c88de7a0330b 100644 --- a/src/test/ui/rmeta-pass.rs +++ b/src/test/ui/rmeta-pass.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // compile-pass diff --git a/src/test/ui/rmeta_lib.rs b/src/test/ui/rmeta_lib.rs index 345b712e37e47..6c74aec32e30b 100644 --- a/src/test/ui/rmeta_lib.rs +++ b/src/test/ui/rmeta_lib.rs @@ -1,4 +1,4 @@ -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found diff --git a/src/test/ui/rmeta_meta_main.rs b/src/test/ui/rmeta_meta_main.rs index df550775ee465..52cd0c2f53fad 100644 --- a/src/test/ui/rmeta_meta_main.rs +++ b/src/test/ui/rmeta_meta_main.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // Check that building a metadata crate finds an error with a dependent, diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs index d1e2efa6a3331..9e4b7e7656055 100644 --- a/src/test/ui/simd-type.rs +++ b/src/test/ui/simd-type.rs @@ -7,7 +7,4 @@ struct empty; //~ ERROR SIMD vector cannot be empty #[repr(simd)] struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous -#[repr(simd)] -struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type - fn main() {} diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr index 027afcb981a0d..48b9916e89d98 100644 --- a/src/test/ui/simd-type.stderr +++ b/src/test/ui/simd-type.stderr @@ -10,13 +10,7 @@ error[E0076]: SIMD vector should be homogeneous LL | struct i64f64(i64, f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type -error[E0077]: SIMD vector element type should be machine type - --> $DIR/simd-type.rs:11:1 - | -LL | struct int4(isize, isize, isize, isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0075, E0076, E0077. +Some errors occurred: E0075, E0076. For more information about an error, try `rustc --explain E0075`. diff --git a/src/test/ui/substs-ppaux.rs b/src/test/ui/substs-ppaux.rs index 7ad7ccb54448f..129ebd43594ce 100644 --- a/src/test/ui/substs-ppaux.rs +++ b/src/test/ui/substs-ppaux.rs @@ -25,7 +25,7 @@ fn foo<'z>() where &'z (): Sized { let x: () = >::bar::<'static, char>; //[verbose]~^ ERROR mismatched types //[verbose]~| expected type `()` - //[verbose]~| found type `fn() {>::bar::}` + //[verbose]~| found type `fn() {>::bar::}` //[normal]~^^^^ ERROR mismatched types //[normal]~| expected type `()` //[normal]~| found type `fn() {>::bar::<'static, char>}` diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr index 9d8a555dffe16..86936475f8c14 100644 --- a/src/test/ui/substs-ppaux.verbose.stderr +++ b/src/test/ui/substs-ppaux.verbose.stderr @@ -14,7 +14,7 @@ LL | let x: () = >::bar::<'static, char>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item | = note: expected type `()` - found type `fn() {>::bar::}` + found type `fn() {>::bar::}` error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:33:17 diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 0000000000000..9bfce11be9ea3 --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,10 @@ +struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +//~^ ERROR missing lifetime specifier + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr new file mode 100644 index 0000000000000..7f5ff95938e30 --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:2:16 + | +LL | struct Foo<'a>(&usize); + | ^ help: consider using the named lifetime: `&'a` + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:34 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:7:35 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/symbol-names/basic.rs b/src/test/ui/symbol-names/basic.rs index 2a051a5e144da..086b903b973b0 100644 --- a/src/test/ui/symbol-names/basic.rs +++ b/src/test/ui/symbol-names/basic.rs @@ -1,6 +1,6 @@ #![feature(rustc_attrs)] #[rustc_symbol_name] //~ ERROR _ZN5basic4main -#[rustc_item_path] //~ ERROR item-path(main) +#[rustc_def_path] //~ ERROR def-path(main) fn main() { } diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr index e23a326d5f889..6ddd93d632e15 100644 --- a/src/test/ui/symbol-names/basic.stderr +++ b/src/test/ui/symbol-names/basic.stderr @@ -4,11 +4,11 @@ error: symbol-name(_ZN5basic4main17h08bcaf310214ed52E) LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(main) +error: def-path(main) --> $DIR/basic.rs:4:1 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 97169c33b8cbf..c712137e828f9 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -6,7 +6,7 @@ mod foo { impl Foo { #[rustc_symbol_name] //~ ERROR _ZN5impl13foo3Foo3bar - #[rustc_item_path] //~ ERROR item-path(foo::Foo::bar) + #[rustc_def_path] //~ ERROR def-path(foo::Foo::bar) fn bar() { } } } @@ -16,7 +16,7 @@ mod bar { impl Foo { #[rustc_symbol_name] //~ ERROR _ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz - #[rustc_item_path] //~ ERROR item-path(bar::::baz) + #[rustc_def_path] //~ ERROR def-path(bar::::baz) fn baz() { } } } diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr index e4fefeb601fe0..eda8646b5b4de 100644 --- a/src/test/ui/symbol-names/impl1.stderr +++ b/src/test/ui/symbol-names/impl1.stderr @@ -4,11 +4,11 @@ error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E) LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(foo::Foo::bar) +error: def-path(foo::Foo::bar) --> $DIR/impl1.rs:9:9 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h38577281258e1527E) --> $DIR/impl1.rs:18:9 @@ -16,11 +16,11 @@ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h385772 LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(bar::::baz) +error: def-path(bar::::baz) --> $DIR/impl1.rs:19:9 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs index bb54669d37df2..cd15f81a61535 100644 --- a/src/test/ui/type_length_limit.rs +++ b/src/test/ui/type_length_limit.rs @@ -1,3 +1,5 @@ +// ignore-musl +// ignore-x86 // error-pattern: reached the type-length limit while instantiating // Test that the type length limit can be changed. diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr index 910eca075948a..9d07c86356b67 100644 --- a/src/test/ui/type_length_limit.stderr +++ b/src/test/ui/type_length_limit.stderr @@ -1,6 +1,10 @@ -error: reached the type-length limit while instantiating `std::mem::drop::>` + --> $SRC_DIR/libcore/mem.rs:LL:COL | - = note: consider adding a `#![type_length_limit="512"]` attribute to your crate +LL | pub fn drop(_x: T) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: consider adding a `#![type_length_limit="1094"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr index f1118709962a4..d41086186f8d7 100644 --- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -7,7 +7,7 @@ LL | *x | ^^ expected (), found trait std::iter::Iterator | = note: expected type `()` - found type `(dyn std::iter::Iterator + 'static)` + found type `(dyn std::iter::Iterator + 'static)` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr index 508c2f780b9fb..ce90f5b9d2486 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output=()>: Eq>` is not satisfied +error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output = ()>: Eq>` is not satisfied --> $DIR/unboxed-closure-sugar-default.rs:21:5 | LL | eq::< Foo<(isize,),isize,Output=()>, Foo(isize) >(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq>` is not implemented for `dyn Foo<(isize,), isize, Output=()>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq>` is not implemented for `dyn Foo<(isize,), isize, Output = ()>` | note: required by `eq` --> $DIR/unboxed-closure-sugar-default.rs:14:1 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr index 071ba2792b0ac..857a32ca69e73 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr @@ -1,9 +1,9 @@ -error[E0277]: the trait bound `dyn Foo<(char,), Output=()>: Eq>` is not satisfied +error[E0277]: the trait bound `dyn Foo<(char,), Output = ()>: Eq>` is not satisfied --> $DIR/unboxed-closure-sugar-equiv.rs:43:5 | LL | / eq::< Foo<(),Output=()>, LL | | Foo(char) >(); - | |___________________________________________________________________^ the trait `Eq>` is not implemented for `dyn Foo<(char,), Output=()>` + | |___________________________________________________________________^ the trait `Eq>` is not implemented for `dyn Foo<(char,), Output = ()>` | note: required by `eq` --> $DIR/unboxed-closure-sugar-equiv.rs:16:1 diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 69a9fd7a60c93..d0475bf08c38d 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -19,8 +19,8 @@ LL | Box::new(items.iter()) | ^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator + 'static)> - found std::boxed::Box> + expected std::boxed::Box<(dyn std::iter::Iterator + 'static)> + found std::boxed::Box> error: aborting due to previous error diff --git a/src/test/ui/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use-from-trait-xc.rs similarity index 100% rename from src/test/ui/auxiliary/use_from_trait_xc.rs rename to src/test/ui/use/auxiliary/use-from-trait-xc.rs diff --git a/src/test/ui/use/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use_from_trait_xc.rs deleted file mode 100644 index 4abe11941b11f..0000000000000 --- a/src/test/ui/use/auxiliary/use_from_trait_xc.rs +++ /dev/null @@ -1,29 +0,0 @@ -pub use self::sub::{Bar, Baz}; - -pub trait Trait { - fn foo(&self); - type Assoc; - const CONST: u32; -} - -struct Foo; - -impl Foo { - pub fn new() {} - - pub const C: u32 = 0; -} - -mod sub { - pub struct Bar; - - impl Bar { - pub fn new() {} - } - - pub enum Baz {} - - impl Baz { - pub fn new() {} - } -} diff --git a/src/test/ui/issue-18986.rs b/src/test/ui/use/issue-18986.rs similarity index 85% rename from src/test/ui/issue-18986.rs rename to src/test/ui/use/issue-18986.rs index 1c431a45ab23e..f0b292f2911c0 100644 --- a/src/test/ui/issue-18986.rs +++ b/src/test/ui/use/issue-18986.rs @@ -1,4 +1,4 @@ -// aux-build:use_from_trait_xc.rs +// aux-build:use-from-trait-xc.rs extern crate use_from_trait_xc; pub use use_from_trait_xc::Trait; diff --git a/src/test/ui/issue-18986.stderr b/src/test/ui/use/issue-18986.stderr similarity index 100% rename from src/test/ui/issue-18986.stderr rename to src/test/ui/use/issue-18986.stderr diff --git a/src/test/ui/use/use-from-trait-xc.rs b/src/test/ui/use/use-from-trait-xc.rs index e6f102f6269a7..695ed66a1c183 100644 --- a/src/test/ui/use/use-from-trait-xc.rs +++ b/src/test/ui/use/use-from-trait-xc.rs @@ -1,4 +1,4 @@ -// aux-build:use_from_trait_xc.rs +// aux-build:use-from-trait-xc.rs extern crate use_from_trait_xc; diff --git a/src/test/ui/useless_comment.rs b/src/test/ui/useless-comment.rs similarity index 100% rename from src/test/ui/useless_comment.rs rename to src/test/ui/useless-comment.rs diff --git a/src/test/ui/useless_comment.stderr b/src/test/ui/useless-comment.stderr similarity index 85% rename from src/test/ui/useless_comment.stderr rename to src/test/ui/useless-comment.stderr index 10d8ee60f99f6..925e307963692 100644 --- a/src/test/ui/useless_comment.stderr +++ b/src/test/ui/useless-comment.stderr @@ -1,5 +1,5 @@ error: unused doc comment - --> $DIR/useless_comment.rs:9:1 + --> $DIR/useless-comment.rs:9:1 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,14 +7,14 @@ LL | mac!(); | ------- rustdoc does not generate documentation for macro expansions | note: lint level defined here - --> $DIR/useless_comment.rs:3:9 + --> $DIR/useless-comment.rs:3:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless_comment.rs:13:5 + --> $DIR/useless-comment.rs:13:5 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let x = 12; | ----------- rustdoc does not generate documentation for statements error: unused doc comment - --> $DIR/useless_comment.rs:16:5 + --> $DIR/useless-comment.rs:16:5 | LL | / /// multi-line LL | | /// doc comment @@ -36,7 +36,7 @@ LL | | } | |_____- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:20:9 + --> $DIR/useless-comment.rs:20:9 | LL | /// c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | 1 => {}, | ------- rustdoc does not generate documentation for match arms error: unused doc comment - --> $DIR/useless_comment.rs:25:5 + --> $DIR/useless-comment.rs:25:5 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | unsafe {} | --------- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:28:5 + --> $DIR/useless-comment.rs:28:5 | LL | #[doc = "foo"] | ^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | 3; | - rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:29:5 + --> $DIR/useless-comment.rs:29:5 | LL | #[doc = "bar"] | ^^^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL | 3; | - rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:32:5 + --> $DIR/useless-comment.rs:32:5 | LL | /// bar | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,13 +79,13 @@ LL | mac!(); = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless_comment.rs:35:13 + --> $DIR/useless-comment.rs:35:13 | LL | let x = /** comment */ 47; | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:37:5 + --> $DIR/useless-comment.rs:37:5 | LL | /// dox | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/xc-private-method.rs b/src/test/ui/xc-private-method.rs index 157249194a345..e95cab93d750e 100644 --- a/src/test/ui/xc-private-method.rs +++ b/src/test/ui/xc-private-method.rs @@ -1,4 +1,4 @@ -// aux-build:xc_private_method_lib.rs +// aux-build:xc-private-method-lib.rs extern crate xc_private_method_lib; diff --git a/src/test/ui/xc-private-method2.rs b/src/test/ui/xc-private-method2.rs index 6d73570318ae8..f11b251082bf2 100644 --- a/src/test/ui/xc-private-method2.rs +++ b/src/test/ui/xc-private-method2.rs @@ -1,4 +1,4 @@ -// aux-build:xc_private_method_lib.rs +// aux-build:xc-private-method-lib.rs extern crate xc_private_method_lib; diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index d44a51a9635e9..058f2df624b55 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -23,6 +23,10 @@ static HOSTS: &'static [&'static str] = &[ "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", @@ -32,6 +36,7 @@ static HOSTS: &'static [&'static str] = &[ "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", ]; @@ -77,6 +82,10 @@ static TARGETS: &'static [&'static str] = &[ "mips-unknown-linux-musl", "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "nvptx64-nvidia-cuda", diff --git a/src/tools/cargo b/src/tools/cargo index 95b45eca19ac7..0e35bd8af0ec7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 95b45eca19ac785263fed98ecefe540bb47337ac +Subproject commit 0e35bd8af0ec72d3225c4819b330b94628f0e9d0 diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index c54035cdec510..50dce4b55ae86 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -48,7 +48,15 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("mips64", "mips64"), ("mips64el", "mips64"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("mipsel", "mips"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("msp430", "msp430"), ("nvptx64", "nvptx64"), ("powerpc", "powerpc"), diff --git a/src/tools/miri b/src/tools/miri index e3527fdba7178..72b4ee0381dec 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit e3527fdba7178120a6398e76aa4b3908b10ef85e +Subproject commit 72b4ee0381decf609204e5548c1f5e79bdfb18b7