diff options
931 files changed, 9033 insertions, 4261 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c296a28e90..e3767df2808 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -421,7 +421,7 @@ Here are those same steps in detail: These instructions are specific to updating `rustfmt`, however they may apply to the other submodules as well. Please help by improving these instructions -if you find any discrepencies or special cases that need to be addressed. +if you find any discrepancies or special cases that need to be addressed. To update the `rustfmt` submodule, start by running the appropriate [`git submodule` command](https://git-scm.com/book/en/v2/Git-Tools-Submodules). diff --git a/RELEASES.md b/RELEASES.md index 7a3b097611e..57434ebc1f6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,13 +1,17 @@ -Version 1.22.0 (2017-11-23) +Version 1.22.1 (2017-11-22) +========================== + +- [Update Cargo to fix an issue with macOS 10.13 "High Sierra"][46183] + +[46183]: https://github.com/rust-lang/rust/pull/46183 + +Version 1.22.0 (2017-11-22) ========================== Language -------- - [`non_snake_case` lint now allows extern no-mangle functions][44966] - [Now accepts underscores in unicode escapes][43716] -- [`#![feature(const_fn)]` is now no longer required for - calling const functions.][43017] It's still required for creating - constant functions. - [`T op= &T` now works for numeric types.][44287] eg. `let mut x = 2; x += &8;` - [types that impl `Drop` are now allowed in `const` and `static` types][44456] @@ -45,8 +49,8 @@ Cargo Misc ---- - [`libbacktrace` is now available on Apple platforms.][44251] -- [Stabilised the `compile_fail` attribute for code fences.][43949] This now - lets you specify that a given code example will fail to compile. +- [Stabilised the `compile_fail` attribute for code fences in doc-comments.][43949] + This now lets you specify that a given code example will fail to compile. Compatibility Notes ------------------- @@ -624,7 +628,7 @@ Misc ---- - [rustdoc can now use pulldown-cmark with the `--enable-commonmark` flag][40338] -- [Added rust-winbg script for better debugging on Windows][39983] +- [Added rust-windbg script for better debugging on Windows][39983] - [Rust now uses the official cross compiler for NetBSD][40612] - [rustdoc now accepts `#` at the start of files][40828] - [Fixed jemalloc support for musl][41168] @@ -1658,7 +1662,7 @@ Diagnostics ----------- * [Replace macro backtraces with labeled local uses][35702] -* [Improve error message for missplaced doc comments][33922] +* [Improve error message for misplaced doc comments][33922] * [Buffer unix and lock windows to prevent message interleaving][35975] * [Update lifetime errors to specifically note temporaries][36171] * [Special case a few colors for Windows][36178] @@ -1966,7 +1970,7 @@ Language useful](https://github.com/rust-lang/rust/pull/34908) * [`macro_rules!` `stmt` matchers correctly consume the entire contents when inside non-braces invocations](https://github.com/rust-lang/rust/pull/34886) -* [Semicolons are properly required as statement delimeters inside +* [Semicolons are properly required as statement delimiters inside `macro_rules!` invocations](https://github.com/rust-lang/rust/pull/34660) * [`cfg_attr` works on `path` attributes](https://github.com/rust-lang/rust/pull/34546) @@ -2191,7 +2195,7 @@ Compatibility Notes * [`const`s and `static`s may not have unsized types](https://github.com/rust-lang/rust/pull/34443) * [The new follow-set rules that place restrictions on `macro_rules!` in order to ensure syntax forward-compatibility have been enabled](https://github.com/rust-lang/rust/pull/33982) - This was an [ammendment to RFC 550](https://github.com/rust-lang/rfcs/pull/1384), + This was an [amendment to RFC 550](https://github.com/rust-lang/rfcs/pull/1384), and has been a warning since 1.10. * [`cfg` attribute process has been refactored to fix various bugs](https://github.com/rust-lang/rust/pull/33706). This causes breakage in some corner cases. @@ -3348,7 +3352,7 @@ Libraries * `FromStr` is [implemented for `SockAddrV4` and `SockAddrV6`][1.5s]. * There are now `From` conversions [between floating point types][1.5f] where the conversions are lossless. -* Thera are now `From` conversions [between integer types][1.5i] where +* There are now `From` conversions [between integer types][1.5i] where the conversions are lossless. * [`fs::Metadata` implements `Clone`][1.5fs]. * The `parse` method [accepts a leading "+" when parsing @@ -3548,7 +3552,7 @@ Libraries * [`IntoIterator` is implemented for references to `Option` and `Result`][into2]. * [`HashMap` and `HashSet` implement `Extend<&T>` where `T: - Copy`][ext] as part of [RFC 839]. This will cause type inferance + Copy`][ext] as part of [RFC 839]. This will cause type inference breakage in rare situations. * [`BinaryHeap` implements `Debug`][bh2]. * [`Borrow` and `BorrowMut` are implemented for fixed-size @@ -3559,7 +3563,7 @@ Libraries * `&mut T` where `T: std::fmt::Write` [also implements `std::fmt::Write`][mutw]. * [A stable regression in `VecDeque::push_back` and other - capicity-altering methods that caused panics for zero-sized types + capacity-altering methods that caused panics for zero-sized types was fixed][vd]. * [Function pointers implement traits for up to 12 parameters][fp2]. @@ -3746,7 +3750,7 @@ Libraries [better for long data][sh]. * [`AtomicPtr`] implements [`Send`]. * The [`read_to_end`] implementations for [`Stdin`] and [`File`] - are now [specialized to use uninitalized buffers for increased + are now [specialized to use uninitialized buffers for increased performance][rte]. * Lifetime parameters of foreign functions [are now resolved properly][f]. @@ -3875,7 +3879,7 @@ Highlights * This is the first release with [experimental support for linking with the MSVC linker and lib C on Windows (instead of using the GNU variants via MinGW)][win]. It is yet recommended only for the most - intrepid Rusticians. + intrepid Rustaceans. * Benchmark compilations are showing a 30% improvement in bootstrapping over 1.1. @@ -4741,7 +4745,7 @@ Version 0.11.0 (2014-07-02) * Libraries * The standard library is now a "facade" over a number of underlying libraries. This means that development on the standard library should - be speeder due to smaller crates, as well as a clearer line between + be speedier due to smaller crates, as well as a clearer line between all dependencies. * A new library, libcore, lives under the standard library's facade which is Rust's "0-assumption" library, suitable for embedded and diff --git a/src/Cargo.lock b/src/Cargo.lock index d0d6271acd7..729cce118ff 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1505,6 +1505,15 @@ dependencies = [ ] [[package]] +name = "rls-data" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "rls-rustc" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1869,7 +1878,7 @@ name = "rustc_save_analysis" version = "0.0.0" dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-data 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-data 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2737,6 +2746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum rls-analysis 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b961e7270b2084839ede4d2788167086b24bc9cf09c9e955cc851afaf116054" "checksum rls-data 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48257ceade23c2e01a3ca8d2fc4226101b107f6a3c868f829cf3fd2f204a1fe6" +"checksum rls-data 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff85bb3a0daf9f64207a5530d90ae1c10f5515cef064c88b6821090678382b44" "checksum rls-rustc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b21ea952e9bf1569929abf1bb920262cde04b7b1b26d8e0260286302807299d2" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd34691a510938bb67fe0444fb363103c73ffb31c121d1e16bc92d8945ea8ff" diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 16a23eb364a..8325b1d2a27 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -183,7 +183,8 @@ fn main() { if env::var("RUSTC_SAVE_ANALYSIS") == Ok("api".to_string()) { cmd.arg("-Zsave-analysis"); cmd.env("RUST_SAVE_ANALYSIS_CONFIG", - "{\"output_file\": null,\"full_docs\": false,\"pub_only\": true,\ + "{\"output_file\": null,\"full_docs\": false,\ + \"pub_only\": true,\"reachable_only\": false,\ \"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}"); } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b202df76f7c..888aa4449f8 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -624,9 +624,7 @@ impl<'a> Builder<'a> { cargo.arg("--release"); } - if mode != Mode::Libstd && // FIXME(#45320) - mode != Mode::Libtest && // FIXME(#45511) - self.config.rust_codegen_units.is_none() && + if self.config.rust_codegen_units.is_none() && self.build.is_rust_llvm(compiler.host) { cargo.env("RUSTC_THINLTO", "1"); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 9f7e3de9dc0..95be9a396c1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1168,7 +1168,12 @@ impl Step for Rustfmt { compiler: builder.compiler(stage, build.build), target }).expect("Rustfmt to build: toolstate is testing"); + let cargofmt = builder.ensure(tool::Cargofmt { + compiler: builder.compiler(stage, build.build), + target + }).expect("Cargofmt to build: toolstate is testing"); install(&rustfmt, &image.join("bin"), 0o755); + install(&cargofmt, &image.join("bin"), 0o755); let doc = image.join("share/doc/rustfmt"); install(&src.join("README.md"), &doc, 0o644); install(&src.join("LICENSE-MIT"), &doc, 0o644); diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index 72a5d1338b8..fa3ba02482f 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -185,7 +185,7 @@ pub unsafe fn setup(build: &mut Build) { 0, FALSE, DUPLICATE_SAME_ACCESS); // If this failed, well at least we tried! An example of DuplicateHandle - // failing in the past has been when the wrong python2 package spawed this + // failing in the past has been when the wrong python2 package spawned this // build system (e.g. the `python2` package in MSYS instead of // `mingw-w64-x86_64-python2`. Not sure why it failed, but the "failure // mode" here is that we only clean everything up when the build system diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 8b23be69a85..bc275b7fc74 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -78,7 +78,7 @@ pub fn check(build: &mut Build) { } let mut cmd_finder = Finder::new(); - // If we've got a git directory we're gona need git to update + // If we've got a git directory we're gonna need git to update // submodules and learn about various other aspects. if build.rust_info.is_git() { cmd_finder.must_have("git"); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 7175fed5410..9b16ca0980a 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -403,71 +403,66 @@ impl Step for Cargo { } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Clippy { - pub compiler: Compiler, - pub target: Interned<String>, -} +macro_rules! tool_extended { + (($sel:ident, $builder:ident), + $($name:ident, + $toolstate:ident, + $path:expr, + $tool_name:expr, + $extra_deps:block;)+) => { + $( + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + pub struct $name { + pub compiler: Compiler, + pub target: Interned<String>, + } -impl Step for Clippy { - type Output = Option<PathBuf>; - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; + impl Step for $name { + type Output = Option<PathBuf>; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; - fn should_run(run: ShouldRun) -> ShouldRun { - let builder = run.builder; - run.path("src/tools/clippy").default_condition(builder.build.config.extended) - } + fn should_run(run: ShouldRun) -> ShouldRun { + let builder = run.builder; + run.path($path).default_condition(builder.build.config.extended) + } - fn make_run(run: RunConfig) { - run.builder.ensure(Clippy { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), - target: run.target, - }); + fn make_run(run: RunConfig) { + run.builder.ensure($name { + compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), + target: run.target, + }); + } + + fn run($sel, $builder: &Builder) -> Option<PathBuf> { + $extra_deps + let toolstate = $builder.build.config.toolstate.$toolstate; + $builder.ensure(ToolBuild { + compiler: $sel.compiler, + target: $sel.target, + tool: $tool_name, + mode: Mode::Librustc, + path: $path, + expectation: toolstate.passes(ToolState::Compiling), + }) + } + } + )+ } +} - fn run(self, builder: &Builder) -> Option<PathBuf> { +tool_extended!((self, builder), + Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {}; + Clippy, clippy, "src/tools/clippy", "clippy-driver", { // Clippy depends on procedural macros (serde), which requires a full host // compiler to be available, so we need to depend on that. builder.ensure(compile::Rustc { compiler: self.compiler, target: builder.build.build, }); - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "clippy-driver", - mode: Mode::Librustc, - path: "src/tools/clippy", - expectation: builder.build.config.toolstate.clippy.passes(ToolState::Compiling), - }) - } -} - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Rls { - pub compiler: Compiler, - pub target: Interned<String>, -} - -impl Step for Rls { - type Output = Option<PathBuf>; - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun) -> ShouldRun { - let builder = run.builder; - run.path("src/tools/rls").default_condition(builder.build.config.extended) - } - - fn make_run(run: RunConfig) { - run.builder.ensure(Rls { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder) -> Option<PathBuf> { + }; + Miri, miri, "src/tools/miri", "miri", {}; + Rls, rls, "src/tools/rls", "rls", { builder.ensure(native::Openssl { target: self.target, }); @@ -477,87 +472,9 @@ impl Step for Rls { compiler: self.compiler, target: builder.build.build, }); - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "rls", - mode: Mode::Librustc, - path: "src/tools/rls", - expectation: builder.build.config.toolstate.rls.passes(ToolState::Compiling), - }) - } -} - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Rustfmt { - pub compiler: Compiler, - pub target: Interned<String>, -} - -impl Step for Rustfmt { - type Output = Option<PathBuf>; - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun) -> ShouldRun { - let builder = run.builder; - run.path("src/tools/rustfmt").default_condition(builder.build.config.extended) - } - - fn make_run(run: RunConfig) { - run.builder.ensure(Rustfmt { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder) -> Option<PathBuf> { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "rustfmt", - mode: Mode::Librustc, - path: "src/tools/rustfmt", - expectation: builder.build.config.toolstate.rustfmt.passes(ToolState::Compiling), - }) - } -} - - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Miri { - pub compiler: Compiler, - pub target: Interned<String>, -} - -impl Step for Miri { - type Output = Option<PathBuf>; - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun) -> ShouldRun { - let build_miri = run.builder.build.config.test_miri; - run.path("src/tools/miri").default_condition(build_miri) - } - - fn make_run(run: RunConfig) { - run.builder.ensure(Miri { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder) -> Option<PathBuf> { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "miri", - mode: Mode::Librustc, - path: "src/tools/miri", - expectation: builder.build.config.toolstate.miri.passes(ToolState::Compiling), - }) - } -} + }; + Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", {}; +); impl<'a> Builder<'a> { /// Get a `Command` which is ready to run `tool` in `stage` built for diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 922deba7367..8d4dbc39998 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -36,14 +36,14 @@ a Docker image. 1. Select the "default" virtual machine inside VirtualBox, then click "Settings" - 2. Go to "Shared Folders", click "Add shared foldrer" (the folder icon with + 2. Go to "Shared Folders", click "Add shared folder" (the folder icon with a plus sign), fill in the following information, then click "OK": * Folder path: `E:\rust` * Folder name: `e/rust` * Read-only: ☐ *unchecked* * Auto-mount: ☑ *checked* - * Make Permanant: ☑ *checked* + * Make Permanent: ☑ *checked* 3. VirtualBox might not support creating symbolic links inside a shared folder by default. You can enable it manually by running these from `cmd.exe`: diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 9e1b769f6c4..5b4314d57e6 100755 --- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -52,7 +52,7 @@ curl $URL/2017-03-17-netbsd-comp.tgz | \ cd usr/src # The options, in order, do the following -# * this is an unpriviledged build +# * this is an unprivileged build # * output to a predictable location # * disable various uneeded stuff MKUNPRIVED=yes TOOLDIR=/x-tools/x86_64-unknown-netbsd \ diff --git a/src/ci/run.sh b/src/ci/run.sh index a8a7dd5bc27..ffb3532f497 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -37,7 +37,7 @@ if [ "$DIST_SRC" = "" ]; then fi # If we're deploying artifacts then we set the release channel, otherwise if -# we're not deploying then we want to be sure to enable all assertions becauase +# we're not deploying then we want to be sure to enable all assertions because # we'll be running tests # # FIXME: need a scheme for changing this `nightly` value to `beta` and `stable` diff --git a/src/doc/book b/src/doc/book -Subproject 7db393dae740d84775b73f403123c866e94e3a5 +Subproject 3944d61149fa234ea991b498d4dac4fcec68a80 diff --git a/src/doc/nomicon b/src/doc/nomicon -Subproject 1625e0b8c870891b84b0969777a974bf87be579 +Subproject cfb1f2d7e5eb6143915d5a63afe4cf58e8531c2 diff --git a/src/doc/reference b/src/doc/reference -Subproject 36adc6ae504c6e0343ab5d7b3871f0a2a71236d +Subproject 857f2c97c8075d39fa07eb4a404980519faa600 diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 8e8e2a7ff1d..e51c63cf008 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -279,7 +279,7 @@ $ rustdoc README.md --markdown-playground-url https://play.rust-lang.org/ ``` When rendering a Markdown file, this flag gives the base URL of the Rust -Playround, to use for generating `Run` buttons. +Playground, to use for generating `Run` buttons. ## `--markdown-no-toc`: don't generate a table of contents @@ -291,7 +291,7 @@ $ rustdoc README.md --markdown-no-toc ``` When generating documentation from a Markdown file, by default, `rustdoc` will -generate a table of contents. This flag supresses that, and no TOC will be +generate a table of contents. This flag suppresses that, and no TOC will be generated. diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 9c6b86d6ddc..e5a603a3709 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -50,7 +50,7 @@ running them. Here's the full algorithm rustdoc uses to preprocess examples: 5. Finally, if the example does not contain `fn main`, the remainder of the text is wrapped in `fn main() { your_code }`. -For more about that caveat in rule 4, see "Documeting Macros" below. +For more about that caveat in rule 4, see "Documenting Macros" below. ## Hiding portions of the example diff --git a/src/doc/unstable-book/src/language-features/doc-spotlight.md b/src/doc/unstable-book/src/language-features/doc-spotlight.md new file mode 100644 index 00000000000..8117755fef1 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/doc-spotlight.md @@ -0,0 +1,30 @@ +# `doc_spotlight` + +The tracking issue for this feature is: [#45040] + +The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute, +to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]` +attribute to a trait definition will make rustdoc print extra information for functions which return +a type that implements that trait. This attribute is applied to the `Iterator`, `io::Read`, and +`io::Write` traits in the standard library. + +You can do this on your own traits, like this: + +``` +#![feature(doc_spotlight)] + +#[doc(spotlight)] +pub trait MyTrait {} + +pub struct MyStruct; +impl MyTrait for MyStruct {} + +/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`, +/// without having to write that yourself! +pub fn my_fn() -> MyStruct { MyStruct } +``` + +This feature was originally implemented in PR [#45039]. + +[#45040]: https://github.com/rust-lang/rust/issues/45040 +[#45039]: https://github.com/rust-lang/rust/pull/45039 diff --git a/src/doc/unstable-book/src/language-features/external-doc.md b/src/doc/unstable-book/src/language-features/external-doc.md new file mode 100644 index 00000000000..effae5d2999 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/external-doc.md @@ -0,0 +1,40 @@ +# `external_doc` + +The tracking issue for this feature is: [#44732] + +The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to +include external files in documentation. Use the attribute in place of, or in addition to, regular +doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders +documentation for your crate. + +With the following files in the same directory: + +`external-doc.md`: + +```markdown +# My Awesome Type + +This is the documentation for this spectacular type. +``` + +`lib.rs`: + +```no_run (needs-external-files) +#![feature(external_doc)] + +#[doc(include = "external-doc.md")] +pub struct MyAwesomeType; +``` + +`rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType` +struct. + +When locating files, `rustdoc` will base paths in the `src/` directory, as if they were alongside the +`lib.rs` for your crate. So if you want a `docs/` folder to live alongside the `src/` directory, +start your paths with `../docs/` for `rustdoc` to properly find the file. + +This feature was proposed in [RFC #1990] and initially implemented in PR [#44781]. + +[#44732]: https://github.com/rust-lang/rust/issues/44732 +[RFC #1990]: https://github.com/rust-lang/rfcs/pull/1990 +[#44781]: https://github.com/rust-lang/rust/pull/44781 diff --git a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md index 97b57c690fc..5c8124c9c6b 100644 --- a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md +++ b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md @@ -10,7 +10,7 @@ The `optin_builtin_traits` feature gate allows you to define auto traits. Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits that are automatically implemented for every type, unless the type, or a type it contains, -has explictly opted out via a negative impl. +has explicitly opted out via a negative impl. [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html diff --git a/src/doc/unstable-book/src/language-features/unboxed-closures.md b/src/doc/unstable-book/src/language-features/unboxed-closures.md index 0eaed7a1989..d845c99a88a 100644 --- a/src/doc/unstable-book/src/language-features/unboxed-closures.md +++ b/src/doc/unstable-book/src/language-features/unboxed-closures.md @@ -9,7 +9,7 @@ See Also: [`fn_traits`](library-features/fn-traits.html) ---- The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI, -required for implmenting the [`Fn*`] family of traits. `"rust-call"` functions must have +required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have exactly one (non self) argument, a tuple representing the argument list. [`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html diff --git a/src/etc/installer/exe/modpath.iss b/src/etc/installer/exe/modpath.iss index 35cc0097035..2cfc8698c4b 100644 --- a/src/etc/installer/exe/modpath.iss +++ b/src/etc/installer/exe/modpath.iss @@ -144,7 +144,7 @@ begin end; end; -// Split a string into an array using passed delimeter +// Split a string into an array using passed delimiter procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); var i: Integer; diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 9481cd4e1a4..fc0a3c0fd88 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1328,7 +1328,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> fmt::Pointer for Arc<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Pointer::fmt(&self.ptr, f) + fmt::Pointer::fmt(&(&**self as *const T), f) } } diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2226cee6e36..0343787d0c0 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -374,6 +374,59 @@ impl<T: ?Sized> Box<T> { unique }; } + + /// Consumes and leaks the `Box`, returning a mutable reference, + /// `&'a mut T`. Here, the lifetime `'a` may be chosen to be `'static`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the program's life. Dropping the returned reference will cause a memory + /// leak. If this is not acceptable, the reference should first be wrapped + /// with the [`Box::from_raw`] function producing a `Box`. This `Box` can + /// then be dropped which will properly destroy `T` and release the + /// allocated memory. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Box::leak(b)` instead of `b.leak()`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// [`Box::from_raw`]: struct.Box.html#method.from_raw + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// #![feature(box_leak)] + /// + /// fn main() { + /// let x = Box::new(41); + /// let static_ref: &'static mut usize = Box::leak(x); + /// *static_ref += 1; + /// assert_eq!(*static_ref, 42); + /// } + /// ``` + /// + /// Unsized data: + /// + /// ``` + /// #![feature(box_leak)] + /// + /// fn main() { + /// let x = vec![1, 2, 3].into_boxed_slice(); + /// let static_ref = Box::leak(x); + /// static_ref[0] = 4; + /// assert_eq!(*static_ref, [4, 2, 3]); + /// } + /// ``` + #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", + issue = "46179")] + #[inline] + pub fn leak<'a>(b: Box<T>) -> &'a mut T + where + T: 'a // Technically not needed, but kept to be explicit. + { + unsafe { &mut *Box::into_raw(b) } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 58299d5d836..7148a1143fd 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Utilities for formatting and printing `String`s +//! Utilities for formatting and printing `String`s. //! //! This module contains the runtime support for the [`format!`] syntax extension. //! This macro is implemented in the compiler to emit calls to this module in @@ -536,7 +536,7 @@ use string; /// assert_eq!(s, "Hello, world!"); /// ``` /// -/// Please note that using [`format!`] might be preferrable. +/// Please note that using [`format!`] might be preferable. /// Example: /// /// ``` diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index c2a3019515f..472eef77d79 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -72,7 +72,7 @@ macro_rules! vec { /// Creates a `String` using interpolation of runtime expressions. /// -/// The first argument `format!` recieves is a format string. This must be a string +/// The first argument `format!` receives is a format string. This must be a string /// literal. The power of the formatting string is in the `{}`s contained. /// /// Additional parameters passed to `format!` replace the `{}`s within the diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 2f8620cc750..58f08fd8bc1 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -346,7 +346,7 @@ impl<T> Rc<T> { unsafe { let val = ptr::read(&*this); // copy the contained object - // Indicate to Weaks that they can't be promoted by decrememting + // Indicate to Weaks that they can't be promoted by decrementing // the strong count, and then remove the implicit "strong weak" // pointer while also handling drop logic by just crafting a // fake Weak. @@ -1072,7 +1072,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Rc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> fmt::Pointer for Rc<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Pointer::fmt(&self.ptr, f) + fmt::Pointer::fmt(&(&**self as *const T), f) } } diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index b41cb912fe7..7e3d2af79ce 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1468,9 +1468,9 @@ impl<T> [T] { core_slice::SliceExt::copy_from_slice(self, src) } - /// Swaps all elements in `self` with those in `src`. + /// Swaps all elements in `self` with those in `other`. /// - /// The length of `src` must be the same as `self`. + /// The length of `other` must be the same as `self`. /// /// # Panics /// @@ -1481,16 +1481,16 @@ impl<T> [T] { /// ``` /// #![feature(swap_with_slice)] /// - /// let mut src = [1, 2, 3]; - /// let mut dst = [7, 8, 9]; + /// let mut slice1 = [1, 2, 3]; + /// let mut slice2 = [7, 8, 9]; /// - /// src.swap_with_slice(&mut dst); - /// assert_eq!(src, [7, 8, 9]); - /// assert_eq!(dst, [1, 2, 3]); + /// slice1.swap_with_slice(&mut slice2); + /// assert_eq!(slice1, [7, 8, 9]); + /// assert_eq!(slice2, [1, 2, 3]); /// ``` #[unstable(feature = "swap_with_slice", issue = "44030")] - pub fn swap_with_slice(&mut self, src: &mut [T]) { - core_slice::SliceExt::swap_with_slice(self, src) + pub fn swap_with_slice(&mut self, other: &mut [T]) { + core_slice::SliceExt::swap_with_slice(self, other) } /// Copies `self` into a new `Vec`. diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f68ee847eb3..6e8515f0b36 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -1734,7 +1734,7 @@ impl str { /// A more complex pattern, using a closure: /// /// ``` - /// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX"); + /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 25fcc1ccdab..cd0f4a22e9c 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -596,7 +596,7 @@ impl String { /// Decode a UTF-16 encoded vector `v` into a `String`, returning [`Err`] /// if `v` contains any invalid data. /// - /// [`Err`]: ../../std/result/enum.Result.htlm#variant.Err + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// /// # Examples /// diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs new file mode 100644 index 00000000000..d3ce12056bb --- /dev/null +++ b/src/liballoc/tests/heap.rs @@ -0,0 +1,45 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use alloc_system::System; +use std::heap::{Heap, Alloc, Layout}; + +/// https://github.com/rust-lang/rust/issues/45955 +/// +/// Note that `#[global_allocator]` is not used, +/// so `liballoc_jemalloc` is linked (on some platforms). +#[test] +fn alloc_system_overaligned_request() { + check_overalign_requests(System) +} + +#[test] +fn std_heap_overaligned_request() { + check_overalign_requests(Heap) +} + +fn check_overalign_requests<T: Alloc>(mut allocator: T) { + let size = 8; + let align = 16; // greater than size + let iterations = 100; + unsafe { + let pointers: Vec<_> = (0..iterations).map(|_| { + allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() + }).collect(); + for &ptr in &pointers { + assert_eq!((ptr as usize) % align, 0, "Got a pointer less aligned than requested") + } + + // Clean up + for &ptr in &pointers { + allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + } + } +} diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 00ebd88d464..f1e95883b38 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -10,6 +10,8 @@ #![deny(warnings)] +#![feature(allocator_api)] +#![feature(alloc_system)] #![feature(attr_literals)] #![feature(box_syntax)] #![feature(inclusive_range_syntax)] @@ -29,6 +31,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] +extern crate alloc_system; extern crate std_unicode; extern crate rand; @@ -39,6 +42,7 @@ mod binary_heap; mod btree; mod cow_str; mod fmt; +mod heap; mod linked_list; mod slice; mod str; diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 6b075e7ac0e..a14a5d32738 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1427,12 +1427,12 @@ mod pattern { Reject(6, 7), Match (7, 7), ]); - make_test!(str_searcher_mulibyte_haystack, " ", "├──", [ + make_test!(str_searcher_multibyte_haystack, " ", "├──", [ Reject(0, 3), Reject(3, 6), Reject(6, 9), ]); - make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [ + make_test!(str_searcher_empty_needle_multibyte_haystack, "", "├──", [ Match (0, 0), Reject(0, 3), Match (3, 3), @@ -1455,7 +1455,7 @@ mod pattern { Match (5, 6), Reject(6, 7), ]); - make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [ + make_test!(char_searcher_multibyte_haystack, ' ', "├──", [ Reject(0, 3), Reject(3, 6), Reject(6, 9), diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 5aca199cf40..c29449a241e 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1089,7 +1089,7 @@ impl<T> Vec<T> { // Memory safety // // When the Drain is first created, it shortens the length of - // the source vector to make sure no uninitalized or moved-from elements + // the source vector to make sure no uninitialized or moved-from elements // are accessible at all if the Drain's destructor never gets to run. // // Drain will ptr::read out the values to remove. diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index f060f6d79c1..d7370ae400d 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -72,8 +72,7 @@ mod contents { const MALLOCX_ZERO: c_int = 0x40; // The minimum alignment guaranteed by the architecture. This value is used to - // add fast paths for low alignment values. In practice, the alignment is a - // constant at the call site and the branch will be optimized out. + // add fast paths for low alignment values. #[cfg(all(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))] @@ -92,8 +91,8 @@ mod contents { a.trailing_zeros() as c_int } - fn align_to_flags(align: usize) -> c_int { - if align <= MIN_ALIGN { + fn align_to_flags(align: usize, size: usize) -> c_int { + if align <= MIN_ALIGN && align <= size { 0 } else { mallocx_align(align) @@ -111,7 +110,7 @@ mod contents { pub unsafe extern fn __rde_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8 { - let flags = align_to_flags(align); + let flags = align_to_flags(align, size); let ptr = mallocx(size as size_t, flags) as *mut u8; if ptr.is_null() { let layout = Layout::from_size_align_unchecked(size, align); @@ -132,7 +131,7 @@ mod contents { pub unsafe extern fn __rde_dealloc(ptr: *mut u8, size: usize, align: usize) { - let flags = align_to_flags(align); + let flags = align_to_flags(align, size); sdallocx(ptr as *mut c_void, size, flags); } @@ -142,7 +141,7 @@ mod contents { min: *mut usize, max: *mut usize) { let layout = &*(layout as *const Layout); - let flags = align_to_flags(layout.align()); + let flags = align_to_flags(layout.align(), layout.size()); let size = nallocx(layout.size(), flags) as usize; *min = layout.size(); if size > 0 { @@ -166,7 +165,7 @@ mod contents { return 0 as *mut u8 } - let flags = align_to_flags(new_align); + let flags = align_to_flags(new_align, new_size); let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8; if ptr.is_null() { let layout = Layout::from_size_align_unchecked(new_size, new_align); @@ -181,10 +180,10 @@ mod contents { pub unsafe extern fn __rde_alloc_zeroed(size: usize, align: usize, err: *mut u8) -> *mut u8 { - let ptr = if align <= MIN_ALIGN { + let ptr = if align <= MIN_ALIGN && align <= size { calloc(size as size_t, 1) as *mut u8 } else { - let flags = align_to_flags(align) | MALLOCX_ZERO; + let flags = align_to_flags(align, size) | MALLOCX_ZERO; mallocx(size as size_t, flags) as *mut u8 }; if ptr.is_null() { @@ -203,7 +202,7 @@ mod contents { err: *mut u8) -> *mut u8 { let p = __rde_alloc(size, align, err); if !p.is_null() { - let flags = align_to_flags(align); + let flags = align_to_flags(align, size); *excess = nallocx(size, flags) as usize; } return p @@ -220,7 +219,7 @@ mod contents { err: *mut u8) -> *mut u8 { let p = __rde_realloc(ptr, old_size, old_align, new_size, new_align, err); if !p.is_null() { - let flags = align_to_flags(new_align); + let flags = align_to_flags(new_align, new_size); *excess = nallocx(new_size, flags) as usize; } p @@ -244,7 +243,7 @@ mod contents { new_size: usize, new_align: usize) -> u8 { if old_align == new_align { - let flags = align_to_flags(new_align); + let flags = align_to_flags(new_align, new_size); (xallocx(ptr as *mut c_void, new_size, 0, flags) == new_size) as u8 } else { 0 diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 05cacf6e881..27259cc31a5 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -25,8 +25,7 @@ #![rustc_alloc_kind = "lib"] // The minimum alignment guaranteed by the architecture. This value is used to -// add fast paths for low alignment values. In practice, the alignment is a -// constant at the call site and the branch will be optimized out. +// add fast paths for low alignment values. #[cfg(all(any(target_arch = "x86", target_arch = "arm", target_arch = "mips", @@ -132,7 +131,7 @@ mod platform { unsafe impl<'a> Alloc for &'a System { #[inline] unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - let ptr = if layout.align() <= MIN_ALIGN { + let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { libc::malloc(layout.size()) as *mut u8 } else { aligned_malloc(&layout) @@ -148,7 +147,7 @@ mod platform { unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - if layout.align() <= MIN_ALIGN { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { let ptr = libc::calloc(layout.size(), 1) as *mut u8; if !ptr.is_null() { Ok(ptr) @@ -180,7 +179,7 @@ mod platform { }) } - if new_layout.align() <= MIN_ALIGN { + if new_layout.align() <= MIN_ALIGN && new_layout.align() <= new_layout.size(){ let ptr = libc::realloc(ptr as *mut libc::c_void, new_layout.size()); if !ptr.is_null() { Ok(ptr as *mut u8) diff --git a/src/libbacktrace/configure b/src/libbacktrace/configure index 873220794bd..8bdb29d2560 100755 --- a/src/libbacktrace/configure +++ b/src/libbacktrace/configure @@ -14584,7 +14584,7 @@ func_basename () # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value retuned in "$func_basename_result" +# value returned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. diff --git a/src/libbacktrace/ltmain.sh b/src/libbacktrace/ltmain.sh index eaef55a5933..eff9e62be8a 100644 --- a/src/libbacktrace/ltmain.sh +++ b/src/libbacktrace/ltmain.sh @@ -177,7 +177,7 @@ basename="s,^.*/,," # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value retuned in "$func_basename_result" +# value returned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins -Subproject f5532b22b5d741f3ea207b5b07e3e1ca63476f9 +Subproject 02b3734a5ba6de984eb5a02c50860cc014e58d5 diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e2d61890c30..897222747f5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -261,6 +261,14 @@ pub struct Formatter<'a> { struct Void { _priv: (), + /// Erases all oibits, because `Void` erases the type of the object that + /// will be used to produce formatted output. Since we do not know what + /// oibits the real types have (and they can have any or none), we need to + /// take the most conservative approach and forbid all oibits. + /// + /// It was added after #45197 showed that one could share a `!Sync` + /// object across threads by passing it into `format_args!`. + _oibit_remover: PhantomData<*mut Fn()>, } /// This struct represents the generic "argument" which is taken by the Xprintf @@ -952,7 +960,7 @@ pub trait UpperExp { /// assert_eq!(output, "Hello world!"); /// ``` /// -/// Please note that using [`write!`] might be preferrable. Example: +/// Please note that using [`write!`] might be preferable. Example: /// /// ``` /// use std::fmt::Write; diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 40298389c1a..7f6d627536d 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -30,6 +30,7 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ `.iter()` or a similar method"] +#[doc(spotlight)] pub trait Iterator { /// The type of the elements being iterated over. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4a57417e86a..631b9f98589 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -107,6 +107,24 @@ #![feature(const_unsafe_cell_new)] #![feature(const_cell_new)] #![feature(const_nonzero_new)] +#![cfg_attr(not(stage0), feature(doc_spotlight))] + +#![cfg_attr(not(stage0), feature(const_min_value))] +#![cfg_attr(not(stage0), feature(const_max_value))] +#![cfg_attr(not(stage0), feature(const_atomic_bool_new))] +#![cfg_attr(not(stage0), feature(const_atomic_isize_new))] +#![cfg_attr(not(stage0), feature(const_atomic_usize_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i8_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u8_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i16_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u16_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i32_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u32_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i64_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u64_new))] +#![cfg_attr(not(stage0), feature(const_unsafe_cell_new))] +#![cfg_attr(not(stage0), feature(const_cell_new))] +#![cfg_attr(not(stage0), feature(const_nonzero_new))] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index c410c2d9004..122baec8e58 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -361,7 +361,7 @@ macro_rules! try { }) } -/// Write formatted data into a buffer +/// Write formatted data into a buffer. /// /// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be /// formatted according to the specified format string and the result will be passed to the writer. diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index e0efdbcd4c7..70ef4487334 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -150,7 +150,7 @@ //! [`Sub`]: trait.Sub.html //! [`Mul`]: trait.Mul.html //! [`clone`]: ../clone/trait.Clone.html#tymethod.clone -//! [operator precedence]: ../../reference/expressions/operator-expr.html#operator-precedence +//! [operator precedence]: ../../reference/expressions.html#expression-precedence #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 523a244c836..db3aa9a1efa 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -498,9 +498,7 @@ define_dep_nodes!( <'tcx> [] IsAutoImpl(DefId), [] ImplTraitRef(DefId), [] ImplPolarity(DefId), - [] ClosureKind(DefId), [] FnSignature(DefId), - [] GenSignature(DefId), [] CoerceUnsizedInfo(DefId), [] ItemVarianceConstraints(DefId), diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 015cdd11bbd..32f40367fab 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -659,6 +659,39 @@ impl DepGraph { }).unwrap_or(false) } + // This method loads all on-disk cacheable query results into memory, so + // they can be written out to the new cache file again. Most query results + // will already be in memory but in the case where we marked something as + // green but then did not need the value, that value will never have been + // loaded from disk. + // + // This method will only load queries that will end up in the disk cache. + // Other queries will not be executed. + pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { + let green_nodes: Vec<DepNode> = { + let data = self.data.as_ref().unwrap(); + data.colors.borrow().iter().filter_map(|(dep_node, color)| match color { + DepNodeColor::Green(_) => { + if dep_node.cache_on_disk(tcx) { + Some(*dep_node) + } else { + None + } + } + DepNodeColor::Red => { + // We can skip red nodes because a node can only be marked + // as red if the query result was recomputed and thus is + // already in memory. + None + } + }).collect() + }; + + for dep_node in green_nodes { + dep_node.load_from_on_disk_cache(tcx); + } + } + pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) { debug!("mark_loaded_from_cache({:?}, {})", self.data.as_ref().unwrap().current.borrow().nodes[dep_node_index], diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index bab3bded77b..8089a88a9e8 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1969,8 +1969,39 @@ fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { ``` "##, +E0644: r##" +A closure or generator was constructed that references its own type. + +Erroneous example: + +```compile-fail,E0644 +fn fix<F>(f: &F) + where F: Fn(&F) +{ + f(&f); } +fn main() { + fix(&|y| { + // Here, when `x` is called, the parameter `y` is equal to `x`. + }); +} +``` + +Rust does not permit a closure to directly reference its own type, +either through an argument (as in the example above) or by capturing +itself through its environment. This restriction helps keep closure +inference tractable. + +The easiest fix is to rewrite your closure into a top-level function, +or into a method. In some cases, you may also be able to have your +closure call itself by capturing a `&Fn()` object or `fn()` pointer +that refers to itself. That is permitting, since the closure would be +invoking itself via a virtual call, and hence does not directly +reference its own *type*. + +"##, } + register_diagnostics! { // E0006 // merged with E0005 @@ -2019,4 +2050,7 @@ register_diagnostics! { E0628, // generators cannot have explicit arguments E0631, // type mismatch in closure arguments E0637, // "'_" is not a valid lifetime bound + E0657, // `impl Trait` can only capture lifetimes bound at the fn level + E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax + E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index f6fcff37ca5..8858023ec1d 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -17,8 +17,8 @@ use std::u32; newtype_index!(CrateNum { - derive[Debug] ENCODABLE = custom + DEBUG_FORMAT = "crate{}", /// Item definitions in the currently-compiled crate would have the CrateNum /// LOCAL_CRATE in their DefId. @@ -172,17 +172,19 @@ pub struct DefId { impl fmt::Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DefId {{ krate: {:?}, index: {:?}", - self.krate, self.index)?; + write!(f, "DefId({:?}/{}:{}", + self.krate.index(), + self.index.address_space().index(), + self.index.as_array_index())?; ty::tls::with_opt(|opt_tcx| { if let Some(tcx) = opt_tcx { - write!(f, " => {}", tcx.def_path_debug_str(*self))?; + write!(f, " ~ {}", tcx.def_path_debug_str(*self))?; } Ok(()) })?; - write!(f, " }}") + write!(f, ")") } } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 84be68cb197..c9d35158ed0 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -591,8 +591,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { } visitor.visit_lifetime(lifetime); } - TyImplTraitExistential(ref bounds) => { + TyImplTraitExistential(ref existty, ref lifetimes) => { + let ExistTy { ref generics, ref bounds } = *existty; + walk_generics(visitor, generics); walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_lifetime, lifetimes); } TyImplTraitUniversal(_, ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8c9d1a38e70..7fd6f4a8b42 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -42,8 +42,9 @@ use dep_graph::DepGraph; use hir; -use hir::map::{Definitions, DefKey}; -use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX}; +use hir::HirVec; +use hir::map::{Definitions, DefKey, DefPathData}; +use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace}; use hir::def::{Def, PathResolution}; use lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES; use middle::cstore::CrateStore; @@ -52,7 +53,7 @@ use session::Session; use util::common::FN_OUTPUT_NAME; use util::nodemap::{DefIdMap, FxHashMap, NodeMap}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::fmt::Debug; use std::iter; use std::mem; @@ -105,6 +106,26 @@ pub struct LoweringContext<'a> { is_in_loop_condition: bool, is_in_trait_impl: bool, + // Used to create lifetime definitions from in-band lifetime usages. + // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8` + // When a named lifetime is encountered in a function or impl header and + // has not been defined + // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added + // to this list. The results of this list are then added to the list of + // lifetime definitions in the corresponding impl or function generics. + lifetimes_to_define: Vec<(Span, Name)>, + // Whether or not in-band lifetimes are being collected. This is used to + // indicate whether or not we're in a place where new lifetimes will result + // in in-band lifetime definitions, such a function or an impl header. + // This will always be false unless the `in_band_lifetimes` feature is + // enabled. + is_collecting_in_band_lifetimes: bool, + // Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB. + // When `is_collectin_in_band_lifetimes` is true, each lifetime is checked + // against this list to see if it is already in-scope, or if a definition + // needs to be created for it. + in_scope_lifetimes: Vec<Name>, + type_def_lifetime_params: DefIdMap<usize>, current_hir_id_owner: Vec<(DefIndex, u32)>, @@ -176,6 +197,9 @@ pub fn lower_crate(sess: &Session, node_id_to_hir_id: IndexVec::new(), is_generator: false, is_in_trait_impl: false, + lifetimes_to_define: Vec::new(), + is_collecting_in_band_lifetimes: false, + in_scope_lifetimes: Vec::new(), }.lower_crate(krate) } @@ -270,13 +294,23 @@ impl<'a> LoweringContext<'a> { }); if item_lowered { - if let ItemKind::Impl(_,_,_,_,ref opt_trait_ref,_,_) = item.node { - self.with_trait_impl_ref(opt_trait_ref, |this| { - visit::walk_item(this, item) - }); - } else { - visit::walk_item(self, item); - } + let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node { + hir::Item_::ItemImpl(_,_,_,ref generics,..) | + hir::Item_::ItemTrait(_,_,ref generics,..) => + generics.lifetimes.clone(), + _ => Vec::new().into(), + }; + + self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| { + let this = &mut ItemLowerer { lctx: this }; + if let ItemKind::Impl(_,_,_,_,ref opt_trait_ref,_,_) = item.node { + this.with_trait_impl_ref(opt_trait_ref, |this| { + visit::walk_item(this, item) + }); + } else { + visit::walk_item(this, item); + } + }); } } @@ -489,6 +523,124 @@ impl<'a> LoweringContext<'a> { span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } + // Creates a new hir::LifetimeDef for every new lifetime encountered + // while evaluating `f`. Definitions are created with the parent provided. + // If no `parent_id` is provided, no definitions will be returned. + fn collect_in_band_lifetime_defs<T, F>( + &mut self, + parent_id: Option<DefId>, + f: F + ) -> (Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T + { + assert!(!self.is_collecting_in_band_lifetimes); + assert!(self.lifetimes_to_define.is_empty()); + self.is_collecting_in_band_lifetimes = self.sess.features.borrow().in_band_lifetimes; + + let res = f(self); + + self.is_collecting_in_band_lifetimes = false; + + let lifetimes_to_define = self.lifetimes_to_define.split_off(0); + + let lifetime_defs = match parent_id { + Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| { + let def_node_id = self.next_id().node_id; + + // Add a definition for the in-band lifetime def + self.resolver.definitions().create_def_with_parent( + parent_id.index, + def_node_id, + DefPathData::LifetimeDef(name.as_str()), + DefIndexAddressSpace::High, + Mark::root() + ); + + hir::LifetimeDef { + lifetime: hir::Lifetime { + id: def_node_id, + span, + name: hir::LifetimeName::Name(name), + }, + bounds: Vec::new().into(), + pure_wrt_drop: false, + in_band: true, + } + }).collect(), + None => Vec::new(), + }; + + (lifetime_defs, res) + } + + // Evaluates `f` with the lifetimes in `lt_defs` in-scope. + // This is used to track which lifetimes have already been defined, and + // which are new in-band lifetimes that need to have a definition created + // for them. + fn with_in_scope_lifetime_defs<T, F>( + &mut self, + lt_defs: &[LifetimeDef], + f: F + ) -> T where F: FnOnce(&mut LoweringContext) -> T + { + let old_len = self.in_scope_lifetimes.len(); + let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.ident.name); + self.in_scope_lifetimes.extend(lt_def_names); + + let res = f(self); + + self.in_scope_lifetimes.truncate(old_len); + res + } + + // Same as the method above, but accepts `hir::LifetimeDef`s + // instead of `ast::LifetimeDef`s. + // This should only be used with generics that have already had their + // in-band lifetimes added. In practice, this means that this function is + // only used when lowering a child item of a trait or impl. + fn with_parent_impl_lifetime_defs<T, F>( + &mut self, + lt_defs: &[hir::LifetimeDef], + f: F + ) -> T where F: FnOnce(&mut LoweringContext) -> T + { + let old_len = self.in_scope_lifetimes.len(); + let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name()); + self.in_scope_lifetimes.extend(lt_def_names); + + let res = f(self); + + self.in_scope_lifetimes.truncate(old_len); + res + } + + // Appends in-band lifetime defs to the existing set of out-of-band lifetime defs. + // Evaluates all within the context of the out-of-band defs. + // If provided, `impl_item_id` is used to find the parent impls of impl items so + // that their generics are not duplicated. + fn add_in_band_lifetime_defs<F, T>( + &mut self, + generics: &Generics, + parent_id: Option<DefId>, + f: F + ) -> (hir::Generics, T) + where F: FnOnce(&mut LoweringContext) -> T + { + let (in_band_defs, (mut lowered_generics, res)) = + self.with_in_scope_lifetime_defs(&generics.lifetimes, |this| { + this.collect_in_band_lifetime_defs(parent_id, |this| { + (this.lower_generics(generics), f(this)) + }) + }); + + lowered_generics.lifetimes = + lowered_generics.lifetimes + .iter().cloned() + .chain(in_band_defs.into_iter()) + .collect(); + + (lowered_generics, res) + } + fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T where F: FnOnce(&mut LoweringContext) -> T { @@ -709,13 +861,14 @@ impl<'a> LoweringContext<'a> { hir::TyRptr(lifetime, self.lower_mt(mt, itctx)) } TyKind::BareFn(ref f) => { - hir::TyBareFn(P(hir::BareFnTy { - lifetimes: self.lower_lifetime_defs(&f.lifetimes), - unsafety: self.lower_unsafety(f.unsafety), - abi: f.abi, - decl: self.lower_fn_decl(&f.decl, None, false), - arg_names: self.lower_fn_args_to_names(&f.decl), - })) + self.with_in_scope_lifetime_defs(&f.lifetimes, |this| + hir::TyBareFn(P(hir::BareFnTy { + lifetimes: this.lower_lifetime_defs(&f.lifetimes), + unsafety: this.lower_unsafety(f.unsafety), + abi: f.abi, + decl: this.lower_fn_decl(&f.decl, None, false), + arg_names: this.lower_fn_args_to_names(&f.decl), + }))) } TyKind::Never => hir::TyNever, TyKind::Tup(ref tys) => { @@ -777,7 +930,24 @@ impl<'a> LoweringContext<'a> { t.span, GateIssue::Language, "`impl Trait` in return position is experimental"); } - hir::TyImplTraitExistential(self.lower_bounds(bounds, itctx)) + let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap(); + let hir_bounds = self.lower_bounds(bounds, itctx); + let (lifetimes, lifetime_defs) = + self.lifetimes_from_impl_trait_bounds(def_index, &hir_bounds); + + hir::TyImplTraitExistential(hir::ExistTy { + generics: hir::Generics { + lifetimes: lifetime_defs, + // Type parameters are taken from environment: + ty_params: Vec::new().into(), + where_clause: hir::WhereClause { + id: self.next_id().node_id, + predicates: Vec::new().into(), + }, + span: t.span, + }, + bounds: hir_bounds, + }, lifetimes) }, ImplTraitContext::Universal(def_id) => { let has_feature = self.sess.features.borrow().universal_impl_trait; @@ -808,6 +978,112 @@ impl<'a> LoweringContext<'a> { }) } + fn lifetimes_from_impl_trait_bounds( + &mut self, + parent_index: DefIndex, + bounds: &hir::TyParamBounds + ) -> (HirVec<hir::Lifetime>, HirVec<hir::LifetimeDef>) { + + // This visitor walks over impl trait bounds and creates defs for all lifetimes which + // appear in the bounds, excluding lifetimes that are created within the bounds. + // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>` + struct ImplTraitLifetimeCollector<'r, 'a: 'r> { + context: &'r mut LoweringContext<'a>, + parent: DefIndex, + currently_bound_lifetimes: Vec<Name>, + already_defined_lifetimes: HashSet<Name>, + output_lifetimes: Vec<hir::Lifetime>, + output_lifetime_defs: Vec<hir::LifetimeDef>, + } + + impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> { + fn nested_visit_map<'this>(&'this mut self) + -> hir::intravisit::NestedVisitorMap<'this, 'v> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_poly_trait_ref(&mut self, + polytr: &'v hir::PolyTraitRef, + _: hir::TraitBoundModifier) { + let old_len = self.currently_bound_lifetimes.len(); + + // Record the introduction of 'a in `for<'a> ...` + for lt_def in &polytr.bound_lifetimes { + // Introduce lifetimes one at a time so that we can handle + // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd> ...` + if let hir::LifetimeName::Name(name) = lt_def.lifetime.name { + self.currently_bound_lifetimes.push(name); + } + + // Visit the lifetime bounds + for lt_bound in <_def.bounds { + self.visit_lifetime(<_bound); + } + } + + hir::intravisit::walk_trait_ref(self, &polytr.trait_ref); + + self.currently_bound_lifetimes.truncate(old_len); + } + + fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) { + // Exclude '_, 'static, and elided lifetimes (there should be no elided lifetimes) + if let hir::LifetimeName::Name(lifetime_name) = lifetime.name { + if !self.currently_bound_lifetimes.contains(&lifetime_name) && + !self.already_defined_lifetimes.contains(&lifetime_name) + { + self.already_defined_lifetimes.insert(lifetime_name); + let name = hir::LifetimeName::Name(lifetime_name); + + self.output_lifetimes.push(hir::Lifetime { + id: self.context.next_id().node_id, + span: lifetime.span, + name, + }); + + let def_node_id = self.context.next_id().node_id; + self.context.resolver.definitions().create_def_with_parent( + self.parent, + def_node_id, + DefPathData::LifetimeDef(lifetime_name.as_str()), + DefIndexAddressSpace::High, + Mark::root() + ); + let def_lifetime = hir::Lifetime { + id: def_node_id, + span: lifetime.span, + name, + }; + self.output_lifetime_defs.push(hir::LifetimeDef { + lifetime: def_lifetime, + bounds: Vec::new().into(), + pure_wrt_drop: false, + in_band: false, + }); + } + } + } + } + + let mut lifetime_collector = ImplTraitLifetimeCollector { + context: self, + parent: parent_index, + currently_bound_lifetimes: Vec::new(), + already_defined_lifetimes: HashSet::new(), + output_lifetimes: Vec::new(), + output_lifetime_defs: Vec::new(), + }; + + for bound in bounds { + hir::intravisit::walk_ty_param_bound(&mut lifetime_collector, &bound); + } + + ( + lifetime_collector.output_lifetimes.into(), + lifetime_collector.output_lifetime_defs.into() + ) + } + fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, @@ -1221,23 +1497,44 @@ impl<'a> LoweringContext<'a> { } fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { + let name = match self.lower_ident(l.ident) { + x if x == "'_" => hir::LifetimeName::Underscore, + x if x == "'static" => hir::LifetimeName::Static, + name => { + if self.is_collecting_in_band_lifetimes && + !self.in_scope_lifetimes.contains(&name) && + self.lifetimes_to_define.iter() + .find(|&&(_, lt_name)| lt_name == name) + .is_none() + { + self.lifetimes_to_define.push((l.span, name)); + } + + hir::LifetimeName::Name(name) + } + }; + hir::Lifetime { id: self.lower_node_id(l.id).node_id, - name: match self.lower_ident(l.ident) { - x if x == "'_" => hir::LifetimeName::Underscore, - x if x == "'static" => hir::LifetimeName::Static, - name => hir::LifetimeName::Name(name), - }, + name, span: l.span, } } fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef { - hir::LifetimeDef { + let was_collecting_in_band = self.is_collecting_in_band_lifetimes; + self.is_collecting_in_band_lifetimes = false; + + let def = hir::LifetimeDef { lifetime: self.lower_lifetime(&l.lifetime), bounds: self.lower_lifetimes(&l.bounds), pure_wrt_drop: l.attrs.iter().any(|attr| attr.check_name("may_dangle")), - } + in_band: false, + }; + + self.is_collecting_in_band_lifetimes = was_collecting_in_band; + + def } fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> { @@ -1312,15 +1609,19 @@ impl<'a> LoweringContext<'a> { ref bounded_ty, ref bounds, span}) => { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes), - bounded_ty: self.lower_ty(bounded_ty, ImplTraitContext::Disallowed), - bounds: bounds.iter().filter_map(|bound| match *bound { - // Ignore `?Trait` bounds, they were copied into type parameters already. - TraitTyParamBound(_, TraitBoundModifier::Maybe) => None, - _ => Some(self.lower_ty_param_bound(bound, ImplTraitContext::Disallowed)) - }).collect(), - span, + self.with_in_scope_lifetime_defs(bound_lifetimes, |this| { + hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + bound_lifetimes: this.lower_lifetime_defs(bound_lifetimes), + bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed), + bounds: bounds.iter().filter_map(|bound| match *bound { + // Ignore `?Trait` bounds. + // Tthey were copied into type parameters already. + TraitTyParamBound(_, TraitBoundModifier::Maybe) => None, + _ => Some(this.lower_ty_param_bound( + bound, ImplTraitContext::Disallowed)) + }).collect(), + span, + }) }) } WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, @@ -1381,9 +1682,13 @@ impl<'a> LoweringContext<'a> { p: &PolyTraitRef, itctx: ImplTraitContext) -> hir::PolyTraitRef { + let bound_lifetimes = self.lower_lifetime_defs(&p.bound_lifetimes); + let trait_ref = self.with_parent_impl_lifetime_defs(&bound_lifetimes, + |this| this.lower_trait_ref(&p.trait_ref, itctx)); + hir::PolyTraitRef { - bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes), - trait_ref: self.lower_trait_ref(&p.trait_ref, itctx), + bound_lifetimes, + trait_ref, span: p.span, } } @@ -1555,11 +1860,15 @@ impl<'a> LoweringContext<'a> { let body = this.lower_block(body, false); this.expr_block(body, ThinVec::new()) }); - hir::ItemFn(this.lower_fn_decl(decl, fn_def_id, true), + let (generics, fn_decl) = + this.add_in_band_lifetime_defs(generics, fn_def_id, |this| + this.lower_fn_decl(decl, fn_def_id, true)); + + hir::ItemFn(fn_decl, this.lower_unsafety(unsafety), this.lower_constness(constness), abi, - this.lower_generics(generics), + generics, body_id) }) } @@ -1600,29 +1909,42 @@ impl<'a> LoweringContext<'a> { ItemKind::Impl(unsafety, polarity, defaultness, - ref generics, + ref ast_generics, ref ifce, ref ty, ref impl_items) => { - let new_impl_items = impl_items.iter() - .map(|item| self.lower_impl_item_ref(item)) - .collect(); - let ifce = ifce.as_ref().map(|trait_ref| { - self.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed) + let def_id = self.resolver.definitions().opt_local_def_id(id); + let (generics, (ifce, lowered_ty)) = + self.add_in_band_lifetime_defs(ast_generics, def_id, |this| { + let ifce = ifce.as_ref().map(|trait_ref| { + this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed) + }); + + if let Some(ref trait_ref) = ifce { + if let Def::Trait(def_id) = trait_ref.path.def { + this.trait_impls.entry(def_id).or_insert(vec![]).push(id); + } + } + + let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed); + + (ifce, lowered_ty) + }); + + let new_impl_items = self.with_in_scope_lifetime_defs( + &ast_generics.lifetimes, |this| { + impl_items.iter() + .map(|item| this.lower_impl_item_ref(item)) + .collect() }); - if let Some(ref trait_ref) = ifce { - if let Def::Trait(def_id) = trait_ref.path.def { - self.trait_impls.entry(def_id).or_insert(vec![]).push(id); - } - } hir::ItemImpl(self.lower_unsafety(unsafety), self.lower_impl_polarity(polarity), self.lower_defaultness(defaultness, true /* [1] */), - self.lower_generics(generics), + generics, ifce, - self.lower_ty(ty, ImplTraitContext::Disallowed), + lowered_ty, new_impl_items) } ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => { @@ -1646,41 +1968,55 @@ impl<'a> LoweringContext<'a> { let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id); let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id); + let (generics, node) = match i.node { + TraitItemKind::Const(ref ty, ref default) => { + ( + this.lower_generics(&i.generics), + hir::TraitItemKind::Const( + this.lower_ty(ty, ImplTraitContext::Disallowed), + default.as_ref().map(|x| { + this.lower_body(None, |this| this.lower_expr(x)) + })) + ) + } + TraitItemKind::Method(ref sig, None) => { + let names = this.lower_fn_args_to_names(&sig.decl); + this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this| + hir::TraitItemKind::Method( + this.lower_method_sig(sig, fn_def_id, false), + hir::TraitMethod::Required(names))) + } + TraitItemKind::Method(ref sig, Some(ref body)) => { + let body_id = this.lower_body(Some(&sig.decl), |this| { + let body = this.lower_block(body, false); + this.expr_block(body, ThinVec::new()) + }); + + this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this| + hir::TraitItemKind::Method( + this.lower_method_sig(sig, fn_def_id, false), + hir::TraitMethod::Provided(body_id))) + } + TraitItemKind::Type(ref bounds, ref default) => { + ( + this.lower_generics(&i.generics), + hir::TraitItemKind::Type( + this.lower_bounds(bounds, ImplTraitContext::Disallowed), + default.as_ref().map(|x| { + this.lower_ty(x, ImplTraitContext::Disallowed) + })) + ) + } + TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }; + hir::TraitItem { id: node_id, hir_id, name: this.lower_ident(i.ident), attrs: this.lower_attrs(&i.attrs), - generics: this.lower_generics(&i.generics), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::TraitItemKind::Const(this.lower_ty(ty, ImplTraitContext::Disallowed), - default.as_ref().map(|x| { - this.lower_body(None, |this| this.lower_expr(x)) - })) - } - TraitItemKind::Method(ref sig, None) => { - let names = this.lower_fn_args_to_names(&sig.decl); - hir::TraitItemKind::Method(this.lower_method_sig(sig, fn_def_id, false), - hir::TraitMethod::Required(names)) - } - TraitItemKind::Method(ref sig, Some(ref body)) => { - let body_id = this.lower_body(Some(&sig.decl), |this| { - let body = this.lower_block(body, false); - this.expr_block(body, ThinVec::new()) - }); - hir::TraitItemKind::Method(this.lower_method_sig(sig, fn_def_id, false), - hir::TraitMethod::Provided(body_id)) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TraitItemKind::Type(this.lower_bounds(bounds, - ImplTraitContext::Disallowed), - default.as_ref().map(|x| { - this.lower_ty(x, ImplTraitContext::Disallowed) - })) - } - TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, + generics, + node, span: i.span, } }) @@ -1715,37 +2051,46 @@ impl<'a> LoweringContext<'a> { let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id); let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id); + let (generics, node) = match i.node { + ImplItemKind::Const(ref ty, ref expr) => { + let body_id = this.lower_body(None, |this| this.lower_expr(expr)); + ( + this.lower_generics(&i.generics), + hir::ImplItemKind::Const( + this.lower_ty(ty, ImplTraitContext::Disallowed), + body_id + ) + ) + } + ImplItemKind::Method(ref sig, ref body) => { + let body_id = this.lower_body(Some(&sig.decl), |this| { + let body = this.lower_block(body, false); + this.expr_block(body, ThinVec::new()) + }); + let impl_trait_return_allow = !this.is_in_trait_impl; + + this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this| + hir::ImplItemKind::Method( + this.lower_method_sig(sig, fn_def_id, impl_trait_return_allow), + body_id)) + } + ImplItemKind::Type(ref ty) => ( + this.lower_generics(&i.generics), + hir::ImplItemKind::Type( + this.lower_ty(ty, ImplTraitContext::Disallowed)), + ), + ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }; + hir::ImplItem { id: node_id, hir_id, name: this.lower_ident(i.ident), attrs: this.lower_attrs(&i.attrs), - generics: this.lower_generics(&i.generics), + generics, vis: this.lower_visibility(&i.vis, None), defaultness: this.lower_defaultness(i.defaultness, true /* [1] */), - node: match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - let body_id = this.lower_body(None, |this| this.lower_expr(expr)); - hir::ImplItemKind::Const( - this.lower_ty(ty, ImplTraitContext::Disallowed), - body_id - ) - } - ImplItemKind::Method(ref sig, ref body) => { - let body_id = this.lower_body(Some(&sig.decl), |this| { - let body = this.lower_block(body, false); - this.expr_block(body, ThinVec::new()) - }); - let impl_trait_return_allow = !this.is_in_trait_impl; - hir::ImplItemKind::Method(this.lower_method_sig(sig, - fn_def_id, - impl_trait_return_allow), - body_id) - } - ImplItemKind::Type(ref ty) => - hir::ImplItemKind::Type(this.lower_ty(ty, ImplTraitContext::Disallowed)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, + node, span: i.span, } }) @@ -1835,16 +2180,26 @@ impl<'a> LoweringContext<'a> { fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem { self.with_parent_def(i.id, |this| { + let node_id = this.lower_node_id(i.id).node_id; + let def_id = this.resolver.definitions().local_def_id(node_id); hir::ForeignItem { - id: this.lower_node_id(i.id).node_id, + id: node_id, name: i.ident.name, attrs: this.lower_attrs(&i.attrs), node: match i.node { ForeignItemKind::Fn(ref fdec, ref generics) => { // Disallow impl Trait in foreign items - hir::ForeignItemFn(this.lower_fn_decl(fdec, None, false), - this.lower_fn_args_to_names(fdec), - this.lower_generics(generics)) + let (generics, (fn_dec, fn_args)) = + this.add_in_band_lifetime_defs( + generics, + Some(def_id), + |this| ( + this.lower_fn_decl(fdec, None, false), + this.lower_fn_args_to_names(fdec) + ) + ); + + hir::ForeignItemFn(fn_dec, fn_args, generics) } ForeignItemKind::Static(ref t, m) => { hir::ForeignItemStatic(this.lower_ty(t, ImplTraitContext::Disallowed), m) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1346685e02a..39ec33eef1f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -222,6 +222,10 @@ pub struct LifetimeDef { pub lifetime: Lifetime, pub bounds: HirVec<Lifetime>, pub pure_wrt_drop: bool, + // Indicates that the lifetime definition was synthetically added + // as a result of an in-band lifetime usage like + // `fn foo(x: &'a u8) -> &'a u8 { x }` + pub in_band: bool, } /// A "Path" is essentially Rust's notion of a name; for instance: @@ -1462,6 +1466,12 @@ pub struct BareFnTy { } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ExistTy { + pub generics: Generics, + pub bounds: TyParamBounds, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] /// The different kinds of types recognized by the compiler pub enum Ty_ { /// A variable length slice (`[T]`) @@ -1488,7 +1498,16 @@ pub enum Ty_ { TyTraitObject(HirVec<PolyTraitRef>, Lifetime), /// An exsitentially quantified (there exists a type satisfying) `impl /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime. - TyImplTraitExistential(TyParamBounds), + /// + /// The `ExistTy` structure emulates an + /// `abstract type Foo<'a, 'b>: MyTrait<'a, 'b>;`. + /// + /// The `HirVec<Lifetime>` is the list of lifetimes applied as parameters + /// to the `abstract type`, e.g. the `'c` and `'d` in `-> Foo<'c, 'd>`. + /// This list is only a list of lifetimes and not type parameters + /// because all in-scope type parameters are captured by `impl Trait`, + /// so they are resolved directly through the parent `Generics`. + TyImplTraitExistential(ExistTy, HirVec<Lifetime>), /// An universally quantified (for all types satisfying) `impl /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime. TyImplTraitUniversal(DefId, TyParamBounds), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 451e870f500..d94dd24af3e 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -421,8 +421,10 @@ impl<'a> State<'a> { self.print_lifetime(lifetime)?; } } - hir::TyImplTraitExistential(ref bounds) | - hir::TyImplTraitUniversal(_, ref bounds) => { + hir::TyImplTraitExistential(ref existty, ref _lifetimes) => { + self.print_bounds("impl", &existty.bounds[..])?; + } + hir::TyImplTraitUniversal(_, ref bounds) => { self.print_bounds("impl", &bounds[..])?; } hir::TyArray(ref ty, v) => { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 2b5390e6bb9..bccef6dc91b 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -157,7 +157,8 @@ impl_stable_hash_for!(struct hir::Lifetime { impl_stable_hash_for!(struct hir::LifetimeDef { lifetime, bounds, - pure_wrt_drop + pure_wrt_drop, + in_band }); impl_stable_hash_for!(struct hir::Path { @@ -295,6 +296,11 @@ impl_stable_hash_for!(struct hir::BareFnTy { arg_names }); +impl_stable_hash_for!(struct hir::ExistTy { + generics, + bounds +}); + impl_stable_hash_for!(enum hir::Ty_ { TySlice(t), TyArray(t, body_id), @@ -305,7 +311,7 @@ impl_stable_hash_for!(enum hir::Ty_ { TyTup(ts), TyPath(qpath), TyTraitObject(trait_refs, lifetime), - TyImplTraitExistential(bounds), + TyImplTraitExistential(existty, lifetimes), TyImplTraitUniversal(def_id, bounds), TyTypeof(body_id), TyErr, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index e7627b110fa..45e80b58a4f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -236,8 +236,9 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Predicate<'gcx> { ty::Predicate::ObjectSafe(def_id) => { def_id.hash_stable(hcx, hasher); } - ty::Predicate::ClosureKind(def_id, closure_kind) => { + ty::Predicate::ClosureKind(def_id, closure_substs, closure_kind) => { def_id.hash_stable(hcx, hasher); + closure_substs.hash_stable(hcx, hasher); closure_kind.hash_stable(hcx, hasher); } ty::Predicate::ConstEvaluatable(def_id, substs) => { @@ -492,10 +493,15 @@ for ::middle::resolve_lifetime::Set1<T> } } +impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin { + Explicit, + InBand +}); + impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region { Static, - EarlyBound(index, decl), - LateBound(db_index, decl), + EarlyBound(index, decl, is_in_band), + LateBound(db_index, decl, is_in_band), LateBoundAnon(db_index, anon_index), Free(call_site_scope_data, decl) }); diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 40e933b26a2..50a37e12531 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -270,6 +270,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid), ambient_variance, needs_wf: false, + root_ty: ty, }; let ty = generalize.relate(&ty, &ty)?; @@ -280,10 +281,23 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, + + /// Span, used when creating new type variables and things. span: Span, + + /// The vid of the type variable that is in the process of being + /// instantiated; if we find this within the type we are folding, + /// that means we would have created a cyclic type. for_vid_sub_root: ty::TyVid, + + /// Track the variance as we descend into the type. ambient_variance: ty::Variance, - needs_wf: bool, // see the field `needs_wf` in `Generalization` + + /// See the field `needs_wf` in `Generalization`. + needs_wf: bool, + + /// The root type that we are generalizing. Used when reporting cycles. + root_ty: Ty<'tcx>, } /// Result from a generalization operation. This includes @@ -386,7 +400,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' if sub_vid == self.for_vid_sub_root { // If sub-roots are equal, then `for_vid` and // `vid` are related via subtyping. - return Err(TypeError::CyclicTy); + return Err(TypeError::CyclicTy(self.root_ty)); } else { match variables.probe_root(vid) { Some(u) => { diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index c64bd610962..cade67a44bb 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -281,7 +281,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { // Find the index of the named region that was part of the // error. We will then search the function parameters for a bound // region at the right depth with the same index - (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \ def_id={:?}", id, def_id); if id == def_id { @@ -293,7 +293,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { // Find the index of the named region that was part of the // error. We will then search the function parameters for a bound // region at the right depth with the same index - (Some(rl::Region::LateBound(debruijn_index, id)), ty::BrNamed(def_id, _)) => { + ( + Some(rl::Region::LateBound(debruijn_index, id, _)), + ty::BrNamed(def_id, _) + ) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index.depth); debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", id); @@ -306,8 +309,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { (Some(rl::Region::Static), _) | (Some(rl::Region::Free(_, _)), _) | - (Some(rl::Region::EarlyBound(_, _)), _) | - (Some(rl::Region::LateBound(_, _)), _) | + (Some(rl::Region::EarlyBound(_, _, _)), _) | + (Some(rl::Region::LateBound(_, _, _)), _) | (Some(rl::Region::LateBoundAnon(_, _)), _) | (None, _) => { debug!("no arg found"); @@ -368,7 +371,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { } } - (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \ def_id={:?}", id, def_id); if id == def_id { @@ -377,7 +380,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { } } - (Some(rl::Region::LateBound(debruijn_index, id)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index.depth); debug!("id={:?}", id); @@ -389,8 +392,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { } (Some(rl::Region::Static), _) | - (Some(rl::Region::EarlyBound(_, _)), _) | - (Some(rl::Region::LateBound(_, _)), _) | + (Some(rl::Region::EarlyBound(_, _, _)), _) | + (Some(rl::Region::LateBound(_, _, _)), _) | (Some(rl::Region::LateBoundAnon(_, _)), _) | (Some(rl::Region::Free(_, _)), _) | (None, _) => { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 4f36193e197..6fadafc7b97 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -689,9 +689,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { diag: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>, secondary_span: Option<(Span, String)>, - values: Option<ValuePairs<'tcx>>, + mut values: Option<ValuePairs<'tcx>>, terr: &TypeError<'tcx>) { + // For some types of errors, expected-found does not make + // sense, so just ignore the values we were given. + match terr { + TypeError::CyclicTy(_) => { values = None; } + _ => { } + } + let (expected_found, exp_found, is_simple_error) = match values { None => (None, None, false), Some(values) => { @@ -780,17 +787,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { terr); let span = trace.cause.span; - let failure_str = trace.cause.as_failure_str(); - let mut diag = match trace.cause.code { - ObligationCauseCode::IfExpressionWithNoElse => { + let failure_code = trace.cause.as_failure_code(terr); + let mut diag = match failure_code { + FailureCode::Error0317(failure_str) => { struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str) } - ObligationCauseCode::MainFunctionType => { + FailureCode::Error0580(failure_str) => { struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str) } - _ => { + FailureCode::Error0308(failure_str) => { struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str) } + FailureCode::Error0644(failure_str) => { + struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str) + } }; self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr); diag @@ -1040,23 +1050,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } +enum FailureCode { + Error0317(&'static str), + Error0580(&'static str), + Error0308(&'static str), + Error0644(&'static str), +} + impl<'tcx> ObligationCause<'tcx> { - fn as_failure_str(&self) -> &'static str { + fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode { + use self::FailureCode::*; use traits::ObligationCauseCode::*; match self.code { - CompareImplMethodObligation { .. } => "method not compatible with trait", - MatchExpressionArm { source, .. } => match source { + CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"), + MatchExpressionArm { source, .. } => Error0308(match source { hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types", _ => "match arms have incompatible types", - }, - IfExpression => "if and else have incompatible types", - IfExpressionWithNoElse => "if may be missing an else clause", - EquatePredicate => "equality predicate not satisfied", - MainFunctionType => "main function has wrong type", - StartFunctionType => "start function has wrong type", - IntrinsicType => "intrinsic has wrong type", - MethodReceiver => "mismatched method receiver", - _ => "mismatched types", + }), + IfExpression => Error0308("if and else have incompatible types"), + IfExpressionWithNoElse => Error0317("if may be missing an else clause"), + EquatePredicate => Error0308("equality predicate not satisfied"), + MainFunctionType => Error0580("main function has wrong type"), + StartFunctionType => Error0308("start function has wrong type"), + IntrinsicType => Error0308("intrinsic has wrong type"), + MethodReceiver => Error0308("mismatched method receiver"), + + // In the case where we have no more specific thing to + // say, also take a look at the error code, maybe we can + // tailor to that. + _ => match terr { + TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => + Error0644("closure/generator type that references itself"), + _ => + Error0308("mismatched types"), + } } } diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 22d9a9e313b..ea3c0a8ddb4 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -125,9 +125,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // ``` labels.clear(); labels.push((pattern.span, format!("consider giving this closure parameter a type"))); - } - - if let Some(pattern) = local_visitor.found_local_pattern { + } else if let Some(pattern) = local_visitor.found_local_pattern { if let Some(simple_name) = pattern.simple_name() { labels.push((pattern.span, format!("consider giving `{}` a type", simple_name))); } else { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 41e7dffe54d..426c61e9ac0 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -43,9 +43,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::TypeFolder; -use ty::subst::Substs; use util::nodemap::FxHashMap; -use hir::def_id::DefId; use std::collections::hash_map::Entry; @@ -56,7 +54,6 @@ pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, freshen_count: u32, freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>, - closure_set: Vec<DefId>, } impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { @@ -66,7 +63,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { infcx, freshen_count: 0, freshen_map: FxHashMap(), - closure_set: vec![], } } @@ -92,88 +88,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { } } } - - fn next_fresh<F>(&mut self, - freshener: F) - -> Ty<'tcx> - where F: FnOnce(u32) -> ty::InferTy, - { - let index = self.freshen_count; - self.freshen_count += 1; - self.infcx.tcx.mk_infer(freshener(index)) - } - - fn freshen_closure_like<M, C>(&mut self, - def_id: DefId, - substs: ty::ClosureSubsts<'tcx>, - t: Ty<'tcx>, - markers: M, - combine: C) - -> Ty<'tcx> - where M: FnOnce(&mut Self) -> (Ty<'tcx>, Ty<'tcx>), - C: FnOnce(&'tcx Substs<'tcx>) -> Ty<'tcx> - { - let tcx = self.infcx.tcx; - - let closure_in_progress = self.infcx.in_progress_tables.map_or(false, |tables| { - tcx.hir.as_local_node_id(def_id).map_or(false, |closure_id| { - tables.borrow().local_id_root == - Some(DefId::local(tcx.hir.node_to_hir_id(closure_id).owner)) - }) - }); - - if !closure_in_progress { - // If this closure belongs to another infcx, its kind etc. were - // fully inferred and its signature/kind are exactly what's listed - // in its infcx. So we don't need to add the markers for them. - return t.super_fold_with(self); - } - - // We are encoding a closure in progress. Because we want our freshening - // key to contain all inference information needed to make sense of our - // value, we need to encode the closure signature and kind. The way - // we do that is to add them as 2 variables to the closure substs, - // basically because it's there (and nobody cares about adding extra stuff - // to substs). - // - // This means the "freshened" closure substs ends up looking like - // fresh_substs = [PARENT_SUBSTS* ; UPVARS* ; SIG_MARKER ; KIND_MARKER] - let (marker_1, marker_2) = if self.closure_set.contains(&def_id) { - // We found the closure def-id within its own signature. Just - // leave a new freshened type - any matching operations would - // have found and compared the exterior closure already to - // get here. - // - // In that case, we already know what the signature would - // be - the parent closure on the stack already contains a - // "copy" of the signature, so there is no reason to encode - // it again for injectivity. Just use a fresh type variable - // to make everything comparable. - // - // For example (closure kinds omitted for clarity) - // t=[closure FOO sig=[closure BAR sig=[closure FOO ..]]] - // Would get encoded to - // t=[closure FOO sig=[closure BAR sig=[closure FOO sig=$0]]] - // - // and we can decode by having - // $0=[closure BAR {sig doesn't exist in decode}] - // and get - // t=[closure FOO] - // sig[FOO] = [closure BAR] - // sig[BAR] = [closure FOO] - (self.next_fresh(ty::FreshTy), self.next_fresh(ty::FreshTy)) - } else { - self.closure_set.push(def_id); - let markers = markers(self); - self.closure_set.pop(); - markers - }; - - combine(tcx.mk_substs( - substs.substs.iter().map(|k| k.fold_with(self)).chain( - [marker_1, marker_2].iter().cloned().map(From::from) - ))) - } } impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { @@ -249,51 +163,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { t } - ty::TyClosure(def_id, substs) => { - self.freshen_closure_like( - def_id, substs, t, - |this| { - // HACK: use a "random" integer type to mark the kind. Because - // different closure kinds shouldn't get unified during - // selection, the "subtyping" relationship (where any kind is - // better than no kind) shouldn't matter here, just that the - // types are different. - let closure_kind = this.infcx.closure_kind(def_id); - let closure_kind_marker = match closure_kind { - None => tcx.types.i8, - Some(ty::ClosureKind::Fn) => tcx.types.i16, - Some(ty::ClosureKind::FnMut) => tcx.types.i32, - Some(ty::ClosureKind::FnOnce) => tcx.types.i64, - }; - - let closure_sig = this.infcx.fn_sig(def_id); - (tcx.mk_fn_ptr(closure_sig.fold_with(this)), - closure_kind_marker) - }, - |substs| tcx.mk_closure(def_id, substs) - ) - } - - ty::TyGenerator(def_id, substs, interior) => { - self.freshen_closure_like( - def_id, substs, t, - |this| { - let gen_sig = this.infcx.generator_sig(def_id).unwrap(); - // FIXME: want to revise this strategy when generator - // signatures can actually contain LBRs. - let sig = this.tcx().no_late_bound_regions(&gen_sig) - .unwrap_or_else(|| { - bug!("late-bound regions in signature of {:?}", - def_id) - }); - (sig.yield_ty, sig.return_ty).fold_with(this) - }, - |substs| { - tcx.mk_generator(def_id, ty::ClosureSubsts { substs }, interior) - } - ) - } - + ty::TyGenerator(..) | ty::TyBool | ty::TyChar | ty::TyInt(..) | @@ -314,6 +184,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyProjection(..) | ty::TyForeign(..) | ty::TyParam(..) | + ty::TyClosure(..) | ty::TyAnon(..) => { t.super_fold_with(self) } diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 0692d284d7c..5a4f2157298 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -171,7 +171,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { for (r, vid) in seeds { // While all things transitively reachable in the graph // from the variable (`'0` in the example above). - let seed_index = NodeIndex(vid.index as usize); + let seed_index = NodeIndex(vid.index() as usize); for succ_index in graph.depth_traverse(seed_index, OUTGOING) { let succ_index = succ_index.0; @@ -512,16 +512,16 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { match *constraint { Constraint::VarSubVar(a_id, b_id) => { graph.add_edge( - NodeIndex(a_id.index as usize), - NodeIndex(b_id.index as usize), + NodeIndex(a_id.index() as usize), + NodeIndex(b_id.index() as usize), *constraint, ); } Constraint::RegSubVar(_, b_id) => { - graph.add_edge(dummy_source, NodeIndex(b_id.index as usize), *constraint); + graph.add_edge(dummy_source, NodeIndex(b_id.index() as usize), *constraint); } Constraint::VarSubReg(a_id, _) => { - graph.add_edge(NodeIndex(a_id.index as usize), dummy_sink, *constraint); + graph.add_edge(NodeIndex(a_id.index() as usize), dummy_sink, *constraint); } Constraint::RegSubReg(..) => { // this would be an edge from `dummy_source` to @@ -630,9 +630,9 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { let node_idx = state.stack.pop().unwrap(); // check whether we've visited this node on some previous walk - if dup_vec[node_idx.index as usize] == u32::MAX { - dup_vec[node_idx.index as usize] = orig_node_idx.index; - } else if dup_vec[node_idx.index as usize] != orig_node_idx.index { + if dup_vec[node_idx.index() as usize] == u32::MAX { + dup_vec[node_idx.index() as usize] = orig_node_idx.index() as u32; + } else if dup_vec[node_idx.index() as usize] != orig_node_idx.index() as u32 { state.dup_found = true; } @@ -659,7 +659,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { ) { debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir); - let source_node_index = NodeIndex(source_vid.index as usize); + let source_node_index = NodeIndex(source_vid.index() as usize); for (_, edge) in graph.adjacent_edges(source_node_index, dir) { match edge.data { Constraint::VarSubVar(from_vid, to_vid) => { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4f923f0b249..7302bad0ca1 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1463,26 +1463,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { !traits::type_known_to_meet_bound(self, param_env, ty, copy_def_id, span) } + /// Obtains the latest type of the given closure; this may be a + /// closure in the current function, in which case its + /// `ClosureKind` may not yet be known. pub fn closure_kind(&self, - def_id: DefId) + closure_def_id: DefId, + closure_substs: ty::ClosureSubsts<'tcx>) -> Option<ty::ClosureKind> { - if let Some(tables) = self.in_progress_tables { - if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { - let hir_id = self.tcx.hir.node_to_hir_id(id); - return tables.borrow() - .closure_kinds() - .get(hir_id) - .cloned() - .map(|(kind, _)| kind); - } - } - - // During typeck, ALL closures are local. But afterwards, - // during trans, we see closure ids from other traits. - // That may require loading the closure data out of the - // cstore. - Some(self.tcx.closure_kind(def_id)) + let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx); + let closure_kind_ty = self.shallow_resolve(&closure_kind_ty); + closure_kind_ty.to_opt_closure_kind() } /// Obtain the signature of a function or closure. @@ -1490,11 +1481,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// work during the type-checking of the enclosing function and /// return the closure signature in its partially inferred state. pub fn fn_sig(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> { + // Do we have an in-progress set of tables we are inferring? if let Some(tables) = self.in_progress_tables { + // Is this a local item? if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { - let hir_id = self.tcx.hir.node_to_hir_id(id); - if let Some(&ty) = tables.borrow().closure_tys().get(hir_id) { - return ty; + // Is it a local *closure*? + if self.tcx.is_closure(def_id) { + let hir_id = self.tcx.hir.node_to_hir_id(id); + // Is this local closure contained within the tables we are inferring? + if tables.borrow().local_id_root == Some(DefId::local(hir_id.owner)) { + // if so, extract signature from there. + let closure_ty = tables.borrow().node_id_to_type(hir_id); + let (closure_def_id, closure_substs) = match closure_ty.sty { + ty::TyClosure(closure_def_id, closure_substs) => + (closure_def_id, closure_substs), + _ => + bug!("closure with non-closure type: {:?}", closure_ty), + }; + assert_eq!(def_id, closure_def_id); + let closure_sig_ty = closure_substs.closure_sig_ty(def_id, self.tcx); + let closure_sig_ty = self.shallow_resolve(&closure_sig_ty); + return closure_sig_ty.fn_sig(self.tcx); + } } } } @@ -1502,19 +1510,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.fn_sig(def_id) } - pub fn generator_sig(&self, def_id: DefId) -> Option<ty::PolyGenSig<'tcx>> { - if let Some(tables) = self.in_progress_tables { - if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { - let hir_id = self.tcx.hir.node_to_hir_id(id); - if let Some(&ty) = tables.borrow().generator_sigs().get(hir_id) { - return ty.map(|t| ty::Binder(t)); - } - } - } - - self.tcx.generator_sig(def_id) - } - /// Normalizes associated types in `value`, potentially returning /// new obligations that must further be processed. pub fn partially_normalize_associated_types_in<T>(&self, diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 096037ebe88..72740dd40be 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -16,7 +16,7 @@ use self::CombineMapType::*; use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use super::unify_key; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unify::{self, UnificationTable}; use ty::{self, Ty, TyCtxt}; @@ -404,7 +404,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } AddVar(vid) => { self.var_origins.pop().unwrap(); - assert_eq!(self.var_origins.len(), vid.index as usize); + assert_eq!(self.var_origins.len(), vid.index() as usize); } AddConstraint(ref constraint) => { self.data.constraints.remove(constraint); diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index cc91a637b89..6aa094d2cd6 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -56,7 +56,10 @@ pub enum TypeVariableOrigin { NormalizeProjectionType(Span), TypeInference(Span), TypeParameterDefinition(Span, ast::Name), - TransformedUpvar(Span), + + /// one of the upvars or closure kind parameters in a `ClosureSubsts` + /// (before it has been determined) + ClosureSynthetic(Span), SubstitutionPlaceholder(Span), AutoDeref(Span), AdjustmentType(Span), diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index d7e3a53ff25..99b11794cc5 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -33,7 +33,7 @@ pub struct RegionVidKey { impl Combine for RegionVidKey { fn combine(&self, other: &RegionVidKey) -> RegionVidKey { - let min_vid = if self.min_vid.index < other.min_vid.index { + let min_vid = if self.min_vid.index() < other.min_vid.index() { self.min_vid } else { other.min_vid @@ -45,8 +45,8 @@ impl Combine for RegionVidKey { impl UnifyKey for ty::RegionVid { type Value = RegionVidKey; - fn index(&self) -> u32 { self.index } - fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid { index: i } } + fn index(&self) -> u32 { self.0 } + fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) } fn tag(_: Option<ty::RegionVid>) -> &'static str { "RegionVid" } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index a42ff543227..21eb772b1b3 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -531,13 +531,15 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { id: ast::NodeId, span: syntax_pos::Span, name: ast::Name, - node_type: &str) { + node_type: &str, + participle: &str) { if !name.as_str().starts_with("_") { self.tcx .lint_node(lint::builtin::DEAD_CODE, id, span, - &format!("{} is never used: `{}`", node_type, name)); + &format!("{} is never {}: `{}`", + node_type, participle, name)); } } } @@ -570,7 +572,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { item.id, span, item.name, - item.node.descriptive_variant() + item.node.descriptive_variant(), + "used", ); } else { // Only continue if we didn't warn @@ -583,7 +586,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { g: &'tcx hir::Generics, id: ast::NodeId) { if self.should_warn_about_variant(&variant.node) { - self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name, "variant"); + self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name, + "variant", "constructed"); } else { intravisit::walk_variant(self, variant, g, id); } @@ -591,15 +595,15 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) { if self.should_warn_about_foreign_item(fi) { - self.warn_dead_code(fi.id, fi.span, fi.name, fi.node.descriptive_variant()); + self.warn_dead_code(fi.id, fi.span, fi.name, + fi.node.descriptive_variant(), "used"); } intravisit::walk_foreign_item(self, fi); } fn visit_struct_field(&mut self, field: &'tcx hir::StructField) { if self.should_warn_about_field(&field) { - self.warn_dead_code(field.id, field.span, - field.name, "field"); + self.warn_dead_code(field.id, field.span, field.name, "field", "used"); } intravisit::walk_struct_field(self, field); } @@ -611,14 +615,15 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { self.warn_dead_code(impl_item.id, impl_item.span, impl_item.name, - "associated const"); + "associated const", + "used"); } self.visit_nested_body(body_id) } hir::ImplItemKind::Method(_, body_id) => { if !self.symbol_is_live(impl_item.id, None) { let span = self.tcx.sess.codemap().def_span(impl_item.span); - self.warn_dead_code(impl_item.id, span, impl_item.name, "method"); + self.warn_dead_code(impl_item.id, span, impl_item.name, "method", "used"); } self.visit_nested_body(body_id) } diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index da505f16724..89c3f166847 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> { (&ty::ReFree(_), &ty::ReEarlyBound(_)) | (&ty::ReEarlyBound(_), &ty::ReFree(_)) | (&ty::ReFree(_), &ty::ReFree(_)) => - self.free_regions.relation.contains(&sub_region, &super_region), + self.free_regions.sub_free_regions(&sub_region, &super_region), _ => false, @@ -158,19 +158,39 @@ impl<'tcx> FreeRegionMap<'tcx> { } } - // Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`. - // (with the exception that `'static: 'x` is not notable) + /// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`. + /// (with the exception that `'static: 'x` is not notable) pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) { + debug!("relate_regions(sub={:?}, sup={:?})", sub, sup); if (is_free(sub) || *sub == ty::ReStatic) && is_free(sup) { self.relation.add(sub, sup) } } + /// True if `r_a <= r_b` is known to hold. Both `r_a` and `r_b` + /// must be free regions from the function header. + pub fn sub_free_regions<'a, 'gcx>(&self, + r_a: Region<'tcx>, + r_b: Region<'tcx>) + -> bool { + debug!("sub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b); + assert!(is_free(r_a)); + assert!(is_free(r_b)); + let result = r_a == r_b || self.relation.contains(&r_a, &r_b); + debug!("sub_free_regions: result={}", result); + result + } + + /// Compute the least-upper-bound of two free regions. In some + /// cases, this is more conservative than necessary, in order to + /// avoid making arbitrary choices. See + /// `TransitiveRelation::postdom_upper_bound` for more details. pub fn lub_free_regions<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { + debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b); assert!(is_free(r_a)); assert!(is_free(r_b)); let result = if r_a == r_b { r_a } else { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 19a43f3b5dd..a858a8d7449 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -310,6 +310,34 @@ language_item_table! { NonZeroItem, "non_zero", non_zero; DebugTraitLangItem, "debug_trait", debug_trait; + + // A lang item for each of the 128-bit operators we can optionally lower. + I128AddFnLangItem, "i128_add", i128_add_fn; + U128AddFnLangItem, "u128_add", u128_add_fn; + I128SubFnLangItem, "i128_sub", i128_sub_fn; + U128SubFnLangItem, "u128_sub", u128_sub_fn; + I128MulFnLangItem, "i128_mul", i128_mul_fn; + U128MulFnLangItem, "u128_mul", u128_mul_fn; + I128DivFnLangItem, "i128_div", i128_div_fn; + U128DivFnLangItem, "u128_div", u128_div_fn; + I128RemFnLangItem, "i128_rem", i128_rem_fn; + U128RemFnLangItem, "u128_rem", u128_rem_fn; + I128ShlFnLangItem, "i128_shl", i128_shl_fn; + U128ShlFnLangItem, "u128_shl", u128_shl_fn; + I128ShrFnLangItem, "i128_shr", i128_shr_fn; + U128ShrFnLangItem, "u128_shr", u128_shr_fn; + // And overflow versions for the operators that are checkable. + // While MIR calls these Checked*, they return (T,bool), not Option<T>. + I128AddoFnLangItem, "i128_addo", i128_addo_fn; + U128AddoFnLangItem, "u128_addo", u128_addo_fn; + I128SuboFnLangItem, "i128_subo", i128_subo_fn; + U128SuboFnLangItem, "u128_subo", u128_subo_fn; + I128MuloFnLangItem, "i128_mulo", i128_mulo_fn; + U128MuloFnLangItem, "u128_mulo", u128_mulo_fn; + I128ShloFnLangItem, "i128_shlo", i128_shlo_fn; + U128ShloFnLangItem, "u128_shlo", u128_shlo_fn; + I128ShroFnLangItem, "i128_shro", i128_shro_fn; + U128ShroFnLangItem, "u128_shro", u128_shro_fn; } impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c89d67d4aab..0d4429de22a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -750,10 +750,19 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let kind = match self.node_ty(fn_hir_id)?.sty { ty::TyGenerator(..) => ty::ClosureKind::FnOnce, - ty::TyClosure(..) => { - match self.tables.closure_kinds().get(fn_hir_id) { - Some(&(kind, _)) => kind, - None => span_bug!(span, "missing closure kind"), + ty::TyClosure(closure_def_id, closure_substs) => { + match self.infcx { + // During upvar inference we may not know the + // closure kind, just use the LATTICE_BOTTOM value. + Some(infcx) => + infcx.closure_kind(closure_def_id, closure_substs) + .unwrap_or(ty::ClosureKind::LATTICE_BOTTOM), + + None => + self.tcx.global_tcx() + .lift(&closure_substs) + .expect("no inference cx, but inference variables in closure ty") + .closure_kind(closure_def_id, self.tcx.global_tcx()), } } ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t), diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8c299612064..b39975d3ff9 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -36,11 +36,32 @@ use rustc_back::slice; use hir; use hir::intravisit::{self, Visitor, NestedVisitorMap}; +/// The origin of a named lifetime definition. +/// +/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax. +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] +pub enum LifetimeDefOrigin { + // Explicit binders like `fn foo<'a>(x: &'a u8)` + Explicit, + // In-band declarations like `fn foo(x: &'a u8)` + InBand, +} + +impl LifetimeDefOrigin { + fn from_is_in_band(is_in_band: bool) -> Self { + if is_in_band { + LifetimeDefOrigin::InBand + } else { + LifetimeDefOrigin::Explicit + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum Region { Static, - EarlyBound(/* index */ u32, /* lifetime decl */ DefId), - LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId), + EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin), + LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin), LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), Free(DefId, /* lifetime decl */ DefId), } @@ -52,13 +73,16 @@ impl Region { let i = *index; *index += 1; let def_id = hir_map.local_def_id(def.lifetime.id); - (def.lifetime.name, Region::EarlyBound(i, def_id)) + let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); + debug!("Region::early: index={} def_id={:?}", i, def_id); + (def.lifetime.name, Region::EarlyBound(i, def_id, origin)) } fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) { let depth = ty::DebruijnIndex::new(1); let def_id = hir_map.local_def_id(def.lifetime.id); - (def.lifetime.name, Region::LateBound(depth, def_id)) + let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); + (def.lifetime.name, Region::LateBound(depth, def_id, origin)) } fn late_anon(index: &Cell<u32>) -> Region { @@ -73,16 +97,16 @@ impl Region { Region::Static | Region::LateBoundAnon(..) => None, - Region::EarlyBound(_, id) | - Region::LateBound(_, id) | + Region::EarlyBound(_, id, _) | + Region::LateBound(_, id, _) | Region::Free(_, id) => Some(id) } } fn shifted(self, amount: u32) -> Region { match self { - Region::LateBound(depth, id) => { - Region::LateBound(depth.shifted(amount), id) + Region::LateBound(depth, id, origin) => { + Region::LateBound(depth.shifted(amount), id, origin) } Region::LateBoundAnon(depth, index) => { Region::LateBoundAnon(depth.shifted(amount), index) @@ -93,10 +117,10 @@ impl Region { fn from_depth(self, depth: u32) -> Region { match self { - Region::LateBound(debruijn, id) => { + Region::LateBound(debruijn, id, origin) => { Region::LateBound(ty::DebruijnIndex { depth: debruijn.depth - (depth - 1) - }, id) + }, id, origin) } Region::LateBoundAnon(debruijn, index) => { Region::LateBoundAnon(ty::DebruijnIndex { @@ -109,7 +133,7 @@ impl Region { fn subst(self, params: &[hir::Lifetime], map: &NamedRegionMap) -> Option<Region> { - if let Region::EarlyBound(index, _) = self { + if let Region::EarlyBound(index, _, _) = self { params.get(index as usize).and_then(|lifetime| { map.defs.get(&lifetime.id).cloned() }) @@ -186,6 +210,9 @@ struct LifetimeContext<'a, 'tcx: 'a> { // I'm sorry. trait_ref_hack: bool, + // Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax. + is_in_fn_syntax: bool, + // List of labels in the function/method currently under analysis. labels_in_fn: Vec<(ast::Name, Span)>, @@ -201,6 +228,11 @@ enum Scope<'a> { /// declaration `Binder` and the location it's referenced from. Binder { lifetimes: FxHashMap<hir::LifetimeName, Region>, + + /// if we extend this scope with another scope, what is the next index + /// we should use for an early-bound region? + next_early_index: u32, + s: ScopeRef<'a> }, @@ -274,6 +306,7 @@ pub fn krate(sess: &Session, map: &mut map, scope: ROOT_SCOPE, trait_ref_hack: false, + is_in_fn_syntax: false, labels_in_fn: vec![], xcrate_object_lifetime_defaults: DefIdMap(), }; @@ -343,8 +376,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let lifetimes = generics.lifetimes.iter().map(|def| { Region::early(self.hir_map, &mut index, def) }).collect(); + let next_early_index = index + generics.ty_params.len() as u32; let scope = Scope::Binder { lifetimes, + next_early_index, s: ROOT_SCOPE }; self.with(scope, |old_scope, this| { @@ -372,12 +407,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { + debug!("visit_ty: ty={:?}", ty); match ty.node { hir::TyBareFn(ref c) => { + let next_early_index = self.next_early_index(); + let was_in_fn_syntax = self.is_in_fn_syntax; + self.is_in_fn_syntax = true; let scope = Scope::Binder { lifetimes: c.lifetimes.iter().map(|def| { - Region::late(self.hir_map, def) - }).collect(), + Region::late(self.hir_map, def) + }).collect(), + next_early_index, s: self.scope }; self.with(scope, |old_scope, this| { @@ -386,6 +426,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.check_lifetime_defs(old_scope, &c.lifetimes); intravisit::walk_ty(this, ty); }); + self.is_in_fn_syntax = was_in_fn_syntax; } hir::TyTraitObject(ref bounds, ref lifetime) => { for bound in bounds { @@ -405,6 +446,60 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.with(scope, |_, this| this.visit_ty(&mt.ty)); } + hir::TyImplTraitExistential(ref exist_ty, ref lifetimes) => { + // Resolve the lifetimes that are applied to the existential type. + // These are resolved in the current scope. + // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to + // `fn foo<'a>() -> MyAnonTy<'a> { ... }` + // ^ ^this gets resolved in the current scope + for lifetime in lifetimes { + self.visit_lifetime(lifetime); + + // Check for predicates like `impl for<'a> SomeTrait<impl OtherTrait<'a>>` + // and ban them. Type variables instantiated inside binders aren't + // well-supported at the moment, so this doesn't work. + // In the future, this should be fixed and this error should be removed. + let def = self.map.defs.get(&lifetime.id); + if let Some(&Region::LateBound(_, def_id, _)) = def { + if let Some(node_id) = self.hir_map.as_local_node_id(def_id) { + // Ensure that the parent of the def is an item, not HRTB + let parent_id = self.hir_map.get_parent_node(node_id); + let parent_impl_id = hir::ImplItemId { node_id: parent_id }; + let parent_trait_id = hir::TraitItemId { node_id: parent_id }; + let krate = self.hir_map.forest.krate(); + if !(krate.items.contains_key(&parent_id) || + krate.impl_items.contains_key(&parent_impl_id) || + krate.trait_items.contains_key(&parent_trait_id)) + { + span_err!(self.sess, lifetime.span, E0657, + "`impl Trait` can only capture lifetimes \ + bound at the fn or impl level"); + } + } + } + } + + // Resolve the lifetimes in the bounds to the lifetime defs in the generics. + // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to + // `abstract type MyAnonTy<'b>: MyTrait<'b>;` + // ^ ^ this gets resolved in the scope of + // the exist_ty generics + let hir::ExistTy { ref generics, ref bounds } = *exist_ty; + let mut index = self.next_early_index(); + debug!("visit_ty: index = {}", index); + let lifetimes = generics.lifetimes.iter() + .map(|lt_def| Region::early(self.hir_map, &mut index, lt_def)) + .collect(); + + let next_early_index = index + generics.ty_params.len() as u32; + let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope }; + self.with(scope, |_old_scope, this| { + this.visit_generics(generics); + for bound in bounds { + this.visit_ty_param_bound(bound); + } + }); + } _ => { intravisit::walk_ty(self, ty) } @@ -463,6 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { + check_mixed_explicit_and_in_band_defs(&self.sess, &generics.lifetimes); for ty_param in generics.ty_params.iter() { walk_list!(self, visit_ty_param_bound, &ty_param.bounds); if let Some(ref ty) = ty_param.default { @@ -477,10 +573,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { .. }) => { if !bound_lifetimes.is_empty() { self.trait_ref_hack = true; + let next_early_index = self.next_early_index(); let scope = Scope::Binder { lifetimes: bound_lifetimes.iter().map(|def| { Region::late(self.hir_map, def) - }).collect(), + }).collect(), + next_early_index, s: self.scope }; let result = self.with(scope, |old_scope, this| { @@ -524,10 +622,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { span_err!(self.sess, trait_ref.span, E0316, "nested quantification of lifetimes"); } + let next_early_index = self.next_early_index(); let scope = Scope::Binder { lifetimes: trait_ref.bound_lifetimes.iter().map(|def| { Region::late(self.hir_map, def) - }).collect(), + }).collect(), + next_early_index, s: self.scope }; self.with(scope, |old_scope, this| { @@ -570,6 +670,22 @@ impl ShadowKind { } } +fn check_mixed_explicit_and_in_band_defs( + sess: &Session, + lifetime_defs: &[hir::LifetimeDef], +) { + let oob_def = lifetime_defs.iter().find(|lt| !lt.in_band); + let in_band_def = lifetime_defs.iter().find(|lt| lt.in_band); + + if let (Some(oob_def), Some(in_band_def)) = (oob_def, in_band_def) { + struct_span_err!(sess, in_band_def.lifetime.span, E0688, + "cannot mix in-band and explicit lifetime definitions") + .span_label(in_band_def.lifetime.span, "in-band lifetime definition here") + .span_label(oob_def.lifetime.span, "explicit lifetime definition here") + .emit(); + } +} + fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) { let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) { // lifetime/lifetime shadowing is an error @@ -659,7 +775,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { Scope::Root => { return; } - Scope::Binder { ref lifetimes, s } => { + Scope::Binder { ref lifetimes, s, next_early_index: _ } => { // FIXME (#24278): non-hygienic comparison if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) { let node_id = hir_map.as_local_node_id(def.id().unwrap()) @@ -698,7 +814,7 @@ fn compute_object_lifetime_defaults(sess: &Session, hir_map: &Map) match *set { Set1::Empty => "BaseDefault".to_string(), Set1::One(Region::Static) => "'static".to_string(), - Set1::One(Region::EarlyBound(i, _)) => { + Set1::One(Region::EarlyBound(i, _, _)) => { generics.lifetimes[i as usize].lifetime.name.name().to_string() } Set1::One(_) => bug!(), @@ -768,7 +884,8 @@ fn object_lifetime_defaults_for_item(hir_map: &Map, generics: &hir::Generics) def.lifetime.name == name }).map_or(Set1::Many, |(i, def)| { let def_id = hir_map.local_def_id(def.lifetime.id); - Set1::One(Region::EarlyBound(i as u32, def_id)) + let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); + Set1::One(Region::EarlyBound(i as u32, def_id, origin)) }) } } @@ -799,6 +916,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { map: *map, scope: &wrap_scope, trait_ref_hack: self.trait_ref_hack, + is_in_fn_syntax: self.is_in_fn_syntax, labels_in_fn, xcrate_object_lifetime_defaults, }; @@ -860,8 +978,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } }).collect(); + let next_early_index = index + generics.ty_params.len() as u32; + let scope = Scope::Binder { lifetimes, + next_early_index, s: self.scope }; self.with(scope, move |old_scope, this| { @@ -870,7 +991,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }); } + /// Returns the next index one would use for an early-bound-region + /// if extending the current scope. + fn next_early_index(&self) -> u32 { + let mut scope = self.scope; + loop { + match *scope { + Scope::Root => + return 0, + + Scope::Binder { next_early_index, .. } => + return next_early_index, + + Scope::Body { s, .. } | + Scope::Elision { s, .. } | + Scope::ObjectLifetimeDefault { s, .. } => + scope = s, + } + } + } + fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) { + debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref); + // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the // given name or we run out of scopes. @@ -889,7 +1032,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { break None; } - Scope::Binder { ref lifetimes, s } => { + Scope::Binder { ref lifetimes, s, next_early_index: _ } => { if let Some(&def) = lifetimes.get(&lifetime_ref.name) { break Some(def.shifted(late_depth)); } else { @@ -926,6 +1069,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => {} } } + + // Check for fn-syntax conflicts with in-band lifetime definitions + if self.is_in_fn_syntax { + match def { + Region::EarlyBound(_, _, LifetimeDefOrigin::InBand) | + Region::LateBound(_, _, LifetimeDefOrigin::InBand) => { + struct_span_err!(self.sess, lifetime_ref.span, E0687, + "lifetimes used in `fn` or `Fn` syntax must be \ + explicitly declared using `<...>` binders") + .span_label(lifetime_ref.span, + "in-band lifetime definition") + .emit(); + }, + + Region::Static | + Region::EarlyBound(_, _, LifetimeDefOrigin::Explicit) | + Region::LateBound(_, _, LifetimeDefOrigin::Explicit) | + Region::LateBoundAnon(..) | + Region::Free(..) => {} + } + } + self.insert_lifetime(lifetime_ref, def); } else { struct_span_err!(self.sess, lifetime_ref.span, E0261, @@ -939,8 +1104,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { def: Def, depth: usize, params: &'tcx hir::PathParameters) { + if params.parenthesized { + let was_in_fn_syntax = self.is_in_fn_syntax; + self.is_in_fn_syntax = true; self.visit_fn_like_elision(params.inputs(), Some(¶ms.bindings[0].ty)); + self.is_in_fn_syntax = was_in_fn_syntax; return; } @@ -1261,7 +1430,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) { match lifetime { - Region::LateBound(debruijn, _) | + Region::LateBound(debruijn, _, _) | Region::LateBoundAnon(debruijn, _) if debruijn.depth < self.binder_depth => { self.have_bound_regions = true; @@ -1520,7 +1689,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - Scope::Binder { ref lifetimes, s } => { + Scope::Binder { ref lifetimes, s, next_early_index: _ } => { if let Some(&def) = lifetimes.get(&lifetime.name) { let node_id = self.hir_map .as_local_node_id(def.id().unwrap()) @@ -1549,7 +1718,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { probably a bug in syntax::fold"); } - debug!("{} resolved to {:?} span={:?}", + debug!("insert_lifetime: {} resolved to {:?} span={:?}", self.hir_map.node_to_string(lifetime_ref.id), def, self.sess.codemap().span_to_string(lifetime_ref.span)); @@ -1709,7 +1878,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, } fn visit_ty(&mut self, ty: &hir::Ty) { - if let hir::TyImplTraitExistential(_) = ty.node { + if let hir::TyImplTraitExistential(..) = ty.node { self.impl_trait = true; } intravisit::walk_ty(self, ty); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 355fb570c00..d093ab45b55 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -171,6 +171,15 @@ impl<'tcx> Mir<'tcx> { } #[inline] + pub fn basic_blocks_and_local_decls_mut(&mut self) -> ( + &mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, + &mut LocalDecls<'tcx>, + ) { + self.cache.invalidate(); + (&mut self.basic_blocks, &mut self.local_decls) + } + + #[inline] pub fn predecessors(&self) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> { self.cache.predecessors(self) } @@ -1375,10 +1384,14 @@ pub enum AggregateKind<'tcx> { /// The type is of the element Array(Ty<'tcx>), Tuple, - /// The second field is variant number (discriminant), it's equal to 0 - /// for struct and union expressions. The fourth field is active field - /// number and is present only for union expressions. + + /// The second field is variant number (discriminant), it's equal + /// to 0 for struct and union expressions. The fourth field is + /// active field number and is present only for union expressions + /// -- e.g. for a union expression `SomeUnion { c: .. }`, the + /// active field index would identity the field `c` Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>), + Closure(DefId, ClosureSubsts<'tcx>), Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>), } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 57fae2200e2..a56f850942c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1036,6 +1036,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "run all passes except translation; no output"), treat_err_as_bug: bool = (false, parse_bool, [TRACKED], "treat all errors that occur as bugs"), + external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], + "show macro backtraces even for non-local macros"), continue_parse_after_error: bool = (false, parse_bool, [TRACKED], "attempt to recover from parse errors (experimental)"), incremental: Option<String> = (None, parse_opt_string, [UNTRACKED], @@ -1142,6 +1144,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, saturating_float_casts: bool = (false, parse_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0"), + lower_128bit_ops: bool = (false, parse_bool, [TRACKED], + "rewrite operators on i128 and u128 into lang item calls (typically provided \ + by compiler-builtins) so translation doesn't need to support them"), } pub fn default_lib_output() -> CrateType { @@ -2100,7 +2105,7 @@ mod tests { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(!sess.diagnostic().can_emit_warnings); + assert!(!sess.diagnostic().flags.can_emit_warnings); } { @@ -2111,7 +2116,7 @@ mod tests { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(sess.diagnostic().can_emit_warnings); + assert!(sess.diagnostic().flags.can_emit_warnings); } { @@ -2121,7 +2126,7 @@ mod tests { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(sess.diagnostic().can_emit_warnings); + assert!(sess.diagnostic().flags.can_emit_warnings); } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 9f957cd7808..642153c08f6 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -355,12 +355,15 @@ impl Session { /// Analogous to calling methods on the given `DiagnosticBuilder`, but /// deduplicates on lint ID, span (if any), and message for this `Session` - /// if we're not outputting in JSON mode. fn diag_once<'a, 'b>(&'a self, diag_builder: &'b mut DiagnosticBuilder<'a>, method: DiagnosticBuilderMethod, lint: &'static lint::Lint, message: &str, span: Option<Span>) { - let mut do_method = || { + + let lint_id = DiagnosticMessageId::LintId(lint::LintId::of(lint)); + let id_span_message = (lint_id, span, message.to_owned()); + let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message); + if fresh { match method { DiagnosticBuilderMethod::Note => { diag_builder.note(message); @@ -369,22 +372,6 @@ impl Session { diag_builder.span_note(span.expect("span_note expects a span"), message); } } - }; - - match self.opts.error_format { - // when outputting JSON for tool consumption, the tool might want - // the duplicates - config::ErrorOutputType::Json(_) => { - do_method() - }, - _ => { - let lint_id = DiagnosticMessageId::LintId(lint::LintId::of(lint)); - let id_span_message = (lint_id, span, message.to_owned()); - let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message); - if fresh { - do_method() - } - } } } @@ -727,10 +714,12 @@ pub fn build_session_with_codemap(sopts: config::Options, .unwrap_or(false); let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow); - let can_print_warnings = !(warnings_allow || cap_lints_allow); + let can_emit_warnings = !(warnings_allow || cap_lints_allow); let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug; + let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; + let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(color_config), None) => { Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), false)) @@ -753,9 +742,14 @@ pub fn build_session_with_codemap(sopts: config::Options, }; let diagnostic_handler = - errors::Handler::with_emitter(can_print_warnings, - treat_err_as_bug, - emitter); + errors::Handler::with_emitter_and_flags( + emitter, + errors::HandlerFlags { + can_emit_warnings, + treat_err_as_bug, + external_macro_backtrace, + .. Default::default() + }); build_session_(sopts, local_crate_source_file, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7c38cf75b8d..46ec2be4a1f 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -643,8 +643,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { violations) } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - let found_kind = self.closure_kind(closure_def_id).unwrap(); + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap(); let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap(); let mut err = struct_span_err!( @@ -663,14 +663,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(tables) = self.in_progress_tables { let tables = tables.borrow(); let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id); - match tables.closure_kinds().get(closure_hir_id) { - Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => { - err.span_note(span, &format!( + match (found_kind, tables.closure_kind_origins().get(closure_hir_id)) { + (ty::ClosureKind::FnOnce, Some((span, name))) => { + err.span_note(*span, &format!( "closure is `FnOnce` because it moves the \ variable `{}` out of its environment", name)); }, - Some(&(ty::ClosureKind::FnMut, Some((span, name)))) => { - err.span_note(span, &format!( + (ty::ClosureKind::FnMut, Some((span, name))) => { + err.span_note(*span, &format!( "closure is `FnMut` because it mutates the \ variable `{}` here", name)); }, diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 297feead617..6b681322c9b 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -438,8 +438,8 @@ fn process_predicate<'a, 'gcx, 'tcx>( } } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - match selcx.infcx().closure_kind(closure_def_id) { + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + match selcx.infcx().closure_kind(closure_def_id, closure_substs) { Some(closure_kind) => { if closure_kind.extends(kind) { Ok(Some(vec![])) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 9c56df058c3..0cc755dc427 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1264,8 +1264,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>( vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>) -> Progress<'tcx> { - let gen_sig = selcx.infcx().generator_sig(vtable.closure_def_id).unwrap() - .subst(selcx.tcx(), vtable.substs.substs); + let gen_sig = vtable.substs.generator_poly_sig(vtable.closure_def_id, selcx.tcx()); let Normalized { value: gen_sig, obligations diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7716770d318..4bc3e2dd4d8 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -718,8 +718,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - match self.infcx.closure_kind(closure_def_id) { + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + match self.infcx.closure_kind(closure_def_id, closure_substs) { Some(closure_kind) => { if closure_kind.extends(kind) { EvaluatedToOk @@ -1593,10 +1593,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // touch bound regions, they just capture the in-scope // type/region parameters match obligation.self_ty().skip_binder().sty { - ty::TyClosure(closure_def_id, _) => { + ty::TyClosure(closure_def_id, closure_substs) => { debug!("assemble_unboxed_candidates: kind={:?} obligation={:?}", kind, obligation); - match self.infcx.closure_kind(closure_def_id) { + match self.infcx.closure_kind(closure_def_id, closure_substs) { Some(closure_kind) => { debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind); if closure_kind.extends(kind) { @@ -2726,7 +2726,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligations.push(Obligation::new( obligation.cause.clone(), obligation.param_env, - ty::Predicate::ClosureKind(closure_def_id, kind))); + ty::Predicate::ClosureKind(closure_def_id, substs, kind))); Ok(VtableClosureData { closure_def_id, @@ -3184,8 +3184,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { substs: ty::ClosureSubsts<'tcx>) -> ty::PolyTraitRef<'tcx> { - let gen_sig = self.infcx.generator_sig(closure_def_id).unwrap() - .subst(self.tcx(), substs.substs); + let gen_sig = substs.generator_poly_sig(closure_def_id, self.tcx()); let ty::Binder((trait_ref, ..)) = self.tcx().generator_trait_ref_and_outputs(obligation.predicate.def_id(), obligation.predicate.0.self_ty(), // (1) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 42e0834e8e4..898accb9021 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -43,8 +43,8 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data), - ty::Predicate::ClosureKind(closure_def_id, kind) => - ty::Predicate::ClosureKind(closure_def_id, kind), + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind), ty::Predicate::Subtype(ref data) => ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data)), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 904f9a09125..b0dce1f6684 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -356,16 +356,9 @@ pub struct TypeckTables<'tcx> { /// Borrows pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>, - /// Records the type of each closure. - closure_tys: ItemLocalMap<ty::PolyFnSig<'tcx>>, - - /// Records the kind of each closure and the span and name of the variable - /// that caused the closure to be this kind. - closure_kinds: ItemLocalMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>, - - generator_sigs: ItemLocalMap<Option<ty::GenSig<'tcx>>>, - - generator_interiors: ItemLocalMap<ty::GeneratorInterior<'tcx>>, + /// Records the reasons that we picked the kind of each closure; + /// not all closures are present in the map. + closure_kind_origins: ItemLocalMap<(Span, ast::Name)>, /// For each fn, records the "liberated" types of its arguments /// and return type. Liberated means that all bound regions @@ -411,10 +404,7 @@ impl<'tcx> TypeckTables<'tcx> { pat_binding_modes: ItemLocalMap(), pat_adjustments: ItemLocalMap(), upvar_capture_map: FxHashMap(), - generator_sigs: ItemLocalMap(), - generator_interiors: ItemLocalMap(), - closure_tys: ItemLocalMap(), - closure_kinds: ItemLocalMap(), + closure_kind_origins: ItemLocalMap(), liberated_fn_sigs: ItemLocalMap(), fru_field_types: ItemLocalMap(), cast_kinds: ItemLocalMap(), @@ -609,34 +599,17 @@ impl<'tcx> TypeckTables<'tcx> { self.upvar_capture_map[&upvar_id] } - pub fn closure_tys(&self) -> LocalTableInContext<ty::PolyFnSig<'tcx>> { - LocalTableInContext { - local_id_root: self.local_id_root, - data: &self.closure_tys - } - } - - pub fn closure_tys_mut(&mut self) - -> LocalTableInContextMut<ty::PolyFnSig<'tcx>> { - LocalTableInContextMut { - local_id_root: self.local_id_root, - data: &mut self.closure_tys - } - } - - pub fn closure_kinds(&self) -> LocalTableInContext<(ty::ClosureKind, - Option<(Span, ast::Name)>)> { + pub fn closure_kind_origins(&self) -> LocalTableInContext<(Span, ast::Name)> { LocalTableInContext { local_id_root: self.local_id_root, - data: &self.closure_kinds + data: &self.closure_kind_origins } } - pub fn closure_kinds_mut(&mut self) - -> LocalTableInContextMut<(ty::ClosureKind, Option<(Span, ast::Name)>)> { + pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<(Span, ast::Name)> { LocalTableInContextMut { local_id_root: self.local_id_root, - data: &mut self.closure_kinds + data: &mut self.closure_kind_origins } } @@ -681,42 +654,6 @@ impl<'tcx> TypeckTables<'tcx> { data: &mut self.cast_kinds } } - - pub fn generator_sigs(&self) - -> LocalTableInContext<Option<ty::GenSig<'tcx>>> - { - LocalTableInContext { - local_id_root: self.local_id_root, - data: &self.generator_sigs, - } - } - - pub fn generator_sigs_mut(&mut self) - -> LocalTableInContextMut<Option<ty::GenSig<'tcx>>> - { - LocalTableInContextMut { - local_id_root: self.local_id_root, - data: &mut self.generator_sigs, - } - } - - pub fn generator_interiors(&self) - -> LocalTableInContext<ty::GeneratorInterior<'tcx>> - { - LocalTableInContext { - local_id_root: self.local_id_root, - data: &self.generator_interiors, - } - } - - pub fn generator_interiors_mut(&mut self) - -> LocalTableInContextMut<ty::GeneratorInterior<'tcx>> - { - LocalTableInContextMut { - local_id_root: self.local_id_root, - data: &mut self.generator_interiors, - } - } } impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> { @@ -732,8 +669,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> { ref pat_binding_modes, ref pat_adjustments, ref upvar_capture_map, - ref closure_tys, - ref closure_kinds, + ref closure_kind_origins, ref liberated_fn_sigs, ref fru_field_types, @@ -742,8 +678,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> { ref used_trait_imports, tainted_by_errors, ref free_region_map, - ref generator_sigs, - ref generator_interiors, } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -775,13 +709,10 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> { hcx.def_path_hash(closure_def_id)) }); - closure_tys.hash_stable(hcx, hasher); - closure_kinds.hash_stable(hcx, hasher); + closure_kind_origins.hash_stable(hcx, hasher); liberated_fn_sigs.hash_stable(hcx, hasher); fru_field_types.hash_stable(hcx, hasher); cast_kinds.hash_stable(hcx, hasher); - generator_sigs.hash_stable(hcx, hasher); - generator_interiors.hash_stable(hcx, hasher); used_trait_imports.hash_stable(hcx, hasher); tainted_by_errors.hash_stable(hcx, hasher); free_region_map.hash_stable(hcx, hasher); @@ -1981,11 +1912,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn mk_closure(self, closure_id: DefId, - substs: &'tcx Substs<'tcx>) - -> Ty<'tcx> { - self.mk_closure_from_closure_substs(closure_id, ClosureSubsts { - substs, - }) + substs: ClosureSubsts<'tcx>) + -> Ty<'tcx> { + self.mk_closure_from_closure_substs(closure_id, substs) } pub fn mk_closure_from_closure_substs(self, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 228ca76ed9a..cb68e576e5a 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -49,7 +49,11 @@ pub enum TypeError<'tcx> { FloatMismatch(ExpectedFound<ast::FloatTy>), Traits(ExpectedFound<DefId>), VariadicMismatch(ExpectedFound<bool>), - CyclicTy, + + /// Instantiating a type variable with the given type would have + /// created a cycle (because it appears somewhere within that + /// type). + CyclicTy(Ty<'tcx>), ProjectionMismatched(ExpectedFound<DefId>), ProjectionBoundsLength(ExpectedFound<usize>), TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>), @@ -84,7 +88,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } match *self { - CyclicTy => write!(f, "cyclic type of infinite size"), + CyclicTy(_) => write!(f, "cyclic type of infinite size"), Mismatch => write!(f, "types differ"), UnsafetyMismatch(values) => { write!(f, "expected {} fn, found {} fn", @@ -304,6 +308,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.note_and_explain_type_err(db, &err, sp); } + CyclicTy(ty) => { + // Watch out for various cases of cyclic types and try to explain. + if ty.is_closure() || ty.is_generator() { + db.note("closures cannot capture themselves or take themselves as argument;\n\ + this error may be the result of a recent compiler bug-fix,\n\ + see https://github.com/rust-lang/rust/issues/46062 for more details"); + } + } _ => {} } } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 6ea953c3f73..70636f8b6fe 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -189,7 +189,7 @@ fn resolve_closure<'a, 'tcx>( requested_kind: ty::ClosureKind) -> Instance<'tcx> { - let actual_kind = tcx.closure_kind(def_id); + let actual_kind = substs.closure_kind(def_id, tcx); match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2f648e8d3ff..a477e779af9 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -166,20 +166,12 @@ define_maps! { <'tcx> /// for trans. This is also the only query that can fetch non-local MIR, at present. [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, - /// Type of each closure. The def ID is the ID of the - /// expression defining the closure. - [] fn closure_kind: ClosureKind(DefId) -> ty::ClosureKind, - /// The result of unsafety-checking this def-id. [] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult, /// The signature of functions and closures. [] fn fn_sig: FnSignature(DefId) -> ty::PolyFnSig<'tcx>, - /// Records the signature of each generator. The def ID is the ID of the - /// expression defining the closure. - [] fn generator_sig: GenSignature(DefId) -> Option<ty::PolyGenSig<'tcx>>, - /// Caches CoerceUnsized kinds for impls on custom types. [] fn coerce_unsized_info: CoerceUnsizedInfo(DefId) -> ty::adjustment::CoerceUnsizedInfo, diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 53ca9b3851d..6f55df76df4 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -197,6 +197,10 @@ impl<'sess> OnDiskCache<'sess> { encoder.encode_tagged(PREV_DIAGNOSTICS_TAG, &diagnostics)?; + // Load everything into memory so we can write it out to the on-disk + // cache. The vast majority of cacheable query results should already + // be in memory, so this should be a cheap operation. + tcx.dep_graph.exec_cache_promotions(tcx); // Encode query results let mut query_result_index = EncodedQueryResultIndex::new(); diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 1ca8fc6eb48..c469991d848 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -782,9 +782,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::IsAutoImpl => { force!(is_auto_impl, def_id!()); } DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); } DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); } - DepKind::ClosureKind => { force!(closure_kind, def_id!()); } DepKind::FnSignature => { force!(fn_sig, def_id!()); } - DepKind::GenSignature => { force!(generator_sig, def_id!()); } DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); } DepKind::ItemVariances => { force!(variances_of, def_id!()); } DepKind::IsConstFn => { force!(is_const_fn, def_id!()); } @@ -900,3 +898,58 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, true } + + +// FIXME(#45015): Another piece of boilerplate code that could be generated in +// a combined define_dep_nodes!()/define_maps!() macro. +macro_rules! impl_load_from_cache { + ($($dep_kind:ident => $query_name:ident,)*) => { + impl DepNode { + // Check whether the query invocation corresponding to the given + // DepNode is eligible for on-disk-caching. + pub fn cache_on_disk(&self, tcx: TyCtxt) -> bool { + use ty::maps::queries; + use ty::maps::QueryDescription; + + match self.kind { + $(DepKind::$dep_kind => { + let def_id = self.extract_def_id(tcx).unwrap(); + queries::$query_name::cache_on_disk(def_id) + })* + _ => false + } + } + + // This is method will execute the query corresponding to the given + // DepNode. It is only expected to work for DepNodes where the + // above `cache_on_disk` methods returns true. + // Also, as a sanity check, it expects that the corresponding query + // invocation has been marked as green already. + pub fn load_from_on_disk_cache(&self, tcx: TyCtxt) { + match self.kind { + $(DepKind::$dep_kind => { + debug_assert!(tcx.dep_graph + .node_color(self) + .map(|c| c.is_green()) + .unwrap_or(false)); + + let def_id = self.extract_def_id(tcx).unwrap(); + let _ = tcx.$query_name(def_id); + })* + _ => { + bug!() + } + } + } + } + } +} + +impl_load_from_cache!( + TypeckTables => typeck_tables_of, + MirOptimized => optimized_mir, + UnsafetyCheckResult => unsafety_check_result, + BorrowCheck => borrowck, + MirBorrowCheck => mir_borrowck, + MirConstQualif => mir_const_qualif, +); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 48ec92a255b..583dcb46f00 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -896,7 +896,7 @@ pub enum Predicate<'tcx> { /// No direct syntax. May be thought of as `where T : FnFoo<...>` /// for some substitutions `...` and T being a closure type. /// Satisfied (or refuted) once we know the closure's kind. - ClosureKind(DefId, ClosureKind), + ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind), /// `T1 <: T2` Subtype(PolySubtypePredicate<'tcx>), @@ -999,8 +999,8 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> { Predicate::WellFormed(data.subst(tcx, substs)), Predicate::ObjectSafe(trait_def_id) => Predicate::ObjectSafe(trait_def_id), - Predicate::ClosureKind(closure_def_id, kind) => - Predicate::ClosureKind(closure_def_id, kind), + Predicate::ClosureKind(closure_def_id, closure_substs, kind) => + Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind), Predicate::ConstEvaluatable(def_id, const_substs) => Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)), } @@ -1182,8 +1182,8 @@ impl<'tcx> Predicate<'tcx> { ty::Predicate::ObjectSafe(_trait_def_id) => { vec![] } - ty::Predicate::ClosureKind(_closure_def_id, _kind) => { - vec![] + ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => { + closure_substs.substs.types().collect() } ty::Predicate::ConstEvaluatable(_, substs) => { substs.types().collect() @@ -1932,6 +1932,9 @@ pub enum ClosureKind { } impl<'a, 'tcx> ClosureKind { + // This is the initial value used when doing upvar inference. + pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; + pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId { match *self { ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem), @@ -1957,6 +1960,16 @@ impl<'a, 'tcx> ClosureKind { _ => false, } } + + /// Returns the representative scalar type for this closure kind. + /// See `TyS::to_opt_closure_kind` for more details. + pub fn to_ty(self, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { + match self { + ty::ClosureKind::Fn => tcx.types.i8, + ty::ClosureKind::FnMut => tcx.types.i16, + ty::ClosureKind::FnOnce => tcx.types.i32, + } + } } impl<'tcx> TyS<'tcx> { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index e5c24b4fcf9..83207fbe3c3 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -211,8 +211,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> { ty::Predicate::WellFormed(ty) => { tcx.lift(&ty).map(ty::Predicate::WellFormed) } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - Some(ty::Predicate::ClosureKind(closure_def_id, kind)) + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + tcx.lift(&closure_substs) + .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id, + closure_substs, + kind)) } ty::Predicate::ObjectSafe(trait_def_id) => { Some(ty::Predicate::ObjectSafe(trait_def_id)) @@ -420,7 +423,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { FloatMismatch(x) => FloatMismatch(x), Traits(x) => Traits(x), VariadicMismatch(x) => VariadicMismatch(x), - CyclicTy => CyclicTy, + CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)), ProjectionMismatched(x) => ProjectionMismatched(x), ProjectionBoundsLength(x) => ProjectionBoundsLength(x), @@ -966,8 +969,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { ty::Predicate::Projection(binder.fold_with(folder)), ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data.fold_with(folder)), - ty::Predicate::ClosureKind(closure_def_id, kind) => - ty::Predicate::ClosureKind(closure_def_id, kind), + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => + ty::Predicate::ClosureKind(closure_def_id, closure_substs.fold_with(folder), kind), ty::Predicate::ObjectSafe(trait_def_id) => ty::Predicate::ObjectSafe(trait_def_id), ty::Predicate::ConstEvaluatable(def_id, substs) => @@ -984,7 +987,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor), ty::Predicate::Projection(ref binder) => binder.visit_with(visitor), ty::Predicate::WellFormed(data) => data.visit_with(visitor), - ty::Predicate::ClosureKind(_closure_def_id, _kind) => false, + ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => + closure_substs.visit_with(visitor), ty::Predicate::ObjectSafe(_trait_def_id) => false, ty::Predicate::ConstEvaluatable(_def_id, substs) => substs.visit_with(visitor), } @@ -1169,7 +1173,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { FloatMismatch(x) => FloatMismatch(x), Traits(x) => Traits(x), VariadicMismatch(x) => VariadicMismatch(x), - CyclicTy => CyclicTy, + CyclicTy(t) => CyclicTy(t.fold_with(folder)), ProjectionMismatched(x) => ProjectionMismatched(x), ProjectionBoundsLength(x) => ProjectionBoundsLength(x), Sorts(x) => Sorts(x.fold_with(folder)), @@ -1196,6 +1200,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { OldStyleLUB(ref x) => x.visit_with(visitor), TyParamDefaultMismatch(ref x) => x.visit_with(visitor), ExistentialMismatch(x) => x.visit_with(visitor), + CyclicTy(t) => t.visit_with(visitor), Mismatch | Mutability | TupleSize(_) | @@ -1205,7 +1210,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { FloatMismatch(_) | Traits(_) | VariadicMismatch(_) | - CyclicTy | ProjectionMismatched(_) | ProjectionBoundsLength(_) => false, } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 65406c3d16c..caf78309cc2 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -174,16 +174,26 @@ pub enum TypeVariants<'tcx> { /// A closure can be modeled as a struct that looks like: /// -/// struct Closure<'l0...'li, T0...Tj, U0...Uk> { +/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> { /// upvar0: U0, /// ... /// upvark: Uk /// } /// -/// where 'l0...'li and T0...Tj are the lifetime and type parameters -/// in scope on the function that defined the closure, and U0...Uk are -/// type parameters representing the types of its upvars (borrowed, if -/// appropriate). +/// where: +/// +/// - 'l0...'li and T0...Tj are the lifetime and type parameters +/// in scope on the function that defined the closure, +/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This +/// is rather hackily encoded via a scalar type. See +/// `TyS::to_opt_closure_kind` for details. +/// - CS represents the *closure signature*, representing as a `fn()` +/// type. For example, `fn(u32, u32) -> u32` would mean that the closure +/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait +/// specified above. +/// - U0...Uk are type parameters representing the types of its upvars +/// (borrowed, if appropriate; that is, if Ui represents a by-ref upvar, +/// and the up-var has the type `Foo`, then `Ui = &Foo`). /// /// So, for example, given this function: /// @@ -246,6 +256,17 @@ pub enum TypeVariants<'tcx> { /// closure C wind up influencing the decisions we ought to make for /// closure C (which would then require fixed point iteration to /// handle). Plus it fixes an ICE. :P +/// +/// ## Generators +/// +/// Perhaps surprisingly, `ClosureSubsts` are also used for +/// generators. In that case, what is written above is only half-true +/// -- the set of type parameters is similar, but the role of CK and +/// CS are different. CK represents the "yield type" and CS +/// represents the "return type" of the generator. +/// +/// It'd be nice to split this struct into ClosureSubsts and +/// GeneratorSubsts, I believe. -nmatsakis #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct ClosureSubsts<'tcx> { /// Lifetime and type parameters from the enclosing function, @@ -256,14 +277,97 @@ pub struct ClosureSubsts<'tcx> { pub substs: &'tcx Substs<'tcx>, } -impl<'a, 'gcx, 'acx, 'tcx> ClosureSubsts<'tcx> { +/// Struct returned by `split()`. Note that these are subslices of the +/// parent slice and not canonical substs themselves. +struct SplitClosureSubsts<'tcx> { + closure_kind_ty: Ty<'tcx>, + closure_sig_ty: Ty<'tcx>, + upvar_kinds: &'tcx [Kind<'tcx>], +} + +impl<'tcx> ClosureSubsts<'tcx> { + /// Divides the closure substs into their respective + /// components. Single source of truth with respect to the + /// ordering. + fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitClosureSubsts<'tcx> { + let generics = tcx.generics_of(def_id); + let parent_len = generics.parent_count(); + SplitClosureSubsts { + closure_kind_ty: self.substs[parent_len].as_type().expect("CK should be a type"), + closure_sig_ty: self.substs[parent_len + 1].as_type().expect("CS should be a type"), + upvar_kinds: &self.substs[parent_len + 2..], + } + } + #[inline] - pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'acx>) -> + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> impl Iterator<Item=Ty<'tcx>> + 'tcx { - let generics = tcx.generics_of(def_id); - self.substs[self.substs.len()-generics.own_count()..].iter().map( - |t| t.as_type().expect("unexpected region in upvars")) + let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx); + upvar_kinds.iter().map(|t| t.as_type().expect("upvar should be type")) + } + + /// Returns the closure kind for this closure; may return a type + /// variable during inference. To get the closure kind during + /// inference, use `infcx.closure_kind(def_id, substs)`. + pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.split(def_id, tcx).closure_kind_ty + } + + /// Returns the type representing the closure signature for this + /// closure; may contain type variables during inference. To get + /// the closure signature during inference, use + /// `infcx.fn_sig(def_id)`. + pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.split(def_id, tcx).closure_sig_ty + } + + /// Returns the type representing the yield type of the generator. + pub fn generator_yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.closure_kind_ty(def_id, tcx) + } + + /// Returns the type representing the return type of the generator. + pub fn generator_return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + self.closure_sig_ty(def_id, tcx) + } + + /// Return the "generator signature", which consists of its yield + /// and return types. + /// + /// NB. Some bits of the code prefers to see this wrapped in a + /// binder, but it never contains bound regions. Probably this + /// function should be removed. + pub fn generator_poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> { + ty::Binder(self.generator_sig(def_id, tcx)) + } + + /// Return the "generator signature", which consists of its yield + /// and return types. + pub fn generator_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> { + ty::GenSig { + yield_ty: self.generator_yield_ty(def_id, tcx), + return_ty: self.generator_return_ty(def_id, tcx), + } + } +} + +impl<'tcx> ClosureSubsts<'tcx> { + /// Returns the closure kind for this closure; only usable outside + /// of an inference context, because in that context we know that + /// there are no type variables. + pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::ClosureKind { + self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap() + } + + /// Extracts the signature from the closure; only usable outside + /// of an inference context, because in that context we know that + /// there are no type variables. + pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> { + match self.closure_sig_ty(def_id, tcx).sty { + ty::TyFnPtr(sig) => sig, + ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t), + } } } @@ -894,22 +998,11 @@ pub struct FloatVid { pub index: u32, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, PartialOrd, Ord)] -pub struct RegionVid { - pub index: u32, -} - -// FIXME: We could convert this to use `newtype_index!` -impl Idx for RegionVid { - fn new(value: usize) -> Self { - assert!(value < ::std::u32::MAX as usize); - RegionVid { index: value as u32 } - } - - fn index(self) -> usize { - self.index as usize - } -} +newtype_index!(RegionVid + { + pub idx + DEBUG_FORMAT = custom, + }); #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] pub struct SkolemizedRegionVid { @@ -1261,6 +1354,15 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + pub fn is_enum(&self) -> bool { + match self.sty { + TyAdt(adt_def, _) => { + adt_def.is_enum() + } + _ => false, + } + } + pub fn is_closure(&self) -> bool { match self.sty { TyClosure(..) => true, @@ -1268,6 +1370,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + pub fn is_generator(&self) -> bool { + match self.sty { + TyGenerator(..) => true, + _ => false, + } + } + pub fn is_integral(&self) -> bool { match self.sty { TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true, @@ -1275,6 +1384,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + pub fn is_fresh_ty(&self) -> bool { + match self.sty { + TyInfer(FreshTy(_)) => true, + _ => false, + } + } + pub fn is_fresh(&self) -> bool { match self.sty { TyInfer(FreshTy(_)) => true, @@ -1442,6 +1558,37 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } } + + /// When we create a closure, we record its kind (i.e., what trait + /// it implements) into its `ClosureSubsts` using a type + /// parameter. This is kind of a phantom type, except that the + /// most convenient thing for us to are the integral types. This + /// function converts such a special type into the closure + /// kind. To go the other way, use + /// `tcx.closure_kind_ty(closure_kind)`. + /// + /// Note that during type checking, we use an inference variable + /// to represent the closure kind, because it has not yet been + /// inferred. Once [upvar inference] is complete, that type varibale + /// will be unified. + /// + /// [upvar inference]: src/librustc_typeck/check/upvar.rs + pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> { + match self.sty { + TyInt(int_ty) => match int_ty { + ast::IntTy::I8 => Some(ty::ClosureKind::Fn), + ast::IntTy::I16 => Some(ty::ClosureKind::FnMut), + ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce), + _ => bug!("cannot convert type `{:?}` to a closure kind", self), + }, + + TyInfer(_) => None, + + TyError => Some(ty::ClosureKind::Fn), + + _ => bug!("cannot convert type `{:?}` to a closure kind", self), + } + } } /// Typed constant value. diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 83222e79a12..80b113dfdf5 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -220,11 +220,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { tcx.intern_substs(&result) } - fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - defs: &ty::Generics, - mk_region: &mut FR, - mk_type: &mut FT) + pub fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + defs: &ty::Generics, + mk_region: &mut FR, + mk_type: &mut FT) where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index c631e2c4db5..a851ccc34bf 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -336,14 +336,50 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } } - ty::TyGenerator(..) | ty::TyClosure(..) => { - // the types in a closure or generator are always the types of - // local variables (or possibly references to local - // variables), we'll walk those. + ty::TyGenerator(..) => { + // Walk ALL the types in the generator: this will + // include the upvar types as well as the yield + // type. Note that this is mildly distinct from + // the closure case, where we have to be careful + // about the signature of the closure. We don't + // have the problem of implied bounds here since + // generators don't take arguments. + } + + ty::TyClosure(def_id, substs) => { + // Only check the upvar types for WF, not the rest + // of the types within. This is needed because we + // capture the signature and it may not be WF + // without the implied bounds. Consider a closure + // like `|x: &'a T|` -- it may be that `T: 'a` is + // not known to hold in the creator's context (and + // indeed the closure may not be invoked by its + // creator, but rather turned to someone who *can* + // verify that). + // + // The special treatment of closures here really + // ought not to be necessary either; the problem + // is related to #25860 -- there is no way for us + // to express a fn type complete with the implied + // bounds that it is assuming. I think in reality + // the WF rules around fn are a bit messed up, and + // that is the rot problem: `fn(&'a T)` should + // probably always be WF, because it should be + // shorthand for something like `where(T: 'a) { + // fn(&'a T) }`, as discussed in #25860. // - // (Though, local variables are probably not - // needed, as they are separately checked w/r/t - // WFedness.) + // Note that we are also skipping the generic + // types. This is consistent with the `outlives` + // code, but anyway doesn't matter: within the fn + // body where they are created, the generics will + // always be WF, and outside of that fn body we + // are not directly inspecting closure types + // anyway, except via auto trait matching (which + // only inspects the upvar types). + subtys.skip_current_subtree(); // subtree handled by compute_projection + for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) { + self.compute(upvar_ty); + } } ty::TyFnDef(..) | ty::TyFnPtr(_) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index acb929981fb..9ff3d73f5c4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -726,7 +726,7 @@ define_print! { } } ty::ReVar(region_vid) if cx.identify_regions => { - write!(f, "'{}rv", region_vid.index) + write!(f, "'{}rv", region_vid.index()) } ty::ReScope(_) | ty::ReVar(_) | @@ -850,7 +850,7 @@ impl fmt::Debug for ty::FloatVid { impl fmt::Debug for ty::RegionVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "'_#{}r", self.index) + write!(f, "'_#{}r", self.index()) } } @@ -1015,6 +1015,10 @@ define_print! { TyForeign(def_id) => parameterized(f, subst::Substs::empty(), def_id, &[]), TyProjection(ref data) => data.print(f, cx), TyAnon(def_id, substs) => { + if cx.is_verbose { + return write!(f, "TyAnon({:?}, {:?})", def_id, substs); + } + ty::tls::with(|tcx| { // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. @@ -1257,7 +1261,7 @@ define_print! { ty::tls::with(|tcx| { write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id)) }), - ty::Predicate::ClosureKind(closure_def_id, kind) => + 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) @@ -1281,8 +1285,8 @@ define_print! { ty::Predicate::ObjectSafe(trait_def_id) => { write!(f, "ObjectSafe({:?})", trait_def_id) } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - write!(f, "ClosureKind({:?}, {:?})", closure_def_id, kind) + 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_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 7b09e45fe96..36b397bbbe5 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -655,10 +655,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { ty::TypeVariants::TyClosure(id, _) => { let node_id = self.tcx.hir.as_local_node_id(id).unwrap(); let hir_id = self.tcx.hir.node_to_hir_id(node_id); - if let Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) = - self.tables.closure_kinds().get(hir_id) - { - err.span_note(span, &format!( + if let Some((span, name)) = self.tables.closure_kind_origins().get(hir_id) { + err.span_note(*span, &format!( "closure cannot be invoked more than once because \ it moves the variable `{}` out of its environment", name diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 78aacd49f80..c8b71be86f8 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -15,6 +15,7 @@ #![allow(non_camel_case_types)] +#![feature(match_default_bindings)] #![feature(quote)] #[macro_use] extern crate log; diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 1e67461e055..1b39e029604 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -111,7 +111,7 @@ impl<A: Array> ArrayVec<A> { // Memory safety // // When the Drain is first created, it shortens the length of - // the source vector to make sure no uninitalized or moved-from elements + // the source vector to make sure no uninitialized or moved-from elements // are accessible at all if the Drain's destructor never gets to run. // // Drain will ptr::read out the values to remove. diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 85ccacb43fb..bf1579acf53 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -77,6 +77,7 @@ pub enum PpFlowGraphMode { pub enum PpMode { PpmSource(PpSourceMode), PpmHir(PpSourceMode), + PpmHirTree(PpSourceMode), PpmFlowGraph(PpFlowGraphMode), PpmMir, PpmMirCFG, @@ -93,6 +94,7 @@ impl PpMode { PpmSource(PpmExpandedIdentified) | PpmSource(PpmExpandedHygiene) | PpmHir(_) | + PpmHirTree(_) | PpmMir | PpmMirCFG | PpmFlowGraph(_) => true, @@ -125,6 +127,7 @@ pub fn parse_pretty(sess: &Session, ("hir", true) => PpmHir(PpmNormal), ("hir,identified", true) => PpmHir(PpmIdentified), ("hir,typed", true) => PpmHir(PpmTyped), + ("hir-tree", true) => PpmHirTree(PpmNormal), ("mir", true) => PpmMir, ("mir-cfg", true) => PpmMirCFG, ("flowgraph", true) => PpmFlowGraph(PpFlowGraphMode::Default), @@ -971,6 +974,23 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, }) } + (PpmHirTree(s), None) => { + let out: &mut Write = &mut out; + s.call_with_pp_support_hir(sess, + cstore, + hir_map, + analysis, + resolutions, + arena, + arenas, + output_filenames, + crate_name, + move |_annotation, krate| { + debug!("pretty printing source code {:?}", s); + write!(out, "{:#?}", krate) + }) + } + (PpmHir(s), Some(uii)) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(sess, @@ -1005,6 +1025,28 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, pp_state.s.eof() }) } + + (PpmHirTree(s), Some(uii)) => { + let out: &mut Write = &mut out; + s.call_with_pp_support_hir(sess, + cstore, + hir_map, + analysis, + resolutions, + arena, + arenas, + output_filenames, + crate_name, + move |_annotation, _krate| { + debug!("pretty printing source code {:?}", s); + for node_id in uii.all_matching_node_ids(hir_map) { + let node = hir_map.get(node_id); + write!(out, "{:#?}", node)?; + } + Ok(()) + }) + } + _ => unreachable!(), } .unwrap(); diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 40b5810454b..27e895164e7 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -23,7 +23,7 @@ use syntax_pos::{MultiSpan, Span}; #[must_use] #[derive(Clone)] pub struct DiagnosticBuilder<'a> { - handler: &'a Handler, + pub handler: &'a Handler, diagnostic: Diagnostic, } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 57523d2c058..17ed1734fe2 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -64,8 +64,11 @@ impl Emitter for EmitterWriter { } } - self.fix_multispans_in_std_macros(&mut primary_span, &mut children); + if !db.handler.flags.external_macro_backtrace { + self.fix_multispans_in_std_macros(&mut primary_span, &mut children); + } self.emit_messages_default(&db.level, + db.handler.flags.external_macro_backtrace, &db.styled_message(), &db.code, &primary_span, @@ -793,8 +796,11 @@ impl EmitterWriter { if spans_updated { children.push(SubDiagnostic { level: Level::Note, - message: vec![("this error originates in a macro outside of the current crate" - .to_string(), Style::NoStyle)], + message: vec![ + (["this error originates in a macro outside of the current crate", + "(run with -Z external-macro-backtrace for more info)"].join(" "), + Style::NoStyle), + ], span: MultiSpan::new(), render_span: None, }); @@ -882,6 +888,7 @@ impl EmitterWriter { msg: &Vec<(String, Style)>, code: &Option<DiagnosticId>, level: &Level, + external_macro_backtrace: bool, max_line_num_len: usize, is_secondary: bool) -> io::Result<()> { @@ -1079,6 +1086,12 @@ impl EmitterWriter { } } + if external_macro_backtrace { + if let Some(ref primary_span) = msp.primary_span().as_ref() { + self.render_macro_backtrace_old_school(primary_span, &mut buffer)?; + } + } + // final step: take our styled buffer, render it, then output it emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; @@ -1170,6 +1183,7 @@ impl EmitterWriter { } fn emit_messages_default(&mut self, level: &Level, + external_macro_backtrace: bool, message: &Vec<(String, Style)>, code: &Option<DiagnosticId>, span: &MultiSpan, @@ -1178,7 +1192,13 @@ impl EmitterWriter { let max_line_num = self.get_max_line_num(span, children); let max_line_num_len = max_line_num.to_string().len(); - match self.emit_message_default(span, message, code, level, max_line_num_len, false) { + match self.emit_message_default(span, + message, + code, + level, + external_macro_backtrace, + max_line_num_len, + false) { Ok(()) => { if !children.is_empty() { let mut buffer = StyledBuffer::new(); @@ -1198,6 +1218,7 @@ impl EmitterWriter { &child.styled_message(), &None, &child.level, + external_macro_backtrace, max_line_num_len, true) { Err(e) => panic!("failed to emit error: {}", e), @@ -1226,6 +1247,30 @@ impl EmitterWriter { } } } + + fn render_macro_backtrace_old_school(&self, + sp: &Span, + buffer: &mut StyledBuffer) -> io::Result<()> { + if let Some(ref cm) = self.cm { + for trace in sp.macro_backtrace().iter().rev() { + let line_offset = buffer.num_lines(); + + let mut diag_string = + format!("in this expansion of {}", trace.macro_decl_name); + if let Some(def_site_span) = trace.def_site_span { + diag_string.push_str( + &format!(" (defined in {})", + cm.span_to_filename(def_site_span))); + } + let snippet = cm.span_to_string(trace.call_site); + buffer.append(line_offset, &format!("{} ", snippet), Style::NoStyle); + buffer.append(line_offset, "note", Style::Level(Level::Note)); + buffer.append(line_offset, ": ", Style::NoStyle); + buffer.append(line_offset, &diag_string, Style::OldSchoolNoteText); + } + } + Ok(()) + } } fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) { @@ -1415,7 +1460,7 @@ impl Destination { } } Style::Quotation => {} - Style::HeaderMsg => { + Style::OldSchoolNoteText | Style::HeaderMsg => { self.start_attr(term::Attr::Bold)?; if cfg!(windows) { self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE))?; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e83ac8831de..605cfc5ed12 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -233,10 +233,10 @@ pub use diagnostic_builder::DiagnosticBuilder; /// (fatal, bug, unimpl) may cause immediate exit, /// others log errors for later reporting. pub struct Handler { + pub flags: HandlerFlags, + err_count: Cell<usize>, emitter: RefCell<Box<Emitter>>, - pub can_emit_warnings: bool, - treat_err_as_bug: bool, continue_after_error: Cell<bool>, delayed_span_bug: RefCell<Option<Diagnostic>>, tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>, @@ -247,25 +247,55 @@ pub struct Handler { emitted_diagnostics: RefCell<FxHashSet<u128>>, } +#[derive(Default)] +pub struct HandlerFlags { + pub can_emit_warnings: bool, + pub treat_err_as_bug: bool, + pub external_macro_backtrace: bool, +} + impl Handler { pub fn with_tty_emitter(color_config: ColorConfig, can_emit_warnings: bool, treat_err_as_bug: bool, cm: Option<Rc<CodeMapper>>) -> Handler { + Handler::with_tty_emitter_and_flags( + color_config, + cm, + HandlerFlags { + can_emit_warnings, + treat_err_as_bug, + .. Default::default() + }) + } + + pub fn with_tty_emitter_and_flags(color_config: ColorConfig, + cm: Option<Rc<CodeMapper>>, + flags: HandlerFlags) + -> Handler { let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false)); - Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter) + Handler::with_emitter_and_flags(emitter, flags) } pub fn with_emitter(can_emit_warnings: bool, treat_err_as_bug: bool, e: Box<Emitter>) -> Handler { + Handler::with_emitter_and_flags( + e, + HandlerFlags { + can_emit_warnings, + treat_err_as_bug, + .. Default::default() + }) + } + + pub fn with_emitter_and_flags(e: Box<Emitter>, flags: HandlerFlags) -> Handler { Handler { + flags, err_count: Cell::new(0), emitter: RefCell::new(e), - can_emit_warnings, - treat_err_as_bug, continue_after_error: Cell::new(true), delayed_span_bug: RefCell::new(None), tracked_diagnostics: RefCell::new(None), @@ -293,7 +323,7 @@ impl Handler { -> DiagnosticBuilder<'a> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); - if !self.can_emit_warnings { + if !self.flags.can_emit_warnings { result.cancel(); } result @@ -306,14 +336,14 @@ impl Handler { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); result.code(code); - if !self.can_emit_warnings { + if !self.flags.can_emit_warnings { result.cancel(); } result } pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); - if !self.can_emit_warnings { + if !self.flags.can_emit_warnings { result.cancel(); } result @@ -376,7 +406,7 @@ impl Handler { } fn panic_if_treat_err_as_bug(&self) { - if self.treat_err_as_bug { + if self.flags.treat_err_as_bug { panic!("encountered error with `-Z treat_err_as_bug"); } } @@ -418,7 +448,7 @@ impl Handler { panic!(ExplicitBug); } pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) { - if self.treat_err_as_bug { + if self.flags.treat_err_as_bug { self.span_bug(sp, msg); } let mut diagnostic = Diagnostic::new(Level::Bug, msg); @@ -443,7 +473,7 @@ impl Handler { self.span_bug(sp, &format!("unimplemented {}", msg)); } pub fn fatal(&self, msg: &str) -> FatalError { - if self.treat_err_as_bug { + if self.flags.treat_err_as_bug { self.bug(msg); } let mut db = DiagnosticBuilder::new(self, Fatal, msg); @@ -451,7 +481,7 @@ impl Handler { FatalError } pub fn err(&self, msg: &str) { - if self.treat_err_as_bug { + if self.flags.treat_err_as_bug { self.bug(msg); } let mut db = DiagnosticBuilder::new(self, Error, msg); @@ -504,7 +534,7 @@ impl Handler { panic!(self.fatal(&s)); } pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { - if lvl == Warning && !self.can_emit_warnings { + if lvl == Warning && !self.flags.can_emit_warnings { return; } let mut db = DiagnosticBuilder::new(self, lvl, msg); @@ -515,7 +545,7 @@ impl Handler { } } pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: DiagnosticId, lvl: Level) { - if lvl == Warning && !self.can_emit_warnings { + if lvl == Warning && !self.flags.can_emit_warnings { return; } let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code), msg); diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs index 2e8deeee5a5..c2f4701999e 100644 --- a/src/librustc_errors/snippet.rs +++ b/src/librustc_errors/snippet.rs @@ -70,7 +70,7 @@ impl MultilineAnnotation { pub fn as_end(&self) -> Annotation { Annotation { - start_col: self.end_col - 1, + start_col: self.end_col.saturating_sub(1), end_col: self.end_col, is_primary: self.is_primary, label: self.label.clone(), @@ -213,6 +213,7 @@ pub enum Style { UnderlineSecondary, LabelPrimary, LabelSecondary, + OldSchoolNoteText, NoStyle, Level(Level), Highlight, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index b26ebfd6121..1f671adf4f8 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -136,12 +136,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, mir } - generator_sig => { cdata.generator_sig(def_id.index, tcx) } mir_const_qualif => { (cdata.mir_const_qualif(def_id.index), Rc::new(IdxSetBuf::new_empty(0))) } typeck_tables_of => { cdata.item_body_tables(def_id.index, tcx) } - closure_kind => { cdata.closure_kind(def_id.index) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } is_const_fn => { cdata.is_const_fn(def_id.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0dd1b9e500c..633806d5ef5 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1020,13 +1020,6 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn closure_kind(&self, closure_id: DefIndex) -> ty::ClosureKind { - match self.entry(closure_id).kind { - EntryKind::Closure(data) => data.decode(self).kind, - _ => bug!(), - } - } - pub fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) @@ -1043,23 +1036,6 @@ impl<'a, 'tcx> CrateMetadata { sig.decode((self, tcx)) } - fn get_generator_data(&self, - id: DefIndex, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Option<GeneratorData<'tcx>> { - match self.entry(id).kind { - EntryKind::Generator(data) => Some(data.decode((self, tcx))), - _ => None, - } - } - - pub fn generator_sig(&self, - id: DefIndex, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Option<ty::PolyGenSig<'tcx>> { - self.get_generator_data(id, tcx).map(|d| d.sig) - } - #[inline] pub fn def_key(&self, index: DefIndex) -> DefKey { self.def_path_table.def_key(index) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 23e86b2d35a..d82d50164cb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1205,19 +1205,25 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id); let tcx = self.tcx; - let kind = if let Some(sig) = self.tcx.generator_sig(def_id) { - let layout = self.tcx.generator_layout(def_id); - let data = GeneratorData { - sig, - layout: layout.clone(), - }; - EntryKind::Generator(self.lazy(&data)) - } else { - let data = ClosureData { - kind: tcx.closure_kind(def_id), - sig: self.lazy(&tcx.fn_sig(def_id)), - }; - EntryKind::Closure(self.lazy(&data)) + let tables = self.tcx.typeck_tables_of(def_id); + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let hir_id = self.tcx.hir.node_to_hir_id(node_id); + let kind = match tables.node_id_to_type(hir_id).sty { + ty::TyGenerator(def_id, ..) => { + let layout = self.tcx.generator_layout(def_id); + let data = GeneratorData { + layout: layout.clone(), + }; + EntryKind::Generator(self.lazy(&data)) + } + + ty::TyClosure(def_id, substs) => { + let sig = substs.closure_sig(def_id, self.tcx); + let data = ClosureData { sig: self.lazy(&sig) }; + EntryKind::Closure(self.lazy(&data)) + } + + _ => bug!("closure that is neither generator nor closure") }; Entry { @@ -1514,7 +1520,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_ty(&mut self, ty: &hir::Ty) { match ty.node { - hir::TyImplTraitExistential(_) => { + hir::TyImplTraitExistential(..) => { let def_id = self.tcx.hir.local_def_id(ty.id); self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id); } diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 19f7cb0ee23..8abccb503d6 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -311,98 +311,96 @@ impl<'a> Context<'a> { &None => String::new(), &Some(ref r) => format!(" which `{}` depends on", r.ident), }; + let mut msg = "the following crate versions were found:".to_string(); let mut err = if !self.rejected_via_hash.is_empty() { - struct_span_err!(self.sess, - self.span, - E0460, - "found possibly newer version of crate `{}`{}", - self.ident, - add) - } else if !self.rejected_via_triple.is_empty() { - struct_span_err!(self.sess, - self.span, - E0461, - "couldn't find crate `{}` with expected target triple {}{}", - self.ident, - self.triple, - add) - } else if !self.rejected_via_kind.is_empty() { - struct_span_err!(self.sess, - self.span, - E0462, - "found staticlib `{}` instead of rlib or dylib{}", - self.ident, - add) - } else if !self.rejected_via_version.is_empty() { - struct_span_err!(self.sess, - self.span, - E0514, - "found crate `{}` compiled by an incompatible version of rustc{}", - self.ident, - add) - } else { let mut err = struct_span_err!(self.sess, self.span, - E0463, - "can't find crate for `{}`{}", + E0460, + "found possibly newer version of crate `{}`{}", self.ident, add); - - if (self.ident == "std" || self.ident == "core") - && self.triple != config::host_triple() { - err.note(&format!("the `{}` target may not be installed", self.triple)); - } - err.span_label(self.span, "can't find crate"); - err - }; - - if !self.rejected_via_triple.is_empty() { - let mismatches = self.rejected_via_triple.iter(); - for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() { - err.note(&format!("crate `{}`, path #{}, triple {}: {}", - self.ident, - i + 1, - got, - path.display())); - } - } - if !self.rejected_via_hash.is_empty() { err.note("perhaps that crate needs to be recompiled?"); let mismatches = self.rejected_via_hash.iter(); - for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { - err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display())); + for &CrateMismatch { ref path, .. } in mismatches { + msg.push_str(&format!("\ncrate `{}`: {}", self.ident, path.display())); } match self.root { &None => {} &Some(ref r) => { - for (i, path) in r.paths().iter().enumerate() { - err.note(&format!("crate `{}` path #{}: {}", - r.ident, - i + 1, - path.display())); + for path in r.paths().iter() { + msg.push_str(&format!("\ncrate `{}`: {}", r.ident, path.display())); } } } - } - if !self.rejected_via_kind.is_empty() { + err.note(&msg); + err + } else if !self.rejected_via_triple.is_empty() { + let mut err = struct_span_err!(self.sess, + self.span, + E0461, + "couldn't find crate `{}` \ + with expected target triple {}{}", + self.ident, + self.triple, + add); + let mismatches = self.rejected_via_triple.iter(); + for &CrateMismatch { ref path, ref got } in mismatches { + msg.push_str(&format!("\ncrate `{}`, target triple {}: {}", + self.ident, + got, + path.display())); + } + err.note(&msg); + err + } else if !self.rejected_via_kind.is_empty() { + let mut err = struct_span_err!(self.sess, + self.span, + E0462, + "found staticlib `{}` instead of rlib or dylib{}", + self.ident, + add); err.help("please recompile that crate using --crate-type lib"); let mismatches = self.rejected_via_kind.iter(); - for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { - err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display())); + for &CrateMismatch { ref path, .. } in mismatches { + msg.push_str(&format!("\ncrate `{}`: {}", self.ident, path.display())); } - } - if !self.rejected_via_version.is_empty() { + err.note(&msg); + err + } else if !self.rejected_via_version.is_empty() { + let mut err = struct_span_err!(self.sess, + self.span, + E0514, + "found crate `{}` compiled by an incompatible version \ + of rustc{}", + self.ident, + add); err.help(&format!("please recompile that crate using this compiler ({})", rustc_version())); let mismatches = self.rejected_via_version.iter(); - for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() { - err.note(&format!("crate `{}` path #{}: {} compiled by {:?}", - self.ident, - i + 1, - path.display(), - got)); + for &CrateMismatch { ref path, ref got } in mismatches { + msg.push_str(&format!("\ncrate `{}` compiled by {}: {}", + self.ident, + got, + path.display())); } - } + err.note(&msg); + err + } else { + let mut err = struct_span_err!(self.sess, + self.span, + E0463, + "can't find crate for `{}`{}", + self.ident, + add); + + if (self.ident == "std" || self.ident == "core") + && self.triple != config::host_triple() { + err.note(&format!("the `{}` target may not be installed", self.triple)); + } + err.span_label(self.span, "can't find crate"); + err + }; + if !self.rejected_via_filename.is_empty() { let dylibname = self.dylibname(); let mismatches = self.rejected_via_filename.iter(); @@ -534,16 +532,23 @@ impl<'a> Context<'a> { E0464, "multiple matching crates for `{}`", self.crate_name); - err.note("candidates:"); - for (_, lib) in libraries { - if let Some((ref p, _)) = lib.dylib { - err.note(&format!("path: {}", p.display())); - } - if let Some((ref p, _)) = lib.rlib { - err.note(&format!("path: {}", p.display())); + let candidates = libraries.iter().filter_map(|(_, lib)| { + let crate_name = &lib.metadata.get_root().name.as_str(); + match &(&lib.dylib, &lib.rlib) { + &(&Some((ref pd, _)), &Some((ref pr, _))) => { + Some(format!("\ncrate `{}`: {}\n{:>padding$}", + crate_name, + pd.display(), + pr.display(), + padding=8 + crate_name.len())) + } + &(&Some((ref p, _)), &None) | &(&None, &Some((ref p, _))) => { + Some(format!("\ncrate `{}`: {}", crate_name, p.display())) + } + &(&None, &None) => None, } - note_crate_name(&mut err, &lib.metadata.get_root().name.as_str()); - } + }).collect::<String>(); + err.note(&format!("candidates:{}", candidates)); err.emit(); None } @@ -815,10 +820,6 @@ impl<'a> Context<'a> { } } -pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) { - err.note(&format!("crate name: {}", name)); -} - // Just a small wrapper to time how long reading metadata takes. fn get_metadata_section(target: &Target, flavor: CrateFlavor, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 3efe74bfecc..8ff32746391 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -512,14 +512,12 @@ impl_stable_hash_for!(struct MethodData<'tcx> { fn_data, container, has_self }); #[derive(RustcEncodable, RustcDecodable)] pub struct ClosureData<'tcx> { - pub kind: ty::ClosureKind, pub sig: Lazy<ty::PolyFnSig<'tcx>>, } -impl_stable_hash_for!(struct ClosureData<'tcx> { kind, sig }); +impl_stable_hash_for!(struct ClosureData<'tcx> { sig }); #[derive(RustcEncodable, RustcDecodable)] pub struct GeneratorData<'tcx> { - pub sig: ty::PolyGenSig<'tcx>, pub layout: mir::GeneratorLayout<'tcx>, } -impl_stable_hash_for!(struct GeneratorData<'tcx> { sig, layout }); +impl_stable_hash_for!(struct GeneratorData<'tcx> { layout }); diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs index cdac72b6dff..ddaade98be1 100644 --- a/src/librustc_mir/borrow_check.rs +++ b/src/librustc_mir/borrow_check.rs @@ -17,7 +17,7 @@ use rustc::ty::{self, TyCtxt, ParamEnv}; use rustc::ty::maps::Providers; use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Location, Lvalue, Local}; use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue}; -use rustc::mir::{Statement, StatementKind, Terminator, TerminatorKind}; +use rustc::mir::{Field, Statement, StatementKind, Terminator, TerminatorKind}; use transform::nll; use rustc_data_structures::fx::FxHashSet; @@ -91,7 +91,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, IllegalMoveOriginKind::Static => tcx.cannot_move_out_of(span, "static item", origin), IllegalMoveOriginKind::BorrowedContent => - tcx.cannot_move_out_of(span, "borrowed_content", origin), + tcx.cannot_move_out_of(span, "borrowed content", origin), IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => tcx.cannot_move_out_of_interior_of_drop(span, ty, origin), IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => @@ -1577,15 +1577,40 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // End-user visible description of `lvalue` fn describe_lvalue(&self, lvalue: &Lvalue<'tcx>) -> String { let mut buf = String::new(); - self.append_lvalue_to_string(lvalue, &mut buf, None); + self.append_lvalue_to_string(lvalue, &mut buf, false); buf } + /// If this is a field projection, and the field is being projected from a closure type, + /// then returns the index of the field being projected. Note that this closure will always + /// be `self` in the current MIR, because that is the only time we directly access the fields + /// of a closure type. + fn is_upvar_field_projection(&self, lvalue: &Lvalue<'tcx>) -> Option<Field> { + match *lvalue { + Lvalue::Projection(ref proj) => { + match proj.elem { + ProjectionElem::Field(field, _ty) => { + let is_projection_from_ty_closure = proj.base.ty(self.mir, self.tcx) + .to_ty(self.tcx).is_closure(); + + if is_projection_from_ty_closure { + Some(field) + } else { + None + } + }, + _ => None + } + }, + _ => None + } + } + // Appends end-user visible description of `lvalue` to `buf`. fn append_lvalue_to_string(&self, lvalue: &Lvalue<'tcx>, buf: &mut String, - autoderef: Option<bool>) { + mut autoderef: bool) { match *lvalue { Lvalue::Local(local) => { self.append_local_to_string(local, buf, "_"); @@ -1594,38 +1619,45 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { buf.push_str(&format!("{}", &self.tcx.item_name(static_.def_id))); } Lvalue::Projection(ref proj) => { - let mut autoderef = autoderef.unwrap_or(false); - match proj.elem { ProjectionElem::Deref => { - if autoderef { - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); + if let Some(field) = self.is_upvar_field_projection(&proj.base) { + let var_index = field.index(); + let name = self.mir.upvar_decls[var_index].debug_name.to_string(); + if self.mir.upvar_decls[var_index].by_ref { + buf.push_str(&name); + } else { + buf.push_str(&format!("*{}", &name)); + } } else { - buf.push_str(&"(*"); - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); - buf.push_str(&")"); + if autoderef { + self.append_lvalue_to_string(&proj.base, buf, autoderef); + } else { + buf.push_str(&"*"); + self.append_lvalue_to_string(&proj.base, buf, autoderef); + } } }, ProjectionElem::Downcast(..) => { - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); + self.append_lvalue_to_string(&proj.base, buf, autoderef); }, ProjectionElem::Field(field, _ty) => { autoderef = true; - let is_projection_from_ty_closure = proj.base.ty(self.mir, self.tcx) - .to_ty(self.tcx).is_closure(); - let field_name = self.describe_field(&proj.base, field.index()); - if is_projection_from_ty_closure { - buf.push_str(&format!("{}", field_name)); + if let Some(field) = self.is_upvar_field_projection(lvalue) { + let var_index = field.index(); + let name = self.mir.upvar_decls[var_index].debug_name.to_string(); + buf.push_str(&name); } else { - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); + let field_name = self.describe_field(&proj.base, field); + self.append_lvalue_to_string(&proj.base, buf, autoderef); buf.push_str(&format!(".{}", field_name)); } }, ProjectionElem::Index(index) => { autoderef = true; - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); + self.append_lvalue_to_string(&proj.base, buf, autoderef); buf.push_str("["); self.append_local_to_string(index, buf, ".."); buf.push_str("]"); @@ -1635,7 +1667,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // Since it isn't possible to borrow an element on a particular index and // then use another while the borrow is held, don't output indices details // to avoid confusing the end-user - self.append_lvalue_to_string(&proj.base, buf, Some(autoderef)); + self.append_lvalue_to_string(&proj.base, buf, autoderef); buf.push_str(&"[..]"); }, }; @@ -1653,58 +1685,57 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - // FIXME Instead of passing usize, Field should be passed - // End-user visible description of the `field_index`nth field of `base` - fn describe_field(&self, base: &Lvalue, field_index: usize) -> String { + // End-user visible description of the `field`nth field of `base` + fn describe_field(&self, base: &Lvalue, field: Field) -> String { match *base { Lvalue::Local(local) => { let local = &self.mir.local_decls[local]; - self.describe_field_from_ty(&local.ty, field_index) + self.describe_field_from_ty(&local.ty, field) }, Lvalue::Static(ref static_) => { - self.describe_field_from_ty(&static_.ty, field_index) + self.describe_field_from_ty(&static_.ty, field) }, Lvalue::Projection(ref proj) => { match proj.elem { ProjectionElem::Deref => - self.describe_field(&proj.base, field_index), + self.describe_field(&proj.base, field), ProjectionElem::Downcast(def, variant_index) => - format!("{}", def.variants[variant_index].fields[field_index].name), + format!("{}", def.variants[variant_index].fields[field.index()].name), ProjectionElem::Field(_, field_type) => - self.describe_field_from_ty(&field_type, field_index), + self.describe_field_from_ty(&field_type, field), ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => - format!("{}", self.describe_field(&proj.base, field_index)), + format!("{}", self.describe_field(&proj.base, field)), } } } } // End-user visible description of the `field_index`nth field of `ty` - fn describe_field_from_ty(&self, ty: &ty::Ty, field_index: usize) -> String { + fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String { if ty.is_box() { // If the type is a box, the field is described from the boxed type - self.describe_field_from_ty(&ty.boxed_ty(), field_index) + self.describe_field_from_ty(&ty.boxed_ty(), field) } else { match ty.sty { ty::TyAdt(def, _) => { if def.is_enum() { - format!("{}", field_index) + format!("{}", field.index()) } else { - format!("{}", def.struct_variant().fields[field_index].name) + format!("{}", def.struct_variant().fields[field.index()].name) } }, ty::TyTuple(_, _) => { - format!("{}", field_index) + format!("{}", field.index()) }, ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => { - self.describe_field_from_ty(&tnm.ty, field_index) + self.describe_field_from_ty(&tnm.ty, field) }, ty::TyArray(ty, _) | ty::TySlice(ty) => { - self.describe_field_from_ty(&ty, field_index) + self.describe_field_from_ty(&ty, field) }, ty::TyClosure(closure_def_id, _) => { // Convert the def-id into a node-id. node-ids are only valid for @@ -1712,7 +1743,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // the closure comes from another crate. But in that case we wouldn't // be borrowck'ing it, so we can just unwrap: let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap(); - let freevar = self.tcx.with_freevars(node_id, |fv| fv[field_index]); + let freevar = self.tcx.with_freevars(node_id, |fv| fv[field.index()]); self.tcx.hir.name(freevar.var_id()).to_string() } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 287d1083189..080cf4b47cf 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -103,7 +103,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t Some((closure_self_ty(tcx, id, body_id), None)) } ty::TyGenerator(..) => { - let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id); + let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id); Some((gen_ty, None)) } _ => None, @@ -127,7 +127,12 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t let arguments = implicit_argument.into_iter().chain(explicit_arguments); let (yield_ty, return_ty) = if body.is_generator { - let gen_sig = cx.tables().generator_sigs()[fn_hir_id].clone().unwrap(); + let gen_sig = match ty.sty { + ty::TyGenerator(gen_def_id, gen_substs, ..) => + gen_substs.generator_sig(gen_def_id, tcx), + _ => + span_bug!(tcx.hir.span(id), "generator w/o generator type: {:?}", ty), + }; (Some(gen_sig.yield_ty), gen_sig.return_ty) } else { (None, fn_sig.output()) @@ -248,14 +253,18 @@ pub fn closure_self_ty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, let closure_expr_hir_id = tcx.hir.node_to_hir_id(closure_expr_id); let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id); - let closure_def_id = tcx.hir.local_def_id(closure_expr_id); + let (closure_def_id, closure_substs) = match closure_ty.sty { + ty::TyClosure(closure_def_id, closure_substs) => (closure_def_id, closure_substs), + _ => bug!("closure expr does not have closure type: {:?}", closure_ty) + }; + let region = ty::ReFree(ty::FreeRegion { scope: closure_def_id, bound_region: ty::BoundRegion::BrEnv, }); let region = tcx.mk_region(region); - match tcx.closure_kind(closure_def_id) { + match closure_substs.closure_kind_ty(closure_def_id, tcx).to_opt_closure_kind().unwrap() { ty::ClosureKind::Fn => tcx.mk_ref(region, ty::TypeAndMut { ty: closure_ty, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 798928e7ae7..00d7cdc0ff7 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -713,8 +713,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }); let region = cx.tcx.mk_region(region); - let self_expr = if let ty::TyClosure(..) = closure_ty.sty { - match cx.tcx.closure_kind(closure_def_id) { + let self_expr = if let ty::TyClosure(_, closure_substs) = closure_ty.sty { + match cx.infcx.closure_kind(closure_def_id, closure_substs).unwrap() { ty::ClosureKind::Fn => { let ref_closure_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index d31f3812e9a..15c68954230 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -825,10 +825,16 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, -> Mir<'tcx> { let tcx = infcx.tcx; + let gcx = tcx.global_tcx(); let def_id = tcx.hir.local_def_id(ctor_id); - let sig = tcx.no_late_bound_regions(&tcx.fn_sig(def_id)) + let sig = gcx.no_late_bound_regions(&gcx.fn_sig(def_id)) .expect("LBR in ADT constructor signature"); - let sig = tcx.erase_regions(&sig); + let sig = gcx.erase_regions(&sig); + let param_env = gcx.param_env(def_id); + + // Normalize the sig now that we have liberated the late-bound + // regions. + let sig = gcx.normalize_associated_type_in_env(&sig, param_env); let (adt_def, substs) = match sig.output().sty { ty::TyAdt(adt_def, substs) => (adt_def, substs), diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index f676372193a..43635bcb631 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -767,7 +767,11 @@ impl MirPass for StateTransform { let hir_id = tcx.hir.node_to_hir_id(node_id); // Get the interior types which typeck computed - let interior = *tcx.typeck_tables_of(def_id).generator_interiors().get(hir_id).unwrap(); + let tables = tcx.typeck_tables_of(def_id); + let interior = match tables.node_id_to_type(hir_id).sty { + ty::TyGenerator(_, _, interior) => interior, + ref t => bug!("type of generator not a generator: {:?}", t), + }; // The first argument is the generator type passed by value let gen_ty = mir.local_decls.raw[1].ty; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 4b7856f857b..35cade25f77 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -23,6 +23,7 @@ use rustc::ty::layout::LayoutOf; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; +use std::iter; use transform::{MirPass, MirSource}; use super::simplify::{remove_dead_blocks, CfgSimplifier}; @@ -559,8 +560,29 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { ) -> Vec<Operand<'tcx>> { let tcx = self.tcx; - // A closure is passed its self-type and a tuple like `(arg1, arg2, ...)`, - // hence mappings to tuple fields are needed. + // There is a bit of a mismatch between the *caller* of a closure and the *callee*. + // The caller provides the arguments wrapped up in a tuple: + // + // tuple_tmp = (a, b, c) + // Fn::call(closure_ref, tuple_tmp) + // + // meanwhile the closure body expects the arguments (here, `a`, `b`, and `c`) + // as distinct arguments. (This is the "rust-call" ABI hack.) Normally, trans has + // the job of unpacking this tuple. But here, we are trans. =) So we want to create + // a vector like + // + // [closure_ref, tuple_tmp.0, tuple_tmp.1, tuple_tmp.2] + // + // Except for one tiny wrinkle: we don't actually want `tuple_tmp.0`. It's more convenient + // if we "spill" that into *another* temporary, so that we can map the argument + // variable in the callee MIR directly to an argument variable on our side. + // So we introduce temporaries like: + // + // tmp0 = tuple_tmp.0 + // tmp1 = tuple_tmp.1 + // tmp2 = tuple_tmp.2 + // + // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if tcx.is_closure(callsite.callee) { let mut args = args.into_iter(); let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir); @@ -573,12 +595,21 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { bug!("Closure arguments are not passed as a tuple"); }; - let mut res = Vec::with_capacity(1 + tuple_tys.len()); - res.push(Operand::Consume(self_)); - res.extend(tuple_tys.iter().enumerate().map(|(i, ty)| { - Operand::Consume(tuple.clone().field(Field::new(i), ty)) - })); - res + // The `closure_ref` in our example above. + let closure_ref_arg = iter::once(Operand::Consume(self_)); + + // The `tmp0`, `tmp1`, and `tmp2` in our example abonve. + let tuple_tmp_args = + tuple_tys.iter().enumerate().map(|(i, ty)| { + // This is e.g. `tuple_tmp.0` in our example above. + let tuple_field = Operand::Consume(tuple.clone().field(Field::new(i), ty)); + + // Spill to a local to make e.g. `tmp0`. + let tmp = self.create_temp_if_necessary(tuple_field, callsite, caller_mir); + Operand::Consume(tmp) + }); + + closure_ref_arg.chain(tuple_tmp_args).collect() } else { args.into_iter() .map(|a| Operand::Consume(self.create_temp_if_necessary(a, callsite, caller_mir))) diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs new file mode 100644 index 00000000000..9dc5fdadbb1 --- /dev/null +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -0,0 +1,240 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Replaces 128-bit operators with lang item calls + +use rustc::hir::def_id::DefId; +use rustc::middle::lang_items::LangItem; +use rustc::mir::*; +use rustc::ty::{Slice, Ty, TyCtxt, TypeVariants}; +use rustc_data_structures::indexed_vec::{Idx}; +use transform::{MirPass, MirSource}; +use syntax; + +pub struct Lower128Bit; + +impl MirPass for Lower128Bit { + fn run_pass<'a, 'tcx>(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + _src: MirSource, + mir: &mut Mir<'tcx>) { + if !tcx.sess.opts.debugging_opts.lower_128bit_ops { + return + } + + self.lower_128bit_ops(tcx, mir); + } +} + +impl Lower128Bit { + fn lower_128bit_ops<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) { + let mut new_blocks = Vec::new(); + let cur_len = mir.basic_blocks().len(); + + let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut(); + for block in basic_blocks.iter_mut() { + for i in (0..block.statements.len()).rev() { + let (lang_item, rhs_kind) = + if let Some((lang_item, rhs_kind)) = + lower_to(&block.statements[i], local_decls, tcx) + { + (lang_item, rhs_kind) + } else { + continue; + }; + + let rhs_override_ty = rhs_kind.ty(tcx); + let cast_local = + match rhs_override_ty { + None => None, + Some(ty) => { + let local_decl = LocalDecl::new_internal( + ty, block.statements[i].source_info.span); + Some(local_decls.push(local_decl)) + }, + }; + + let storage_dead = cast_local.map(|local| { + Statement { + source_info: block.statements[i].source_info, + kind: StatementKind::StorageDead(local), + } + }); + let after_call = BasicBlockData { + statements: storage_dead.into_iter() + .chain(block.statements.drain((i+1)..)).collect(), + is_cleanup: block.is_cleanup, + terminator: block.terminator.take(), + }; + + let bin_statement = block.statements.pop().unwrap(); + let (source_info, lvalue, lhs, mut rhs) = match bin_statement { + Statement { + source_info, + kind: StatementKind::Assign( + lvalue, + Rvalue::BinaryOp(_, lhs, rhs)) + } => (source_info, lvalue, lhs, rhs), + Statement { + source_info, + kind: StatementKind::Assign( + lvalue, + Rvalue::CheckedBinaryOp(_, lhs, rhs)) + } => (source_info, lvalue, lhs, rhs), + _ => bug!("Statement doesn't match pattern any more?"), + }; + + if let Some(local) = cast_local { + block.statements.push(Statement { + source_info: source_info, + kind: StatementKind::StorageLive(local), + }); + block.statements.push(Statement { + source_info: source_info, + kind: StatementKind::Assign( + Lvalue::Local(local), + Rvalue::Cast( + CastKind::Misc, + rhs, + rhs_override_ty.unwrap())), + }); + rhs = Operand::Consume(Lvalue::Local(local)); + } + + let call_did = check_lang_item_type( + lang_item, &lvalue, &lhs, &rhs, local_decls, tcx); + + let bb = BasicBlock::new(cur_len + new_blocks.len()); + new_blocks.push(after_call); + + block.terminator = + Some(Terminator { + source_info, + kind: TerminatorKind::Call { + func: Operand::function_handle(tcx, call_did, + Slice::empty(), source_info.span), + args: vec![lhs, rhs], + destination: Some((lvalue, bb)), + cleanup: None, + }, + }); + } + } + + basic_blocks.extend(new_blocks); + } +} + +fn check_lang_item_type<'a, 'tcx, D>( + lang_item: LangItem, + lvalue: &Lvalue<'tcx>, + lhs: &Operand<'tcx>, + rhs: &Operand<'tcx>, + local_decls: &D, + tcx: TyCtxt<'a, 'tcx, 'tcx>) +-> DefId + where D: HasLocalDecls<'tcx> +{ + let did = tcx.require_lang_item(lang_item); + let poly_sig = tcx.fn_sig(did); + let sig = tcx.no_late_bound_regions(&poly_sig).unwrap(); + let lhs_ty = lhs.ty(local_decls, tcx); + let rhs_ty = rhs.ty(local_decls, tcx); + let lvalue_ty = lvalue.ty(local_decls, tcx).to_ty(tcx); + let expected = [lhs_ty, rhs_ty, lvalue_ty]; + assert_eq!(sig.inputs_and_output[..], expected, + "lang item {}", tcx.def_symbol_name(did)); + did +} + +fn lower_to<'a, 'tcx, D>(statement: &Statement<'tcx>, local_decls: &D, tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> Option<(LangItem, RhsKind)> + where D: HasLocalDecls<'tcx> +{ + match statement.kind { + StatementKind::Assign(_, Rvalue::BinaryOp(bin_op, ref lhs, _)) => { + let ty = lhs.ty(local_decls, tcx); + if let Some(is_signed) = sign_of_128bit(ty) { + return item_for_op(bin_op, is_signed); + } + }, + StatementKind::Assign(_, Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => { + let ty = lhs.ty(local_decls, tcx); + if let Some(is_signed) = sign_of_128bit(ty) { + return item_for_checked_op(bin_op, is_signed); + } + }, + _ => {}, + } + None +} + +#[derive(Copy, Clone)] +enum RhsKind { + Unchanged, + ForceU128, + ForceU32, +} + +impl RhsKind { + fn ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Ty<'tcx>> { + match *self { + RhsKind::Unchanged => None, + RhsKind::ForceU128 => Some(tcx.types.u128), + RhsKind::ForceU32 => Some(tcx.types.u32), + } + } +} + +fn sign_of_128bit(ty: Ty) -> Option<bool> { + match ty.sty { + TypeVariants::TyInt(syntax::ast::IntTy::I128) => Some(true), + TypeVariants::TyUint(syntax::ast::UintTy::U128) => Some(false), + _ => None, + } +} + +fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { + let i = match (bin_op, is_signed) { + (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged), + (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged), + (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged), + (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged), + (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged), + (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged), + (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged), + (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged), + (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged), + (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged), + (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32), + (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32), + (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32), + (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32), + _ => return None, + }; + Some(i) +} + +fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { + let i = match (bin_op, is_signed) { + (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged), + (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged), + (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged), + (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged), + (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged), + (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged), + (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128), + (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128), + (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128), + (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128), + _ => bug!("That should be all the checked ones?"), + }; + Some(i) +} \ No newline at end of file diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 441f9be9be1..6987cfa79be 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -42,6 +42,7 @@ pub mod copy_prop; pub mod generator; pub mod inline; pub mod nll; +pub mod lower_128bit; pub(crate) fn provide(providers: &mut Providers) { self::qualify_consts::provide(providers); @@ -241,6 +242,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx // From here on out, regions are gone. erase_regions::EraseRegions, + lower_128bit::Lower128Bit, + // Optimizations begin. inline::Inline, instcombine::InstCombine, diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index cc6b7020903..ade5cf8b70c 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -549,6 +549,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { terr ); } + self.check_rvalue(mir, rv, location); } StatementKind::SetDiscriminant { ref lvalue, @@ -1011,6 +1012,111 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } + fn aggregate_field_ty( + &mut self, + ak: &Box<AggregateKind<'tcx>>, + field_index: usize, + location: Location, + ) -> Result<Ty<'tcx>, FieldAccessError> { + let tcx = self.tcx(); + + match **ak { + AggregateKind::Adt(def, variant_index, substs, active_field_index) => { + let variant = &def.variants[variant_index]; + let adj_field_index = active_field_index.unwrap_or(field_index); + if let Some(field) = variant.fields.get(adj_field_index) { + Ok(self.normalize(&field.ty(tcx, substs), location)) + } else { + Err(FieldAccessError::OutOfRange { + field_count: variant.fields.len(), + }) + } + } + AggregateKind::Closure(def_id, substs) => { + match substs.upvar_tys(def_id, tcx).nth(field_index) { + Some(ty) => Ok(ty), + None => Err(FieldAccessError::OutOfRange { + field_count: substs.upvar_tys(def_id, tcx).count(), + }), + } + } + AggregateKind::Generator(def_id, substs, _) => { + if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field_index) { + Ok(ty) + } else { + match substs.field_tys(def_id, tcx).nth(field_index) { + Some(ty) => Ok(ty), + None => Err(FieldAccessError::OutOfRange { + field_count: substs.field_tys(def_id, tcx).count() + 1, + }), + } + } + } + AggregateKind::Array(ty) => { + Ok(ty) + } + AggregateKind::Tuple => { + unreachable!("This should have been covered in check_rvalues"); + } + } + } + + fn check_rvalue(&mut self, mir: &Mir<'tcx>, rv: &Rvalue<'tcx>, location: Location) { + let tcx = self.tcx(); + match rv { + Rvalue::Aggregate(ak, ops) => { + match **ak { + // tuple rvalue field type is always the type of the op. Nothing to check here. + AggregateKind::Tuple => {} + _ => { + for (i, op) in ops.iter().enumerate() { + let field_ty = match self.aggregate_field_ty(ak, i, location) { + Ok(field_ty) => field_ty, + Err(FieldAccessError::OutOfRange { field_count }) => { + span_mirbug!( + self, + rv, + "accessed field #{} but variant only has {}", + i, + field_count + ); + continue; + } + }; + let op_ty = op.ty(mir, tcx); + if let Err(terr) = self.sub_types( + op_ty, + field_ty, + location.at_successor_within_block(), + ) + { + span_mirbug!( + self, + rv, + "{:?} is not a subtype of {:?}: {:?}", + op_ty, + field_ty, + terr + ); + } + } + } + } + } + // FIXME: These other cases have to be implemented in future PRs + Rvalue::Use(..) | + Rvalue::Repeat(..) | + Rvalue::Ref(..) | + Rvalue::Len(..) | + Rvalue::Cast(..) | + Rvalue::BinaryOp(..) | + Rvalue::CheckedBinaryOp(..) | + Rvalue::UnaryOp(..) | + Rvalue::Discriminant(..) | + Rvalue::NullaryOp(..) => {} + } + } + fn typeck_mir(&mut self, mir: &Mir<'tcx>) { self.last_span = mir.span; debug!("run_on_mir: {:?}", mir.span); diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 40adc6bcb12..3136aeaf8ca 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -21,7 +21,6 @@ use rustc::session::Session; use syntax::ast::*; use syntax::attr; use syntax::codemap::Spanned; -use syntax::parse::token; use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax_pos::Span; @@ -182,18 +181,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_ty(self, ty) } - fn visit_path(&mut self, path: &'a Path, _: NodeId) { - if path.segments.len() >= 2 && path.is_global() { - let ident = path.segments[1].identifier; - if token::Ident(ident).is_path_segment_keyword() { - self.err_handler() - .span_err(path.span, &format!("global paths cannot start with `{}`", ident)); - } - } - - visit::walk_path(self, path) - } - fn visit_item(&mut self, item: &'a Item) { match item.node { ItemKind::Use(ref view_path) => { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index b30fc38fcbc..46513a5740a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -114,7 +114,7 @@ impl<'a> Resolver<'a> { // Extract and intern the module part of the path. For // globs and lists, the path is found directly in the AST; // for simple paths we have to munge the path a little. - let mut module_path: Vec<_> = match view_path.node { + let module_path: Vec<_> = match view_path.node { ViewPathSimple(_, ref full_path) => { full_path.segments .split_last() @@ -134,14 +134,6 @@ impl<'a> Resolver<'a> { } }; - // This can be removed once warning cycle #36888 is complete. - if module_path.len() >= 2 && - module_path[0].node.name == keywords::CrateRoot.name() && - token::Ident(module_path[1].node).is_path_segment_keyword() - { - module_path.remove(0); - } - // Build up the import directives. let is_prelude = attr::contains_name(&item.attrs, "prelude_import"); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8207057fd0a..3243152527f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -588,6 +588,18 @@ struct UsePlacementFinder { found_use: bool, } +impl UsePlacementFinder { + fn check(krate: &Crate, target_module: NodeId) -> (Option<Span>, bool) { + let mut finder = UsePlacementFinder { + target_module, + span: None, + found_use: false, + }; + visit::walk_crate(&mut finder, krate); + (finder.span, finder.found_use) + } +} + impl<'tcx> Visitor<'tcx> for UsePlacementFinder { fn visit_mod( &mut self, @@ -1278,6 +1290,8 @@ pub struct Resolver<'a> { ambiguity_errors: Vec<AmbiguityError<'a>>, /// `use` injections are delayed for better placement and deduplication use_injections: Vec<UseError<'a>>, + /// `use` injections for proc macros wrongly imported with #[macro_use] + proc_mac_errors: Vec<macros::ProcMacError>, gated_errors: FxHashSet<Span>, disallowed_shadowing: Vec<&'a LegacyBinding<'a>>, @@ -1486,6 +1500,7 @@ impl<'a> Resolver<'a> { privacy_errors: Vec::new(), ambiguity_errors: Vec::new(), use_injections: Vec::new(), + proc_mac_errors: Vec::new(), gated_errors: FxHashSet(), disallowed_shadowing: Vec::new(), @@ -2599,6 +2614,22 @@ impl<'a> Resolver<'a> { } _ => {} }, + (Def::Enum(..), PathSource::TupleStruct) + | (Def::Enum(..), PathSource::Expr(..)) => { + if let Some(variants) = this.collect_enum_variants(def) { + err.note(&format!("did you mean to use one \ + of the following variants?\n{}", + variants.iter() + .map(|suggestion| path_names_to_string(suggestion)) + .map(|suggestion| format!("- `{}`", suggestion)) + .collect::<Vec<_>>() + .join("\n"))); + + } else { + err.note("did you mean to use one of the enum's variants?"); + } + return (err, candidates); + }, _ if ns == ValueNS && is_struct_like(def) => { if let Def::Struct(def_id) = def { if let Some((ctor_def, ctor_vis)) @@ -2865,12 +2896,13 @@ impl<'a> Resolver<'a> { debug!("resolve_path ident {} {:?}", i, ident); let is_last = i == path.len() - 1; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; + let name = ident.node.name; - if i == 0 && ns == TypeNS && ident.node.name == keywords::SelfValue.name() { + if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() { let mut ctxt = ident.node.ctxt.modern(); module = Some(self.resolve_self(&mut ctxt, self.current_module)); continue - } else if allow_super && ns == TypeNS && ident.node.name == keywords::Super.name() { + } else if allow_super && ns == TypeNS && name == keywords::Super.name() { let mut ctxt = ident.node.ctxt.modern(); let self_module = match i { 0 => self.resolve_self(&mut ctxt, self.current_module), @@ -2886,12 +2918,41 @@ impl<'a> Resolver<'a> { } allow_super = false; - if i == 0 && ns == TypeNS && ident.node.name == keywords::CrateRoot.name() { - module = Some(self.resolve_crate_root(ident.node.ctxt.modern())); - continue - } else if i == 0 && ns == TypeNS && ident.node.name == keywords::DollarCrate.name() { - module = Some(self.resolve_crate_root(ident.node.ctxt)); - continue + if ns == TypeNS { + if (i == 0 && name == keywords::CrateRoot.name()) || + (i == 1 && name == keywords::Crate.name() && + path[0].node.name == keywords::CrateRoot.name()) { + // `::a::b` or `::crate::a::b` + module = Some(self.resolve_crate_root(ident.node.ctxt.modern())); + continue + } else if i == 0 && name == keywords::DollarCrate.name() { + // `$crate::a::b` + module = Some(self.resolve_crate_root(ident.node.ctxt)); + continue + } + } + + // Report special messages for path segment keywords in wrong positions. + if name == keywords::CrateRoot.name() && i != 0 || + name == keywords::DollarCrate.name() && i != 0 || + name == keywords::SelfValue.name() && i != 0 || + name == keywords::SelfType.name() && i != 0 || + name == keywords::Super.name() && i != 0 || + name == keywords::Crate.name() && i != 1 && + path[0].node.name != keywords::CrateRoot.name() { + let name_str = if name == keywords::CrateRoot.name() { + format!("crate root") + } else { + format!("`{}`", name) + }; + let msg = if i == 1 && path[0].node.name == keywords::CrateRoot.name() { + format!("global paths cannot start with {}", name_str) + } else if i == 0 && name == keywords::Crate.name() { + format!("{} can only be used in absolute paths", name_str) + } else { + format!("{} in paths can only be used in start position", name_str) + }; + return PathResult::Failed(ident.span, msg, false); } let binding = if let Some(module) = module { @@ -2942,7 +3003,7 @@ impl<'a> Resolver<'a> { let msg = if module.and_then(ModuleData::def) == self.graph_root.def() { let is_mod = |def| match def { Def::Mod(..) => true, _ => false }; let mut candidates = - self.lookup_import_candidates(ident.node.name, TypeNS, is_mod); + self.lookup_import_candidates(name, TypeNS, is_mod); candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string())); if let Some(candidate) = candidates.get(0) { format!("Did you mean `{}`?", candidate.path) @@ -3495,6 +3556,72 @@ impl<'a> Resolver<'a> { candidates } + fn find_module(&mut self, + module_def: Def) + -> Option<(Module<'a>, ImportSuggestion)> + { + let mut result = None; + let mut worklist = Vec::new(); + let mut seen_modules = FxHashSet(); + worklist.push((self.graph_root, Vec::new())); + + while let Some((in_module, path_segments)) = worklist.pop() { + // abort if the module is already found + if let Some(_) = result { break; } + + self.populate_module_if_necessary(in_module); + + in_module.for_each_child_stable(|ident, _, name_binding| { + // abort if the module is already found + if let Some(_) = result { + return (); + } + if let Some(module) = name_binding.module() { + // form the path + let mut path_segments = path_segments.clone(); + path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span)); + if module.def() == Some(module_def) { + let path = Path { + span: name_binding.span, + segments: path_segments, + }; + result = Some((module, ImportSuggestion { path: path })); + } else { + // add the module to the lookup + if seen_modules.insert(module.def_id().unwrap()) { + worklist.push((module, path_segments)); + } + } + } + }); + } + + result + } + + fn collect_enum_variants(&mut self, enum_def: Def) -> Option<Vec<Path>> { + if let Def::Enum(..) = enum_def {} else { + panic!("Non-enum def passed to collect_enum_variants: {:?}", enum_def) + } + + self.find_module(enum_def).map(|(enum_module, enum_import_suggestion)| { + self.populate_module_if_necessary(enum_module); + + let mut variants = Vec::new(); + enum_module.for_each_child_stable(|ident, _, name_binding| { + if let Def::Variant(..) = name_binding.def() { + let mut segms = enum_import_suggestion.path.segments.clone(); + segms.push(ast::PathSegment::from_ident(ident, name_binding.span)); + variants.push(Path { + span: name_binding.span, + segments: segms, + }); + } + }); + variants + }) + } + fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) { debug!("(recording def) recording {:?} for {}", resolution, node_id); if let Some(prev_res) = self.def_map.insert(node_id, resolution) { @@ -3539,6 +3666,7 @@ impl<'a> Resolver<'a> { fn report_errors(&mut self, krate: &Crate) { self.report_shadowing_errors(); self.report_with_use_injections(krate); + self.report_proc_macro_import(krate); let mut reported_spans = FxHashSet(); for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors { @@ -3588,14 +3716,9 @@ impl<'a> Resolver<'a> { fn report_with_use_injections(&mut self, krate: &Crate) { for UseError { mut err, candidates, node_id, better } in self.use_injections.drain(..) { - let mut finder = UsePlacementFinder { - target_module: node_id, - span: None, - found_use: false, - }; - visit::walk_crate(&mut finder, krate); + let (span, found_use) = UsePlacementFinder::check(krate, node_id); if !candidates.is_empty() { - show_candidates(&mut err, finder.span, &candidates, better, finder.found_use); + show_candidates(&mut err, span, &candidates, better, found_use); } err.emit(); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index a52e6fcad14..3d1d7c0c48a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -83,6 +83,14 @@ pub struct LegacyBinding<'a> { pub span: Span, } +pub struct ProcMacError { + crate_name: Symbol, + name: Symbol, + module: ast::NodeId, + use_span: Span, + warn_msg: &'static str, +} + #[derive(Copy, Clone)] pub enum MacroBinding<'a> { Legacy(&'a LegacyBinding<'a>), @@ -779,12 +787,37 @@ impl<'a> Resolver<'a> { _ => return, }; - let crate_name = self.cstore.crate_name_untracked(krate); + let def_id = self.current_module.normal_ancestor_id; + let node_id = self.definitions.as_local_node_id(def_id).unwrap(); + + self.proc_mac_errors.push(ProcMacError { + crate_name: self.cstore.crate_name_untracked(krate), + name, + module: node_id, + use_span, + warn_msg, + }); + } + + pub fn report_proc_macro_import(&mut self, krate: &ast::Crate) { + for err in self.proc_mac_errors.drain(..) { + let (span, found_use) = ::UsePlacementFinder::check(krate, err.module); - self.session.struct_span_err(use_span, warn_msg) - .help(&format!("instead, import the procedural macro like any other item: \ - `use {}::{};`", crate_name, name)) - .emit(); + if let Some(span) = span { + let found_use = if found_use { "" } else { "\n" }; + self.session.struct_span_err(err.use_span, err.warn_msg) + .span_suggestion( + span, + "instead, import the procedural macro like any other item", + format!("use {}::{};{}", err.crate_name, err.name, found_use), + ).emit(); + } else { + self.session.struct_span_err(err.use_span, err.warn_msg) + .help(&format!("instead, import the procedural macro like any other item: \ + `use {}::{};`", err.crate_name, err.name)) + .emit(); + } + } } fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index bcbabd70094..d72253e5a8a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -606,10 +606,16 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let module_result = self.resolve_path(&module_path, None, true, span); let module = match module_result { PathResult::Module(module) => module, - PathResult::Failed(span, msg, _) => { + PathResult::Failed(span, msg, false) => { + resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); + return None; + } + PathResult::Failed(span, msg, true) => { let (mut self_path, mut self_result) = (module_path.clone(), None); if !self_path.is_empty() && - !token::Ident(self_path[0].node).is_path_segment_keyword() + !token::Ident(self_path[0].node).is_path_segment_keyword() && + !(self_path.len() > 1 && + token::Ident(self_path[1].node).is_path_segment_keyword()) { self_path[0].node.name = keywords::SelfValue.name(); self_result = Some(self.resolve_path(&self_path, None, false, span)); diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 1b5ab10fc70..6c8c9b73286 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -15,7 +15,7 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rls-data = "0.12" +rls-data = "0.13" rls-span = "0.4" # FIXME(#40527) should move rustc serialize out of tree rustc-serialize = "0.3" diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 272b1cb8d35..d4257e35823 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -42,7 +42,7 @@ use syntax::codemap::Spanned; use syntax_pos::*; use {escape, generated_code, lower_attributes, PathCollector, SaveContext}; -use json_dumper::{DumpOutput, JsonDumper}; +use json_dumper::{Access, DumpOutput, JsonDumper}; use span_utils::SpanUtils; use sig; @@ -59,6 +59,15 @@ macro_rules! down_cast_data { }; } +macro_rules! access_from { + ($save_ctxt:expr, $item:expr) => { + Access { + public: $item.vis == ast::Visibility::Public, + reachable: $save_ctxt.analysis.access_levels.is_reachable($item.id), + } + } +} + pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> { save_ctxt: SaveContext<'l, 'tcx>, tcx: TyCtxt<'l, 'tcx, 'tcx>, @@ -341,7 +350,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let span = self.span_from_span(sub_span.expect("No span found for variable")); self.dumper.dump_def( - false, + &Access { + public: false, + reachable: false, + }, Def { kind: DefKind::Local, id, @@ -387,8 +399,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { method_data.value = sig_str; method_data.sig = sig::method_signature(id, name, generics, sig, &self.save_ctxt); - self.dumper - .dump_def(vis == ast::Visibility::Public, method_data); + self.dumper.dump_def( + &Access { + public: vis == ast::Visibility::Public, + reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), + }, + method_data); } // walk arg and return types @@ -409,8 +425,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) { let field_data = self.save_ctxt.get_field_data(field, parent_id); if let Some(field_data) = field_data { - self.dumper - .dump_def(field.vis == ast::Visibility::Public, field_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, field), field_data); } } @@ -432,7 +447,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let span = self.span_from_span(param_ss); self.dumper.dump_def( - false, + &Access { + public: false, + reachable: false, + }, Def { kind: DefKind::Type, id, @@ -467,8 +485,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { |v| v.process_formals(&decl.inputs, &fn_data.qualname), ); self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, fn_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, item), fn_data); } for arg in &decl.inputs { @@ -491,8 +508,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.nest_tables(item.id, |v| { if let Some(var_data) = v.save_ctxt.get_item_data(item) { down_cast_data!(var_data, DefData, item.span); - v.dumper - .dump_def(item.vis == ast::Visibility::Public, var_data); + v.dumper.dump_def(&access_from!(v.save_ctxt, item), var_data); } v.visit_ty(&typ); v.visit_expr(expr); @@ -516,14 +532,16 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(sub_span, span) { let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt); - let id = ::id_from_node_id(id, &self.save_ctxt); let span = self.span_from_span(sub_span.expect("No span found for variable")); self.dumper.dump_def( - vis == ast::Visibility::Public, + &Access { + public: vis == ast::Visibility::Public, + reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), + }, Def { kind: DefKind::Const, - id, + id: ::id_from_node_id(id, &self.save_ctxt), span, name: name.to_string(), qualname, @@ -596,7 +614,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(sub_span, item.span) { let span = self.span_from_span(sub_span.expect("No span found for struct")); self.dumper.dump_def( - item.vis == ast::Visibility::Public, + &access_from!(self.save_ctxt, item), Def { kind, id: ::id_from_node_id(item.id, &self.save_ctxt), @@ -635,6 +653,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { }; down_cast_data!(enum_data, DefData, item.span); + let access = access_from!(self.save_ctxt, item); + for variant in &enum_definition.variants { let name = variant.node.name.name.to_string(); let mut qualname = enum_data.qualname.clone(); @@ -660,7 +680,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); self.dumper.dump_def( - item.vis == ast::Visibility::Public, + &access, Def { kind: DefKind::StructVariant, id, @@ -700,7 +720,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); self.dumper.dump_def( - item.vis == ast::Visibility::Public, + &access, Def { kind: DefKind::TupleVariant, id, @@ -730,8 +750,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } } self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, enum_data); + self.dumper.dump_def(&access, enum_data); } fn process_impl( @@ -783,7 +802,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .map(|i| ::id_from_node_id(i.id, &self.save_ctxt)) .collect(); self.dumper.dump_def( - item.vis == ast::Visibility::Public, + &access_from!(self.save_ctxt, item), Def { kind: DefKind::Trait, id, @@ -846,8 +865,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_mod(&mut self, item: &ast::Item) { if let Some(mod_data) = self.save_ctxt.get_item_data(item) { down_cast_data!(mod_data, DefData, item.span); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, mod_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, item), mod_data); } } @@ -1038,7 +1056,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let span = self.span_from_span(sub_span.expect("No span found for variable")); self.dumper.dump_def( - false, + &Access { + public: false, + reachable: false, + }, Def { kind: DefKind::Local, id, @@ -1138,7 +1159,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let id = ::id_from_node_id(trait_item.id, &self.save_ctxt); self.dumper.dump_def( - true, + &Access { + public: true, + reachable: true, + }, Def { kind: DefKind::Type, id, @@ -1225,7 +1249,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(span); self.dumper.dump_def( - true, + &Access { + public: true, + reachable: true, + }, Def { kind: DefKind::Mod, id: data_id, @@ -1249,6 +1276,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.process_macro_use(item.span); match item.node { Use(ref use_item) => { + let access = access_from!(self.save_ctxt, item); + match use_item.node { ast::ViewPathSimple(ident, ref path) => { let sub_span = self.span.span_for_last_ident(path.span); @@ -1273,7 +1302,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(sub_span.expect("No span found for use")); self.dumper.import( - item.vis == ast::Visibility::Public, + &access, Import { kind: ImportKind::Use, ref_id: mod_id.map(|id| ::id_from_def_id(id)), @@ -1302,7 +1331,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(sub_span.expect("No span found for use glob")); self.dumper.import( - item.vis == ast::Visibility::Public, + &access, Import { kind: ImportKind::GlobUse, ref_id: None, @@ -1334,7 +1363,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(alias_span.expect("No span found for extern crate")); self.dumper.import( - false, + &Access { + public: false, + reachable: false, + }, Import { kind: ImportKind::ExternCrate, ref_id: None, @@ -1373,7 +1405,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let id = ::id_from_node_id(item.id, &self.save_ctxt); self.dumper.dump_def( - item.vis == ast::Visibility::Public, + &access_from!(self.save_ctxt, item), Def { kind: DefKind::Type, id, @@ -1596,7 +1628,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(sp); self.dumper.dump_def( - false, + &Access { + public: false, + reachable: false, + }, Def { kind: DefKind::Local, id, @@ -1662,6 +1697,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) { + let access = access_from!(self.save_ctxt, item); + match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { @@ -1672,8 +1709,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc |v| v.process_formals(&decl.inputs, &fn_data.qualname), ); self.process_generic_params(generics, item.span, &fn_data.qualname, item.id); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, fn_data); + self.dumper.dump_def(&access, fn_data); } for arg in &decl.inputs { @@ -1687,8 +1723,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc ast::ForeignItemKind::Static(ref ty, _) => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, var_data); + self.dumper.dump_def(&access, var_data); } self.visit_ty(ty); @@ -1696,8 +1731,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc ast::ForeignItemKind::Ty => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); - self.dumper - .dump_def(item.vis == ast::Visibility::Public, var_data); + self.dumper.dump_def(&access, var_data); } } } diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 14b624b9338..2b35a412383 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -17,6 +17,12 @@ use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, use rls_data::config::Config; use rls_span::{Column, Row}; +#[derive(Debug)] +pub struct Access { + pub reachable: bool, + pub public: bool, +} + pub struct JsonDumper<O: DumpOutput> { result: Analysis, config: Config, @@ -84,33 +90,35 @@ impl<'b, O: DumpOutput + 'b> JsonDumper<O> { } pub fn macro_use(&mut self, data: MacroRef) { - if self.config.pub_only { + if self.config.pub_only || self.config.reachable_only { return; } self.result.macro_refs.push(data); } - pub fn import(&mut self, public: bool, import: Import) { - if !public && self.config.pub_only { + pub fn import(&mut self, access: &Access, import: Import) { + if !access.public && self.config.pub_only + || !access.reachable && self.config.reachable_only { return; } self.result.imports.push(import); } pub fn dump_ref(&mut self, data: Ref) { - if self.config.pub_only { + if self.config.pub_only || self.config.reachable_only { return; } self.result.refs.push(data); } - pub fn dump_def(&mut self, public: bool, mut data: Def) { - if !public && self.config.pub_only { + pub fn dump_def(&mut self, access: &Access, mut data: Def) { + if !access.public && self.config.pub_only + || !access.reachable && self.config.reachable_only { return; } if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value { - // If the module is an out-of-line defintion, then we'll make the - // definition the first character in the module's file and turn the + // If the module is an out-of-line definition, then we'll make the + // definition the first character in the module's file and turn // the declaration into a reference to it. let rf = Ref { kind: RefKind::Mod, diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 7bd8a0c81ee..1f92c106784 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -396,7 +396,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs); let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); - let env_ty = match tcx.closure_kind(def_id) { + let env_ty = match substs.closure_kind(def_id, tcx) { ty::ClosureKind::Fn => tcx.mk_imm_ref(tcx.mk_region(env_region), ty), ty::ClosureKind::FnMut => tcx.mk_mut_ref(tcx.mk_region(env_region), ty), ty::ClosureKind::FnOnce => ty, @@ -412,7 +412,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } ty::TyGenerator(def_id, substs, _) => { let tcx = ccx.tcx(); - let sig = tcx.generator_sig(def_id).unwrap().subst(tcx, substs.substs); + let sig = substs.generator_poly_sig(def_id, ccx.tcx()); let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); diff --git a/src/librustc_trans_utils/monomorphize.rs b/src/librustc_trans_utils/monomorphize.rs index eee5c1d9ef2..66833a1a7c2 100644 --- a/src/librustc_trans_utils/monomorphize.rs +++ b/src/librustc_trans_utils/monomorphize.rs @@ -86,7 +86,7 @@ pub fn resolve_closure<'a, 'tcx> ( requested_kind: ty::ClosureKind) -> Instance<'tcx> { - let actual_kind = tcx.closure_kind(def_id); + let actual_kind = substs.closure_kind(def_id, tcx); match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7aaf65e1fd0..8b849a9e52f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -21,7 +21,7 @@ use middle::resolve_lifetime as rl; use namespace::Namespace; use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::traits; -use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; +use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; use rustc_back::slice; use require_c_abi_if_variadic; @@ -110,7 +110,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.types.re_static } - Some(rl::Region::LateBound(debruijn, id)) => { + Some(rl::Region::LateBound(debruijn, id, _)) => { let name = lifetime_name(id); tcx.mk_region(ty::ReLateBound(debruijn, ty::BrNamed(id, name))) @@ -120,7 +120,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index))) } - Some(rl::Region::EarlyBound(index, id)) => { + Some(rl::Region::EarlyBound(index, id, _)) => { let name = lifetime_name(id); tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: id, @@ -1034,9 +1034,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::TyTraitObject(ref bounds, ref lifetime) => { self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime) } - hir::TyImplTraitExistential(_) => { + hir::TyImplTraitExistential(_, ref lifetimes) => { let def_id = tcx.hir.local_def_id(ast_ty.id); - tcx.mk_anon(def_id, Substs::identity_for_item(tcx, def_id)) + self.impl_trait_ty_to_ty(def_id, lifetimes) } hir::TyImplTraitUniversal(fn_def_id, _) => { let impl_trait_def_id = tcx.hir.local_def_id(ast_ty.id); @@ -1097,6 +1097,43 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { result_ty } + pub fn impl_trait_ty_to_ty(&self, def_id: DefId, lifetimes: &[hir::Lifetime]) -> Ty<'tcx> { + debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes); + let tcx = self.tcx(); + let generics = tcx.generics_of(def_id); + + // Fill in the substs of the parent generics + debug!("impl_trait_ty_to_ty: generics={:?}", generics); + let mut substs = Vec::with_capacity(generics.count()); + if let Some(parent_id) = generics.parent { + let parent_generics = tcx.generics_of(parent_id); + Substs::fill_item( + &mut substs, tcx, parent_generics, + &mut |def, _| tcx.mk_region( + ty::ReEarlyBound(def.to_early_bound_region_data())), + &mut |def, _| tcx.mk_param_from_def(def) + ); + + // Replace all lifetimes with 'static + for subst in &mut substs { + if let Some(_) = subst.as_region() { + *subst = Kind::from(&RegionKind::ReStatic); + } + } + debug!("impl_trait_ty_to_ty: substs from parent = {:?}", substs); + } + assert_eq!(substs.len(), generics.parent_count()); + + // Fill in our own generics with the resolved lifetimes + assert_eq!(lifetimes.len(), generics.own_count()); + substs.extend(lifetimes.iter().map(|lt| + Kind::from(self.ast_region_to_region(lt, None)))); + + debug!("impl_trait_ty_to_ty: final substs = {:?}", substs); + + tcx.mk_anon(def_id, tcx.intern_substs(&substs)) + } + pub fn ty_of_arg(&self, ty: &hir::Ty, expected_ty: Option<Ty<'tcx>>) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 91ce4511a31..8f409b68752 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -108,7 +108,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check whether this is a call to a closure where we // haven't yet decided on whether the closure is fn vs // fnmut vs fnonce. If so, we have to defer further processing. - if self.closure_kind(def_id).is_none() { + if self.closure_kind(def_id, substs).is_none() { let closure_ty = self.fn_sig(def_id).subst(self.tcx, substs.substs); let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, @@ -122,6 +122,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { adjustments, fn_sig, closure_def_id: def_id, + closure_substs: substs, }); return Some(CallStep::DeferredClosure(fn_sig)); } @@ -336,6 +337,7 @@ pub struct DeferredCallResolution<'gcx: 'tcx, 'tcx> { adjustments: Vec<Adjustment<'tcx>>, fn_sig: ty::FnSig<'tcx>, closure_def_id: DefId, + closure_substs: ty::ClosureSubsts<'tcx>, } impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> { @@ -344,7 +346,7 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> { // we should not be invoked until the closure kind has been // determined by upvar inference - assert!(fcx.closure_kind(self.closure_def_id).is_some()); + assert!(fcx.closure_kind(self.closure_def_id, self.closure_substs).is_some()); // We may now know enough to figure out fn vs fnmut etc. match fcx.try_overloaded_call_traits(self.call_expr, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index d475fb0cf1a..5b5d697bcf4 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -10,7 +10,7 @@ //! Code for type-checking closure expressions. -use super::{check_fn, Expectation, FnCtxt}; +use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use astconv::AstConv; use rustc::hir::def_id::DefId; @@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("check_closure: ty_of_closure returns {:?}", liberated_sig); - let interior = check_fn( + let generator_types = check_fn( self, self.param_env, liberated_sig, @@ -100,14 +100,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |_, _| span_bug!(expr.span, "closure has region param"), |_, _| { self.infcx - .next_ty_var(TypeVariableOrigin::TransformedUpvar(expr.span)) + .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)) }, ); + let substs = ty::ClosureSubsts { substs }; let closure_type = self.tcx.mk_closure(expr_def_id, substs); - if let Some(interior) = interior { - let closure_substs = ty::ClosureSubsts { substs: substs }; - return self.tcx.mk_generator(expr_def_id, closure_substs, interior); + if let Some(GeneratorTypes { yield_ty, interior }) = generator_types { + self.demand_eqtype(expr.span, + yield_ty, + substs.generator_yield_ty(expr_def_id, self.tcx)); + self.demand_eqtype(expr.span, + liberated_sig.output(), + substs.generator_return_ty(expr_def_id, self.tcx)); + return self.tcx.mk_generator(expr_def_id, substs, interior); } debug!( @@ -135,15 +141,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_kind ); - { - let mut tables = self.tables.borrow_mut(); - tables.closure_tys_mut().insert(expr.hir_id, sig); - match opt_kind { - Some(kind) => { - tables.closure_kinds_mut().insert(expr.hir_id, (kind, None)); - } - None => {} - } + let sig_fn_ptr_ty = self.tcx.mk_fn_ptr(sig); + self.demand_eqtype(expr.span, + sig_fn_ptr_ty, + substs.closure_sig_ty(expr_def_id, self.tcx)); + + if let Some(kind) = opt_kind { + self.demand_eqtype(expr.span, + kind.to_ty(self.tcx), + substs.closure_kind_ty(expr_def_id, self.tcx)); } closure_type diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 8613ec86b4a..b3a7c32140b 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -164,41 +164,63 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; match error { - MethodError::NoMatch(NoMatchData { static_candidates: static_sources, - unsatisfied_predicates, - out_of_scope_traits, - lev_candidate, - mode, - .. }) => { + MethodError::NoMatch(NoMatchData { + static_candidates: static_sources, + unsatisfied_predicates, + out_of_scope_traits, + lev_candidate, + mode, + .. + }) => { let tcx = self.tcx; let actual = self.resolve_type_vars_if_possible(&rcvr_ty); + let ty_string = self.ty_to_string(actual); + let is_method = mode == Mode::MethodCall; + let type_str = if is_method { + "method" + } else if actual.is_enum() { + "variant" + } else { + match (item_name.as_str().chars().next(), actual.is_fresh_ty()) { + (Some(name), false) if name.is_lowercase() => { + "function or associated item" + } + (Some(_), false) => "associated item", + (Some(_), true) | (None, false) => { + "variant or associated item" + } + (None, true) => "variant", + } + }; let mut err = if !actual.references_error() { - struct_span_err!(tcx.sess, span, E0599, - "no {} named `{}` found for type `{}` in the \ - current scope", - if mode == Mode::MethodCall { - "method" - } else { - match item_name.as_str().chars().next() { - Some(name) => { - if name.is_lowercase() { - "function or associated item" - } else { - "associated item" - } - }, - None => { - "" - }, - } - }, - item_name, - self.ty_to_string(actual)) + struct_span_err!( + tcx.sess, + span, + E0599, + "no {} named `{}` found for type `{}` in the current scope", + type_str, + item_name, + ty_string + ) } else { - self.tcx.sess.diagnostic().struct_dummy() + tcx.sess.diagnostic().struct_dummy() }; + if let Some(def) = actual.ty_adt_def() { + if let Some(full_sp) = tcx.hir.span_if_local(def.did) { + let def_sp = tcx.sess.codemap().def_span(full_sp); + err.span_label(def_sp, format!("{} `{}` not found {}", + type_str, + item_name, + if def.is_enum() && !is_method { + "here" + } else { + "for this" + })); + } + } + // If the method name is the name of a field with a function or closure type, // give a helping note that it has to be called as (x.f)(...). if let Some(expr) = rcvr_expr { @@ -240,6 +262,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => {} } } + } else { + err.span_label(span, format!("{} not found in `{}`", type_str, ty_string)); } if self.is_fn_ty(&rcvr_ty, span) { @@ -340,16 +364,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err: &mut DiagnosticBuilder, mut msg: String, candidates: Vec<DefId>) { - let limit = if candidates.len() == 5 { 5 } else { 4 }; - for (i, trait_did) in candidates.iter().take(limit).enumerate() { - msg.push_str(&format!("\ncandidate #{}: `use {};`", - i + 1, - self.tcx.item_path_str(*trait_did))); - } - if candidates.len() > limit { - msg.push_str(&format!("\nand {} others", candidates.len() - limit)); + let module_did = self.tcx.hir.get_module_parent(self.body_id); + let module_id = self.tcx.hir.as_local_node_id(module_did).unwrap(); + let krate = self.tcx.hir.krate(); + let (span, found_use) = UsePlacementFinder::check(self.tcx, krate, module_id); + if let Some(span) = span { + let path_strings = candidates.iter().map(|did| { + // produce an additional newline to separate the new use statement + // from the directly following item. + let additional_newline = if found_use { + "" + } else { + "\n" + }; + format!("use {};\n{}", self.tcx.item_path_str(*did), additional_newline) + }).collect(); + + err.span_suggestions(span, &msg, path_strings); + } else { + let limit = if candidates.len() == 5 { 5 } else { 4 }; + for (i, trait_did) in candidates.iter().take(limit).enumerate() { + msg.push_str(&format!("\ncandidate #{}: `use {};`", + i + 1, + self.tcx.item_path_str(*trait_did))); + } + if candidates.len() > limit { + msg.push_str(&format!("\nand {} others", candidates.len() - limit)); + } + err.note(&msg[..]); } - err.note(&msg[..]); } fn suggest_valid_traits(&self, @@ -604,3 +647,83 @@ impl<'a> Iterator for AllTraits<'a> { }) } } + + +struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> { + target_module: ast::NodeId, + span: Option<Span>, + found_use: bool, + tcx: TyCtxt<'a, 'gcx, 'tcx> +} + +impl<'a, 'tcx, 'gcx> UsePlacementFinder<'a, 'tcx, 'gcx> { + fn check( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + krate: &'tcx hir::Crate, + target_module: ast::NodeId, + ) -> (Option<Span>, bool) { + let mut finder = UsePlacementFinder { + target_module, + span: None, + found_use: false, + tcx, + }; + hir::intravisit::walk_crate(&mut finder, krate); + (finder.span, finder.found_use) + } +} + +impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, 'tcx, 'gcx> { + fn visit_mod( + &mut self, + module: &'tcx hir::Mod, + _: Span, + node_id: ast::NodeId, + ) { + if self.span.is_some() { + return; + } + if node_id != self.target_module { + hir::intravisit::walk_mod(self, module, node_id); + return; + } + // find a use statement + for item_id in &module.item_ids { + let item = self.tcx.hir.expect_item(item_id.id); + match item.node { + hir::ItemUse(..) => { + // don't suggest placing a use before the prelude + // import or other generated ones + if item.span.ctxt().outer().expn_info().is_none() { + self.span = Some(item.span.with_hi(item.span.lo())); + self.found_use = true; + return; + } + }, + // don't place use before extern crate + hir::ItemExternCrate(_) => {} + // but place them before the first other item + _ => if self.span.map_or(true, |span| item.span < span ) { + if item.span.ctxt().outer().expn_info().is_none() { + // don't insert between attributes and an item + if item.attrs.is_empty() { + self.span = Some(item.span.with_hi(item.span.lo())); + } else { + // find the first attribute on the item + for attr in &item.attrs { + if self.span.map_or(true, |span| attr.span < span) { + self.span = Some(attr.span.with_hi(attr.span.lo())); + } + } + } + } + }, + } + } + } + fn nested_visit_map<'this>( + &'this mut self + ) -> hir::intravisit::NestedVisitorMap<'this, 'tcx> { + hir::intravisit::NestedVisitorMap::None + } +} diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b3a07027fb0..09dd334a62d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -213,7 +213,7 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // associated fresh inference variable. Writeback resolves these // variables to get the concrete type, which can be used to // deanonymize TyAnon, after typeck is done with all functions. - anon_types: RefCell<NodeMap<Ty<'tcx>>>, + anon_types: RefCell<DefIdMap<AnonTypeDecl<'tcx>>>, /// Each type parameter has an implicit region bound that /// indicates it must outlive at least the function body (the user @@ -226,6 +226,43 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { body_id: Option<hir::BodyId>, } +/// Information about the anonymous, abstract types whose values we +/// are inferring in this function (these are the `impl Trait` that +/// appear in the return type). +#[derive(Debug)] +struct AnonTypeDecl<'tcx> { + /// The substitutions that we apply to the abstract that that this + /// `impl Trait` desugars to. e.g., if: + /// + /// fn foo<'a, 'b, T>() -> impl Trait<'a> + /// + /// winds up desugared to: + /// + /// abstract type Foo<'x, T>: Trait<'x> + /// fn foo<'a, 'b, T>() -> Foo<'a, T> + /// + /// then `substs` would be `['a, T]`. + substs: &'tcx Substs<'tcx>, + + /// The type variable that represents the value of the abstract type + /// that we require. In other words, after we compile this function, + /// we will be created a constraint like: + /// + /// Foo<'a, T> = ?C + /// + /// where `?C` is the value of this type variable. =) It may + /// naturally refer to the type and lifetime parameters in scope + /// in this function, though ultimately it should only reference + /// those that are arguments to `Foo` in the constraint above. (In + /// other words, `?C` should not include `'b`, even though it's a + /// lifetime parameter on `foo`.) + concrete_ty: Ty<'tcx>, + + /// A list of all required region bounds on the impl Trait type, + /// e.g. `'a` and `'b` in `fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b`. + required_region_bounds: Vec<ty::Region<'tcx>>, +} + impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> { type Target = InferCtxt<'a, 'gcx, 'tcx>; fn deref(&self) -> &Self::Target { @@ -622,7 +659,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { deferred_call_resolutions: RefCell::new(DefIdMap()), deferred_cast_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), - anon_types: RefCell::new(NodeMap()), + anon_types: RefCell::new(DefIdMap()), implicit_region_bound, body_id, } @@ -722,30 +759,12 @@ pub fn provide(providers: &mut Providers) { typeck_item_bodies, typeck_tables_of, has_typeck_tables, - closure_kind, - generator_sig, adt_destructor, used_trait_imports, ..*providers }; } -fn generator_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId) - -> Option<ty::PolyGenSig<'tcx>> { - let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let hir_id = tcx.hir.node_to_hir_id(node_id); - tcx.typeck_tables_of(def_id).generator_sigs()[hir_id].map(|s| ty::Binder(s)) -} - -fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId) - -> ty::ClosureKind { - let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let hir_id = tcx.hir.node_to_hir_id(node_id); - tcx.typeck_tables_of(def_id).closure_kinds()[hir_id].0 -} - fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<ty::Destructor> { @@ -870,7 +889,10 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env, &fn_sig); - check_fn(&inh, param_env, fn_sig, decl, id, body, false).0 + let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, false).0; + // Ensure anon_types have been instantiated prior to entering regionck + fcx.instantiate_anon_types(&fn_sig.output()); + fcx } else { let fcx = FnCtxt::new(&inh, param_env, body.value.id); let expected_type = tcx.type_of(def_id); @@ -981,6 +1003,17 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { _: hir::BodyId, _: Span, _: ast::NodeId) { } } +/// When `check_fn` is invoked on a generator (i.e., a body that +/// includes yield), it returns back some information about the yield +/// points. +struct GeneratorTypes<'tcx> { + /// Type of value that is yielded. + yield_ty: ty::Ty<'tcx>, + + /// Types that are captured (see `GeneratorInterior` for more). + interior: ty::GeneratorInterior<'tcx> +} + /// Helper used for fns and closures. Does the grungy work of checking a function /// body and returns the function context used for that purpose, since in the case of a fn item /// there is still a bit more to do. @@ -994,7 +1027,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fn_id: ast::NodeId, body: &'gcx hir::Body, can_be_generator: bool) - -> (FnCtxt<'a, 'gcx, 'tcx>, Option<ty::GeneratorInterior<'tcx>>) + -> (FnCtxt<'a, 'gcx, 'tcx>, Option<GeneratorTypes<'tcx>>) { let mut fn_sig = fn_sig.clone(); @@ -1044,21 +1077,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id); let gen_ty = if can_be_generator && body.is_generator { - let gen_sig = ty::GenSig { - yield_ty: fcx.yield_ty.unwrap(), - return_ty: ret_ty, - }; - inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, Some(gen_sig)); - let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)); fcx.deferred_generator_interiors.borrow_mut().push((body.id(), witness)); let interior = ty::GeneratorInterior::new(witness); - - inherited.tables.borrow_mut().generator_interiors_mut().insert(fn_hir_id, interior); - - Some(interior) + Some(GeneratorTypes { yield_ty: fcx.yield_ty.unwrap(), interior: interior }) } else { - inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, None); None }; inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig); @@ -1909,20 +1932,34 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// Replace all anonymized types with fresh inference variables /// and record them for writeback. fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T { + debug!("instantiate_anon_types(value={:?})", value); value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| { if let ty::TyAnon(def_id, substs) = ty.sty { + debug!("instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})", def_id, substs); + // Use the same type variable if the exact same TyAnon appears more // than once in the return type (e.g. if it's passed to a type alias). - let id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - if let Some(ty_var) = self.anon_types.borrow().get(&id) { - return ty_var; + if let Some(anon_defn) = self.anon_types.borrow().get(&def_id) { + return anon_defn.concrete_ty; } let span = self.tcx.def_span(def_id); let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span)); - self.anon_types.borrow_mut().insert(id, ty_var); let predicates_of = self.tcx.predicates_of(def_id); let bounds = predicates_of.instantiate(self.tcx, substs); + debug!("instantiate_anon_types: bounds={:?}", bounds); + + let required_region_bounds = + self.tcx.required_region_bounds(ty, bounds.predicates.clone()); + debug!("instantiate_anon_types: required_region_bounds={:?}", + required_region_bounds); + + self.anon_types.borrow_mut().insert(def_id, AnonTypeDecl { + substs, + concrete_ty: ty_var, + required_region_bounds, + }); + debug!("instantiate_anon_types: ty_var={:?}", ty_var); for predicate in bounds.predicates { // Change the predicate to refer to the type variable, @@ -1931,8 +1968,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let predicate = self.instantiate_anon_types(&predicate); // Require that the predicate holds for the concrete type. - let cause = traits::ObligationCause::new(span, self.body_id, + let cause = traits::ObligationCause::new(span, + self.body_id, traits::SizedReturnType); + + debug!("instantiate_anon_types: predicate={:?}", predicate); self.register_predicate(traits::Obligation::new(cause, self.param_env, predicate)); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a17133d412c..b91137aeb68 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -92,6 +92,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{self, Ty}; use rustc::infer::{self, OutlivesEnvironment}; use rustc::ty::adjustment; +use rustc::ty::outlives::Component; use std::mem; use std::ops::Deref; @@ -135,7 +136,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { item_id: ast::NodeId, span: Span, wf_tys: &[Ty<'tcx>]) { - debug!("regionck_item(item.id={:?}, wf_tys={:?}", item_id, wf_tys); + debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys); let subject = self.tcx.hir.local_def_id(item_id); let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), @@ -336,10 +337,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("visit_fn_body body.id {:?} call_site_scope: {:?}", body.id(), call_site_scope); let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); + let body_hir_id = self.tcx.hir.node_to_hir_id(body_id.node_id); self.type_of_node_must_outlive(infer::CallReturn(span), body_hir_id, call_site_region); + + self.constrain_anon_types(); } fn visit_region_obligations(&mut self, node_id: ast::NodeId) @@ -358,6 +362,194 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.body_id); } + /// Go through each of the existential `impl Trait` types that + /// appear in the function signature. For example, if the current + /// function is as follows: + /// + /// fn foo<'a, 'b>(..) -> (impl Bar<'a>, impl Bar<'b>) + /// + /// we would iterate through the `impl Bar<'a>` and the + /// `impl Bar<'b>` here. Remember that each of them has + /// their own "abstract type" definition created for them. As + /// we iterate, we have a `def_id` that corresponds to this + /// definition, and a set of substitutions `substs` that are + /// being supplied to this abstract typed definition in the + /// signature: + /// + /// abstract type Foo1<'x>: Bar<'x>; + /// abstract type Foo2<'x>: Bar<'x>; + /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. } + /// ^^^^ ^^ substs + /// def_id + /// + /// In addition, for each of the types we will have a type + /// variable `concrete_ty` containing the concrete type that + /// this function uses for `Foo1` and `Foo2`. That is, + /// conceptually, there is a constraint like: + /// + /// for<'a> (Foo1<'a> = C) + /// + /// where `C` is `concrete_ty`. For this equation to be satisfiable, + /// the type `C` can only refer to two regions: `'static` and `'a`. + /// + /// The problem is that this type `C` may contain arbitrary + /// region variables. In fact, it is fairly likely that it + /// does! Consider this possible definition of `foo`: + /// + /// fn foo<'a, 'b>(x: &'a i32, y: &'b i32) -> (impl Bar<'a>, impl Bar<'b>) { + /// (&*x, &*y) + /// } + /// + /// Here, the values for the concrete types of the two impl + /// traits will include inference variables: + /// + /// &'0 i32 + /// &'1 i32 + /// + /// Ordinarily, the subtyping rules would ensure that these are + /// sufficiently large. But since `impl Bar<'a>` isn't a specific + /// type per se, we don't get such constraints by default. This + /// is where this function comes into play. It adds extra + /// constraints to ensure that all the regions which appear in the + /// inferred type are regions that could validly appear. + /// + /// This is actually a bit of a tricky constraint in general. We + /// want to say that each variable (e.g., `'0``) can only take on + /// values that were supplied as arguments to the abstract type + /// (e.g., `'a` for `Foo1<'a>`) or `'static`, which is always in + /// scope. We don't have a constraint quite of this kind in the current + /// region checker. + /// + /// What we *do* have is the `<=` relation. So what we do is to + /// find the LUB of all the arguments that appear in the substs: + /// in this case, that would be `LUB('a) = 'a`, and then we apply + /// that as a least bound to the variables (e.g., `'a <= '0`). + /// + /// In some cases this is pretty suboptimal. Consider this example: + /// + /// fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... } + /// + /// Here, the regions `'a` and `'b` appear in the substitutions, + /// so we would generate `LUB('a, 'b)` as a kind of "minimal upper + /// bound", but that turns out be `'static` -- which is clearly + /// too strict! + fn constrain_anon_types(&mut self) { + debug!("constrain_anon_types()"); + + for (&def_id, anon_defn) in self.fcx.anon_types.borrow().iter() { + let concrete_ty = self.resolve_type(anon_defn.concrete_ty); + + debug!("constrain_anon_types: def_id={:?}", def_id); + debug!("constrain_anon_types: anon_defn={:#?}", anon_defn); + debug!("constrain_anon_types: concrete_ty={:?}", concrete_ty); + + let abstract_type_generics = self.tcx.generics_of(def_id); + + let span = self.tcx.def_span(def_id); + + // If there are required region bounds, we can just skip + // ahead. There will already be a registered region + // obligation related `concrete_ty` to those regions. + if anon_defn.required_region_bounds.len() != 0 { + continue; + } + + // There were no `required_region_bounds`, + // so we have to search for a `least_region`. + // Go through all the regions used as arguments to the + // abstract type. These are the parameters to the abstract + // type; so in our example above, `substs` would contain + // `['a]` for the first impl trait and `'b` for the + // second. + let mut least_region = None; + for region_def in &abstract_type_generics.regions { + // Find the index of this region in the list of substitutions. + let index = region_def.index as usize; + + // Get the value supplied for this region from the substs. + let subst_arg = anon_defn.substs[index].as_region().unwrap(); + + // Compute the least upper bound of it with the other regions. + debug!("constrain_anon_types: least_region={:?}", least_region); + debug!("constrain_anon_types: subst_arg={:?}", subst_arg); + match least_region { + None => least_region = Some(subst_arg), + Some(lr) => { + if self.outlives_environment + .free_region_map() + .sub_free_regions(lr, subst_arg) { + // keep the current least region + } else if self.outlives_environment + .free_region_map() + .sub_free_regions(subst_arg, lr) { + // switch to `subst_arg` + least_region = Some(subst_arg); + } else { + // There are two regions (`lr` and + // `subst_arg`) which are not relatable. We can't + // find a best choice. + self.tcx + .sess + .struct_span_err(span, "ambiguous lifetime bound in `impl Trait`") + .span_label(span, + format!("neither `{}` nor `{}` outlives the other", + lr, subst_arg)) + .emit(); + + least_region = Some(self.tcx.mk_region(ty::ReEmpty)); + break; + } + } + } + } + + let least_region = least_region.unwrap_or(self.tcx.types.re_static); + debug!("constrain_anon_types: least_region={:?}", least_region); + + // Require that the type `concrete_ty` outlives + // `least_region`, modulo any type parameters that appear + // in the type, which we ignore. This is because impl + // trait values are assumed to capture all the in-scope + // type parameters. This little loop here just invokes + // `outlives` repeatedly, draining all the nested + // obligations that result. + let mut types = vec![concrete_ty]; + let bound_region = |r| self.sub_regions(infer::CallReturn(span), least_region, r); + while let Some(ty) = types.pop() { + let mut components = self.tcx.outlives_components(ty); + while let Some(component) = components.pop() { + match component { + Component::Region(r) => { + bound_region(r); + } + + Component::Param(_) => { + // ignore type parameters like `T`, they are captured + // implicitly by the `impl Trait` + } + + Component::UnresolvedInferenceVariable(_) => { + // we should get an error that more type + // annotations are needed in this case + self.tcx.sess.delay_span_bug(span, "unresolved inf var in anon"); + } + + Component::Projection(ty::ProjectionTy { substs, item_def_id: _ }) => { + for r in substs.regions() { + bound_region(r); + } + types.extend(substs.types()); + } + + Component::EscapingProjection(more_components) => { + components.extend(more_components); + } + } + } + } + } + } + fn resolve_regions_and_report_errors(&self) { self.fcx.resolve_regions_and_report_errors(self.subject_def_id, &self.region_scope_tree, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 9a70a8699aa..2e0d0ddfc39 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -45,16 +45,14 @@ use super::FnCtxt; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; +use rustc::hir::def_id::DefId; use rustc::ty::{self, Ty, TyCtxt}; use rustc::infer::UpvarRegion; use syntax::ast; use syntax_pos::Span; use rustc::hir; use rustc::hir::def_id::LocalDefId; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::util::nodemap::FxHashMap; - -use std::collections::hash_map::Entry; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn closure_analyze(&self, body: &'gcx hir::Body) { @@ -65,7 +63,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -struct InferBorrowKindVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +struct InferBorrowKindVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, } @@ -79,14 +77,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> { hir::ExprClosure(cc, _, body_id, _, is_generator) => { let body = self.fcx.tcx.hir.body(body_id); self.visit_body(body); - self.fcx.analyze_closure((expr.id, expr.hir_id), - expr.span, - body, - cc, - is_generator); + self.fcx + .analyze_closure(expr.id, expr.hir_id, expr.span, body, cc, is_generator); } - _ => { } + _ => {} } intravisit::walk_expr(self, expr); @@ -94,35 +89,43 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - fn analyze_closure(&self, - (closure_node_id, closure_hir_id): (ast::NodeId, hir::HirId), - span: Span, - body: &hir::Body, - capture_clause: hir::CaptureClause, - gen: bool) { + fn analyze_closure( + &self, + closure_node_id: ast::NodeId, + closure_hir_id: hir::HirId, + span: Span, + body: &hir::Body, + capture_clause: hir::CaptureClause, + is_generator: bool, + ) { /*! * Analysis starting point. */ - debug!("analyze_closure(id={:?}, body.id={:?})", closure_node_id, body.id()); + debug!( + "analyze_closure(id={:?}, body.id={:?})", + closure_node_id, + body.id() + ); - let infer_kind = if gen { - false - } else { - match self.tables - .borrow_mut() - .closure_kinds_mut() - .entry(closure_hir_id) { - Entry::Occupied(_) => false, - Entry::Vacant(entry) => { - debug!("check_closure: adding closure {:?} as Fn", closure_node_id); - entry.insert((ty::ClosureKind::Fn, None)); - true - } + // Extract the type of the closure. + let (closure_def_id, closure_substs) = match self.node_ty(closure_hir_id).sty { + ty::TyClosure(def_id, substs) | ty::TyGenerator(def_id, substs, _) => (def_id, substs), + ref t => { + span_bug!( + span, + "type of closure expr {:?} is not a closure {:?}", + closure_node_id, + t + ); } }; - let closure_def_id = self.tcx.hir.local_def_id(closure_node_id); + let infer_kind = if is_generator { + false + } else { + self.closure_kind(closure_def_id, closure_substs).is_none() + }; self.tcx.with_freevars(closure_node_id, |freevars| { for freevar in freevars { @@ -133,51 +136,63 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("seed upvar_id {:?}", upvar_id); let capture_kind = match capture_clause { - hir::CaptureByValue => { - ty::UpvarCapture::ByValue - } + hir::CaptureByValue => ty::UpvarCapture::ByValue, hir::CaptureByRef => { let origin = UpvarRegion(upvar_id, span); let freevar_region = self.next_region_var(origin); - let upvar_borrow = ty::UpvarBorrow { kind: ty::ImmBorrow, - region: freevar_region }; + let upvar_borrow = ty::UpvarBorrow { + kind: ty::ImmBorrow, + region: freevar_region, + }; ty::UpvarCapture::ByRef(upvar_borrow) } }; - self.tables.borrow_mut().upvar_capture_map.insert(upvar_id, capture_kind); + self.tables + .borrow_mut() + .upvar_capture_map + .insert(upvar_id, capture_kind); } }); - { - let body_owner_def_id = self.tcx.hir.body_owner_def_id(body.id()); - let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id); - let mut delegate = InferBorrowKind { - fcx: self, - adjust_closure_kinds: FxHashMap(), - adjust_upvar_captures: ty::UpvarCaptureMap::default(), - }; - euv::ExprUseVisitor::with_infer(&mut delegate, - &self.infcx, - self.param_env, - region_scope_tree, - &self.tables.borrow()) - .consume_body(body); - - // Write the adjusted values back into the main tables. - if infer_kind { - if let Some(kind) = delegate.adjust_closure_kinds - .remove(&closure_def_id.to_local()) { - self.tables - .borrow_mut() - .closure_kinds_mut() - .insert(closure_hir_id, kind); - } + let body_owner_def_id = self.tcx.hir.body_owner_def_id(body.id()); + let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id); + let mut delegate = InferBorrowKind { + fcx: self, + closure_def_id: closure_def_id, + current_closure_kind: ty::ClosureKind::LATTICE_BOTTOM, + current_origin: None, + adjust_upvar_captures: ty::UpvarCaptureMap::default(), + }; + euv::ExprUseVisitor::with_infer( + &mut delegate, + &self.infcx, + self.param_env, + region_scope_tree, + &self.tables.borrow(), + ).consume_body(body); + + if infer_kind { + // Unify the (as yet unbound) type variable in the closure + // substs with the kind we inferred. + let inferred_kind = delegate.current_closure_kind; + let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx); + self.demand_eqtype(span, inferred_kind.to_ty(self.tcx), closure_kind_ty); + + // If we have an origin, store it. + if let Some(origin) = delegate.current_origin { + self.tables + .borrow_mut() + .closure_kind_origins_mut() + .insert(closure_hir_id, origin); } - self.tables.borrow_mut().upvar_capture_map.extend( - delegate.adjust_upvar_captures); } + self.tables + .borrow_mut() + .upvar_capture_map + .extend(delegate.adjust_upvar_captures); + // Now that we've analyzed the closure, we know how each // variable is borrowed, and we know what traits the closure // implements (Fn vs FnMut etc). We now have some updates to do @@ -190,36 +205,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // C, then the type would have infinite size (and the // inference algorithm will reject it). - // Extract the type variables UV0...UVn. - let (def_id, closure_substs) = match self.node_ty(closure_hir_id).sty { - ty::TyClosure(def_id, substs) | - ty::TyGenerator(def_id, substs, _) => (def_id, substs), - ref t => { - span_bug!( - span, - "type of closure expr {:?} is not a closure {:?}", - closure_node_id, t); - } - }; - - // Equate the type variables with the actual types. + // Equate the type variables for the upvars with the actual types. let final_upvar_tys = self.final_upvar_tys(closure_node_id); - debug!("analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}", - closure_node_id, closure_substs, final_upvar_tys); - for (upvar_ty, final_upvar_ty) in - closure_substs.upvar_tys(def_id, self.tcx).zip(final_upvar_tys) + debug!( + "analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}", + closure_node_id, + closure_substs, + final_upvar_tys + ); + for (upvar_ty, final_upvar_ty) in closure_substs + .upvar_tys(closure_def_id, self.tcx) + .zip(final_upvar_tys) { self.demand_eqtype(span, final_upvar_ty, upvar_ty); } // If we are also inferred the closure kind here, // process any deferred resolutions. - if infer_kind { - let deferred_call_resolutions = - self.remove_deferred_call_resolutions(closure_def_id); - for deferred_call_resolution in deferred_call_resolutions { - deferred_call_resolution.resolve(self); - } + let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id); + for deferred_call_resolution in deferred_call_resolutions { + deferred_call_resolution.resolve(self); } } @@ -234,51 +239,78 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let closure_def_index = tcx.hir.local_def_id(closure_id); tcx.with_freevars(closure_id, |freevars| { - freevars.iter().map(|freevar| { - let var_node_id = freevar.var_id(); - let var_hir_id = tcx.hir.node_to_hir_id(var_node_id); - let freevar_ty = self.node_ty(var_hir_id); - let upvar_id = ty::UpvarId { - var_id: var_hir_id, - closure_expr_id: LocalDefId::from_def_id(closure_def_index), - }; - let capture = self.tables.borrow().upvar_capture(upvar_id); - - debug!("var_id={:?} freevar_ty={:?} capture={:?}", - var_node_id, freevar_ty, capture); - - match capture { - ty::UpvarCapture::ByValue => freevar_ty, - ty::UpvarCapture::ByRef(borrow) => - tcx.mk_ref(borrow.region, - ty::TypeAndMut { - ty: freevar_ty, - mutbl: borrow.kind.to_mutbl_lossy(), - }), - } - }).collect() + freevars + .iter() + .map(|freevar| { + let var_node_id = freevar.var_id(); + let var_hir_id = tcx.hir.node_to_hir_id(var_node_id); + let freevar_ty = self.node_ty(var_hir_id); + let upvar_id = ty::UpvarId { + var_id: var_hir_id, + closure_expr_id: LocalDefId::from_def_id(closure_def_index), + }; + let capture = self.tables.borrow().upvar_capture(upvar_id); + + debug!( + "var_id={:?} freevar_ty={:?} capture={:?}", + var_node_id, + freevar_ty, + capture + ); + + match capture { + ty::UpvarCapture::ByValue => freevar_ty, + ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref( + borrow.region, + ty::TypeAndMut { + ty: freevar_ty, + mutbl: borrow.kind.to_mutbl_lossy(), + }, + ), + } + }) + .collect() }) } } -struct InferBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +struct InferBorrowKind<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - adjust_closure_kinds: FxHashMap<LocalDefId, (ty::ClosureKind, Option<(Span, ast::Name)>)>, + + // The def-id of the closure whose kind and upvar accesses are being inferred. + closure_def_id: DefId, + + // The kind that we have inferred that the current closure + // requires. Note that we *always* infer a minimal kind, even if + // we don't always *use* that in the final result (i.e., sometimes + // we've taken the closure kind from the expectations instead, and + // for generators we don't even implement the closure traits + // really). + current_closure_kind: ty::ClosureKind, + + // If we modified `current_closure_kind`, this field contains a `Some()` with the + // variable access that caused us to do so. + current_origin: Option<(Span, ast::Name)>, + + // For each upvar that we access, we track the minimal kind of + // access we need (ref, ref mut, move, etc). adjust_upvar_captures: ty::UpvarCaptureMap<'tcx>, } impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { - fn adjust_upvar_borrow_kind_for_consume(&mut self, - cmt: mc::cmt<'tcx>, - mode: euv::ConsumeMode) - { - debug!("adjust_upvar_borrow_kind_for_consume(cmt={:?}, mode={:?})", - cmt, mode); + fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { + debug!( + "adjust_upvar_borrow_kind_for_consume(cmt={:?}, mode={:?})", + cmt, + mode + ); // we only care about moves match mode { - euv::Copy => { return; } - euv::Move(_) => { } + euv::Copy => { + return; + } + euv::Move(_) => {} } let tcx = self.fcx.tcx; @@ -287,28 +319,39 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { // for that to be legal, the upvar would have to be borrowed // by value instead let guarantor = cmt.guarantor(); - debug!("adjust_upvar_borrow_kind_for_consume: guarantor={:?}", - guarantor); - debug!("adjust_upvar_borrow_kind_for_consume: guarantor.cat={:?}", - guarantor.cat); + debug!( + "adjust_upvar_borrow_kind_for_consume: guarantor={:?}", + guarantor + ); + debug!( + "adjust_upvar_borrow_kind_for_consume: guarantor.cat={:?}", + guarantor.cat + ); match guarantor.cat { Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::Implicit(..)) => { - debug!("adjust_upvar_borrow_kind_for_consume: found deref with note {:?}", - cmt.note); + debug!( + "adjust_upvar_borrow_kind_for_consume: found deref with note {:?}", + cmt.note + ); match guarantor.note { mc::NoteUpvarRef(upvar_id) => { - debug!("adjust_upvar_borrow_kind_for_consume: \ - setting upvar_id={:?} to by value", - upvar_id); + debug!( + "adjust_upvar_borrow_kind_for_consume: \ + setting upvar_id={:?} to by value", + upvar_id + ); // to move out of an upvar, this must be a FnOnce closure - self.adjust_closure_kind(upvar_id.closure_expr_id, - ty::ClosureKind::FnOnce, - guarantor.span, - var_name(tcx, upvar_id.var_id)); - - self.adjust_upvar_captures.insert(upvar_id, ty::UpvarCapture::ByValue); + self.adjust_closure_kind( + upvar_id.closure_expr_id, + ty::ClosureKind::FnOnce, + guarantor.span, + var_name(tcx, upvar_id.var_id), + ); + + self.adjust_upvar_captures + .insert(upvar_id, ty::UpvarCapture::ByValue); } mc::NoteClosureEnv(upvar_id) => { // we get just a closureenv ref if this is a @@ -317,16 +360,17 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { // must still adjust the kind of the closure // to be a FnOnce closure to permit moves out // of the environment. - self.adjust_closure_kind(upvar_id.closure_expr_id, - ty::ClosureKind::FnOnce, - guarantor.span, - var_name(tcx, upvar_id.var_id)); - } - mc::NoteNone => { + self.adjust_closure_kind( + upvar_id.closure_expr_id, + ty::ClosureKind::FnOnce, + guarantor.span, + var_name(tcx, upvar_id.var_id), + ); } + mc::NoteNone => {} } } - _ => { } + _ => {} } } @@ -334,8 +378,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { /// to). If cmt contains any by-ref upvars, this implies that /// those upvars must be borrowed using an `&mut` borrow. fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: mc::cmt<'tcx>) { - debug!("adjust_upvar_borrow_kind_for_mut(cmt={:?})", - cmt); + debug!("adjust_upvar_borrow_kind_for_mut(cmt={:?})", cmt); match cmt.cat.clone() { Categorization::Deref(base, mc::Unique) | @@ -368,8 +411,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } fn adjust_upvar_borrow_kind_for_unique(&mut self, cmt: mc::cmt<'tcx>) { - debug!("adjust_upvar_borrow_kind_for_unique(cmt={:?})", - cmt); + debug!("adjust_upvar_borrow_kind_for_unique(cmt={:?})", cmt); match cmt.cat.clone() { Categorization::Deref(base, mc::Unique) | @@ -393,16 +435,11 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { Categorization::StaticItem | Categorization::Rvalue(..) | Categorization::Local(_) | - Categorization::Upvar(..) => { - } + Categorization::Upvar(..) => {} } } - fn try_adjust_upvar_deref(&mut self, - cmt: mc::cmt<'tcx>, - borrow_kind: ty::BorrowKind) - -> bool - { + fn try_adjust_upvar_deref(&mut self, cmt: mc::cmt<'tcx>, borrow_kind: ty::BorrowKind) -> bool { assert!(match borrow_kind { ty::MutBorrow => true, ty::UniqueImmBorrow => true, @@ -422,10 +459,12 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_upvar_borrow_kind(upvar_id, borrow_kind); // also need to be in an FnMut closure since this is not an ImmBorrow - self.adjust_closure_kind(upvar_id.closure_expr_id, - ty::ClosureKind::FnMut, - cmt.span, - var_name(tcx, upvar_id.var_id)); + self.adjust_closure_kind( + upvar_id.closure_expr_id, + ty::ClosureKind::FnMut, + cmt.span, + var_name(tcx, upvar_id.var_id), + ); true } @@ -433,16 +472,16 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { // this kind of deref occurs in a `move` closure, or // for a by-value upvar; in either case, to mutate an // upvar, we need to be an FnMut closure - self.adjust_closure_kind(upvar_id.closure_expr_id, - ty::ClosureKind::FnMut, - cmt.span, - var_name(tcx, upvar_id.var_id)); + self.adjust_closure_kind( + upvar_id.closure_expr_id, + ty::ClosureKind::FnMut, + cmt.span, + var_name(tcx, upvar_id.var_id), + ); true } - mc::NoteNone => { - false - } + mc::NoteNone => false, } } @@ -451,13 +490,17 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { /// moving from left to right as needed (but never right to left). /// Here the argument `mutbl` is the borrow_kind that is required by /// some particular use. - fn adjust_upvar_borrow_kind(&mut self, - upvar_id: ty::UpvarId, - kind: ty::BorrowKind) { - let upvar_capture = self.adjust_upvar_captures.get(&upvar_id).cloned() + fn adjust_upvar_borrow_kind(&mut self, upvar_id: ty::UpvarId, kind: ty::BorrowKind) { + let upvar_capture = self.adjust_upvar_captures + .get(&upvar_id) + .cloned() .unwrap_or_else(|| self.fcx.tables.borrow().upvar_capture(upvar_id)); - debug!("adjust_upvar_borrow_kind(upvar_id={:?}, upvar_capture={:?}, kind={:?})", - upvar_id, upvar_capture, kind); + debug!( + "adjust_upvar_borrow_kind(upvar_id={:?}, upvar_capture={:?}, kind={:?})", + upvar_id, + upvar_capture, + kind + ); match upvar_capture { ty::UpvarCapture::ByValue => { @@ -470,99 +513,107 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { (ty::ImmBorrow, ty::MutBorrow) | (ty::UniqueImmBorrow, ty::MutBorrow) => { upvar_borrow.kind = kind; - self.adjust_upvar_captures.insert(upvar_id, - ty::UpvarCapture::ByRef(upvar_borrow)); + self.adjust_upvar_captures + .insert(upvar_id, ty::UpvarCapture::ByRef(upvar_borrow)); } // Take LHS: (ty::ImmBorrow, ty::ImmBorrow) | (ty::UniqueImmBorrow, ty::ImmBorrow) | (ty::UniqueImmBorrow, ty::UniqueImmBorrow) | - (ty::MutBorrow, _) => { - } + (ty::MutBorrow, _) => {} } } } } - fn adjust_closure_kind(&mut self, - closure_id: LocalDefId, - new_kind: ty::ClosureKind, - upvar_span: Span, - var_name: ast::Name) { - debug!("adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})", - closure_id, new_kind, upvar_span, var_name); - - let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned() - .or_else(|| { - let closure_id = self.fcx.tcx.hir.local_def_id_to_hir_id(closure_id); - self.fcx.tables.borrow().closure_kinds().get(closure_id).cloned() - }); - - if let Some((existing_kind, _)) = closure_kind { - debug!("adjust_closure_kind: closure_id={:?}, existing_kind={:?}, new_kind={:?}", - closure_id, existing_kind, new_kind); - - match (existing_kind, new_kind) { - (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | - (ty::ClosureKind::FnOnce, _) => { - // no change needed - } + fn adjust_closure_kind( + &mut self, + closure_id: LocalDefId, + new_kind: ty::ClosureKind, + upvar_span: Span, + var_name: ast::Name, + ) { + debug!( + "adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})", + closure_id, + new_kind, + upvar_span, + var_name + ); + + // Is this the closure whose kind is currently being inferred? + if closure_id.to_def_id() != self.closure_def_id { + debug!("adjust_closure_kind: not current closure"); + return; + } - (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) | - (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // new kind is stronger than the old kind - self.adjust_closure_kinds.insert( - closure_id, - (new_kind, Some((upvar_span, var_name))) - ); - } + // closures start out as `Fn`. + let existing_kind = self.current_closure_kind; + + debug!( + "adjust_closure_kind: closure_id={:?}, existing_kind={:?}, new_kind={:?}", + closure_id, + existing_kind, + new_kind + ); + + match (existing_kind, new_kind) { + (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | + (ty::ClosureKind::FnMut, ty::ClosureKind::Fn) | + (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | + (ty::ClosureKind::FnOnce, _) => { + // no change needed + } + + (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) | + (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | + (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { + // new kind is stronger than the old kind + self.current_closure_kind = new_kind; + self.current_origin = Some((upvar_span, var_name)); } } } } impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { - fn consume(&mut self, - _consume_id: ast::NodeId, - _consume_span: Span, - cmt: mc::cmt<'tcx>, - mode: euv::ConsumeMode) - { + fn consume( + &mut self, + _consume_id: ast::NodeId, + _consume_span: Span, + cmt: mc::cmt<'tcx>, + mode: euv::ConsumeMode, + ) { debug!("consume(cmt={:?},mode={:?})", cmt, mode); self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } - fn matched_pat(&mut self, - _matched_pat: &hir::Pat, - _cmt: mc::cmt<'tcx>, - _mode: euv::MatchMode) - {} - - fn consume_pat(&mut self, - _consume_pat: &hir::Pat, - cmt: mc::cmt<'tcx>, - mode: euv::ConsumeMode) - { + fn matched_pat(&mut self, _matched_pat: &hir::Pat, _cmt: mc::cmt<'tcx>, _mode: euv::MatchMode) { + } + + fn consume_pat(&mut self, _consume_pat: &hir::Pat, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { debug!("consume_pat(cmt={:?},mode={:?})", cmt, mode); self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } - fn borrow(&mut self, - borrow_id: ast::NodeId, - _borrow_span: Span, - cmt: mc::cmt<'tcx>, - _loan_region: ty::Region<'tcx>, - bk: ty::BorrowKind, - _loan_cause: euv::LoanCause) - { - debug!("borrow(borrow_id={}, cmt={:?}, bk={:?})", - borrow_id, cmt, bk); + fn borrow( + &mut self, + borrow_id: ast::NodeId, + _borrow_span: Span, + cmt: mc::cmt<'tcx>, + _loan_region: ty::Region<'tcx>, + bk: ty::BorrowKind, + _loan_cause: euv::LoanCause, + ) { + debug!( + "borrow(borrow_id={}, cmt={:?}, bk={:?})", + borrow_id, + cmt, + bk + ); match bk { - ty::ImmBorrow => { } + ty::ImmBorrow => {} ty::UniqueImmBorrow => { self.adjust_upvar_borrow_kind_for_unique(cmt); } @@ -572,19 +623,16 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { } } - fn decl_without_init(&mut self, - _id: ast::NodeId, - _span: Span) - {} - - fn mutate(&mut self, - _assignment_id: ast::NodeId, - _assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, - _mode: euv::MutateMode) - { - debug!("mutate(assignee_cmt={:?})", - assignee_cmt); + fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {} + + fn mutate( + &mut self, + _assignment_id: ast::NodeId, + _assignment_span: Span, + assignee_cmt: mc::cmt<'tcx>, + _mode: euv::MutateMode, + ) { + debug!("mutate(assignee_cmt={:?})", assignee_cmt); self.adjust_upvar_borrow_kind_for_mut(assignee_cmt); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index ce2ac73a27e..1052f031bbf 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -18,8 +18,9 @@ use rustc::hir::def_id::{DefId, DefIndex}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::infer::{InferCtxt}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::fold::{TypeFolder,TypeFoldable}; -use rustc::util::nodemap::DefIdSet; +use rustc::ty::fold::{TypeFolder, TypeFoldable}; +use rustc::ty::subst::{Kind, Substs}; +use rustc::util::nodemap::{DefIdSet, FxHashMap}; use syntax::ast; use syntax_pos::Span; use std::mem; @@ -46,8 +47,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { wbcx.visit_anon_types(); wbcx.visit_cast_types(); wbcx.visit_free_region_map(); - wbcx.visit_generator_sigs(); - wbcx.visit_generator_interiors(); let used_trait_imports = mem::replace(&mut self.tables.borrow_mut().used_trait_imports, Rc::new(DefIdSet())); @@ -56,6 +55,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { wbcx.tables.tainted_by_errors = self.is_tainted_by_errors(); + debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables); + self.tcx.alloc_tables(wbcx.tables) } } @@ -243,21 +244,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); let common_local_id_root = fcx_tables.local_id_root.unwrap(); - for (&id, closure_ty) in fcx_tables.closure_tys().iter() { - let hir_id = hir::HirId { - owner: common_local_id_root.index, - local_id: id, - }; - let closure_ty = self.resolve(closure_ty, &hir_id); - self.tables.closure_tys_mut().insert(hir_id, closure_ty); - } - - for (&id, &closure_kind) in fcx_tables.closure_kinds().iter() { + for (&id, &origin) in fcx_tables.closure_kind_origins().iter() { let hir_id = hir::HirId { owner: common_local_id_root.index, local_id: id, }; - self.tables.closure_kinds_mut().insert(hir_id, closure_kind); + self.tables.closure_kind_origins_mut().insert(hir_id, origin); } } @@ -285,8 +277,23 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { fn visit_anon_types(&mut self) { let gcx = self.tcx().global_tcx(); - for (&node_id, &concrete_ty) in self.fcx.anon_types.borrow().iter() { - let inside_ty = self.resolve(&concrete_ty, &node_id); + for (&def_id, anon_defn) in self.fcx.anon_types.borrow().iter() { + let node_id = gcx.hir.as_local_node_id(def_id).unwrap(); + let inside_ty = self.resolve(&anon_defn.concrete_ty, &node_id); + + // Use substs to build up a reverse map from regions + // to their identity mappings. + // This is necessary because of `impl Trait` lifetimes + // are computed by replacing existing lifetimes with 'static + // and remapping only those used in the `impl Trait` return type, + // resulting in the parameters shifting. + let id_substs = Substs::identity_for_item(gcx, def_id); + let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> = + anon_defn.substs + .iter() + .enumerate() + .map(|(index, subst)| (*subst, id_substs[index])) + .collect(); // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, @@ -295,25 +302,39 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { match *r { // 'static and early-bound regions are valid. ty::ReStatic | - ty::ReEarlyBound(_) | ty::ReEmpty => r, - ty::ReFree(_) | - ty::ReLateBound(..) | - ty::ReScope(_) | - ty::ReSkolemized(..) => { - let span = node_id.to_span(&self.fcx.tcx); - span_err!(self.tcx().sess, span, E0564, - "only named lifetimes are allowed in `impl Trait`, \ - but `{}` was found in the type `{}`", r, inside_ty); - gcx.types.re_static - } - - ty::ReVar(_) | - ty::ReErased => { - let span = node_id.to_span(&self.fcx.tcx); - span_bug!(span, "invalid region in impl Trait: {:?}", r); - } + // All other regions, we map them appropriately to their adjusted + // indices, erroring if we find any lifetimes that were not mapped + // into the new set. + _ => if let Some(r1) = + map.get(&Kind::from(r)).and_then(|k| k.as_region()) { r1 } else + { + // No mapping was found. This means that + // it is either a disallowed lifetime, + // which will be caught by regionck, or it + // is a region in a non-upvar closure + // generic, which is explicitly + // allowed. If that surprises you, read + // on. + // + // The case of closure is a somewhat + // subtle (read: hacky) consideration. The + // problem is that our closure types + // currently include all the lifetime + // parameters declared on the enclosing + // function, even if they are unused by + // the closure itself. We can't readily + // filter them out, so here we replace + // those values with `'empty`. This can't + // really make a difference to the rest of + // the compiler; those regions are ignored + // for the outlives relation, and hence + // don't affect trait selection or auto + // traits, and they are erased during + // trans. + gcx.types.re_empty + }, } }); @@ -388,33 +409,6 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } - fn visit_generator_interiors(&mut self) { - let common_local_id_root = self.fcx.tables.borrow().local_id_root.unwrap(); - for (&id, interior) in self.fcx.tables.borrow().generator_interiors().iter() { - let hir_id = hir::HirId { - owner: common_local_id_root.index, - local_id: id, - }; - let interior = self.resolve(interior, &hir_id); - self.tables.generator_interiors_mut().insert(hir_id, interior); - } - } - - fn visit_generator_sigs(&mut self) { - let common_local_id_root = self.fcx.tables.borrow().local_id_root.unwrap(); - for (&id, gen_sig) in self.fcx.tables.borrow().generator_sigs().iter() { - let hir_id = hir::HirId { - owner: common_local_id_root.index, - local_id: id, - }; - let gen_sig = gen_sig.map(|s| ty::GenSig { - yield_ty: self.resolve(&s.yield_ty, &hir_id), - return_ty: self.resolve(&s.return_ty, &hir_id), - }); - self.tables.generator_sigs_mut().insert(hir_id, gen_sig); - } - } - fn visit_liberated_fn_sigs(&mut self) { let fcx_tables = self.fcx.tables.borrow(); debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b5fbbeb1692..7de29868d43 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -784,7 +784,7 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let hir_id = self.tcx.hir.node_to_hir_id(lt.id); match self.tcx.named_region(hir_id) { Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {} - Some(rl::Region::LateBound(debruijn, _)) | + Some(rl::Region::LateBound(debruijn, _, _)) | Some(rl::Region::LateBoundAnon(debruijn, _)) if debruijn.depth < self.binder_depth => {} _ => self.has_late_bound_regions = Some(lt.span), @@ -935,6 +935,10 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } + NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(ref exist_ty, _), .. }) => { + (&exist_ty.generics, None) + } + _ => (&no_generics, None) }; @@ -1015,9 +1019,31 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // cares about anything but the length is instantiation, // and we don't do that for closures. if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node { + // add a dummy parameter for the closure kind + types.push(ty::TypeParameterDef { + index: type_start, + name: Symbol::intern("<closure_kind>"), + def_id, + has_default: false, + object_lifetime_default: rl::Set1::Empty, + pure_wrt_drop: false, + synthetic: None, + }); + + // add a dummy parameter for the closure signature + types.push(ty::TypeParameterDef { + index: type_start + 1, + name: Symbol::intern("<closure_signature>"), + def_id, + has_default: false, + object_lifetime_default: rl::Set1::Empty, + pure_wrt_drop: false, + synthetic: None, + }); + tcx.with_freevars(node_id, |fv| { - types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef { - index: type_start + i as u32, + types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef { + index: type_start + i, name: Symbol::intern("<upvar>"), def_id, has_default: false, @@ -1152,14 +1178,19 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id); } - tcx.mk_closure(def_id, Substs::for_item( - tcx, def_id, - |def, _| { - let region = def.to_early_bound_region_data(); - tcx.mk_region(ty::ReEarlyBound(region)) - }, - |def, _| tcx.mk_param_from_def(def) - )) + let substs = ty::ClosureSubsts { + substs: Substs::for_item( + tcx, + def_id, + |def, _| { + let region = def.to_early_bound_region_data(); + tcx.mk_region(ty::ReEarlyBound(region)) + }, + |def, _| tcx.mk_param_from_def(def) + ) + }; + + tcx.mk_closure(def_id, substs) } NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) { @@ -1238,7 +1269,14 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } NodeExpr(&hir::Expr { node: hir::ExprClosure(..), hir_id, .. }) => { - tcx.typeck_tables_of(def_id).closure_tys()[hir_id] + let tables = tcx.typeck_tables_of(def_id); + match tables.node_id_to_type(hir_id).sty { + ty::TyClosure(closure_def_id, closure_substs) => { + assert_eq!(def_id, closure_def_id); + return closure_substs.closure_sig(closure_def_id, tcx); + } + ref t => bug!("closure with non-closure type: {:?}", t), + } } x => { @@ -1358,6 +1396,8 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, use rustc::hir::map::*; use rustc::hir::*; + debug!("explicit_predicates_of(def_id={:?})", def_id); + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let node = tcx.hir.get(node_id); @@ -1412,17 +1452,28 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - NodeTy(&Ty { node: TyImplTraitExistential(ref bounds), span, .. }) => { + NodeTy(&Ty { node: TyImplTraitExistential(ref exist_ty, _), span, .. }) => { let substs = Substs::identity_for_item(tcx, def_id); let anon_ty = tcx.mk_anon(def_id, substs); + debug!("explicit_predicates_of: anon_ty={:?}", anon_ty); + // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`. - let bounds = compute_bounds(&icx, anon_ty, bounds, + let bounds = compute_bounds(&icx, + anon_ty, + &exist_ty.bounds, SizedByDefault::Yes, span); + + debug!("explicit_predicates_of: bounds={:?}", bounds); + + let predicates = bounds.predicates(tcx, anon_ty); + + debug!("explicit_predicates_of: predicates={:?}", predicates); + return ty::GenericPredicates { parent: None, - predicates: bounds.predicates(tcx, anon_ty) + predicates: predicates }; } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 4c518167e08..820c3e856db 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -145,11 +145,13 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait { let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); + let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight"); clean::Trait { unsafety: cx.tcx.trait_def(did).unsafety, generics, items: trait_items, bounds: supertrait_bounds, + is_spotlight, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 101874e495b..538737e7fe4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -44,6 +44,7 @@ use rustc::hir; use rustc_const_math::ConstInt; use std::{mem, slice, vec}; +use std::iter::FromIterator; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; @@ -151,7 +152,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { match module.inner { ModuleItem(ref module) => { for it in &module.items { - if it.is_extern_crate() && it.attrs.has_doc_masked() { + if it.is_extern_crate() && it.attrs.has_doc_flag("masked") { masked_crates.insert(it.def_id.krate); } } @@ -300,6 +301,11 @@ impl Item { pub fn doc_value<'a>(&'a self) -> Option<&'a str> { self.attrs.doc_value() } + /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined + /// with newlines. + pub fn collapsed_doc_value(&self) -> Option<String> { + self.attrs.collapsed_doc_value() + } pub fn is_crate(&self) -> bool { match self.inner { StrippedItem(box ModuleItem(Module { is_crate: true, ..})) | @@ -564,9 +570,69 @@ impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I { } } +/// A portion of documentation, extracted from a `#[doc]` attribute. +/// +/// Each variant contains the line number within the complete doc-comment where the fragment +/// starts, as well as the Span where the corresponding doc comment or attribute is located. +/// +/// Included files are kept separate from inline doc comments so that proper line-number +/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are +/// kept separate because of issue #42760. +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)] +pub enum DocFragment { + // FIXME #44229 (misdreavus): sugared and raw doc comments can be brought back together once + // hoedown is completely removed from rustdoc. + /// A doc fragment created from a `///` or `//!` doc comment. + SugaredDoc(usize, syntax_pos::Span, String), + /// A doc fragment created from a "raw" `#[doc=""]` attribute. + RawDoc(usize, syntax_pos::Span, String), + /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the + /// given filename and the file contents. + Include(usize, syntax_pos::Span, String, String), +} + +impl DocFragment { + pub fn as_str(&self) -> &str { + match *self { + DocFragment::SugaredDoc(_, _, ref s) => &s[..], + DocFragment::RawDoc(_, _, ref s) => &s[..], + DocFragment::Include(_, _, _, ref s) => &s[..], + } + } + + pub fn span(&self) -> syntax_pos::Span { + match *self { + DocFragment::SugaredDoc(_, span, _) | + DocFragment::RawDoc(_, span, _) | + DocFragment::Include(_, span, _, _) => span, + } + } +} + +impl<'a> FromIterator<&'a DocFragment> for String { + fn from_iter<T>(iter: T) -> Self + where + T: IntoIterator<Item = &'a DocFragment> + { + iter.into_iter().fold(String::new(), |mut acc, frag| { + if !acc.is_empty() { + acc.push('\n'); + } + match *frag { + DocFragment::SugaredDoc(_, _, ref docs) + | DocFragment::RawDoc(_, _, ref docs) + | DocFragment::Include(_, _, _, ref docs) => + acc.push_str(docs), + } + + acc + }) + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug, Default)] pub struct Attributes { - pub doc_strings: Vec<String>, + pub doc_strings: Vec<DocFragment>, pub other_attrs: Vec<ast::Attribute>, pub cfg: Option<Rc<Cfg>>, pub span: Option<syntax_pos::Span>, @@ -596,12 +662,53 @@ impl Attributes { None } - pub fn has_doc_masked(&self) -> bool { + /// Reads a `MetaItem` from within an attribute, looks for whether it is a + /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from + /// its expansion. + fn extract_include(mi: &ast::MetaItem) + -> Option<(String, String)> + { + mi.meta_item_list().and_then(|list| { + for meta in list { + if meta.check_name("include") { + // the actual compiled `#[doc(include="filename")]` gets expanded to + // `#[doc(include(file="filename", contents="file contents")]` so we need to + // look for that instead + return meta.meta_item_list().and_then(|list| { + let mut filename: Option<String> = None; + let mut contents: Option<String> = None; + + for it in list { + if it.check_name("file") { + if let Some(name) = it.value_str() { + filename = Some(name.to_string()); + } + } else if it.check_name("contents") { + if let Some(docs) = it.value_str() { + contents = Some(docs.to_string()); + } + } + } + + if let (Some(filename), Some(contents)) = (filename, contents) { + Some((filename, contents)) + } else { + None + } + }); + } + } + + None + }) + } + + pub fn has_doc_flag(&self, flag: &str) -> bool { for attr in &self.other_attrs { if !attr.check_name("doc") { continue; } if let Some(items) = attr.meta_item_list() { - if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name("masked")) { + if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) { return true; } } @@ -610,10 +717,12 @@ impl Attributes { false } - pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes { + pub fn from_ast(diagnostic: &::errors::Handler, + attrs: &[ast::Attribute]) -> Attributes { let mut doc_strings = vec![]; let mut sp = None; let mut cfg = Cfg::True; + let mut doc_line = 0; let other_attrs = attrs.iter().filter_map(|attr| { attr.with_desugared_doc(|attr| { @@ -621,7 +730,16 @@ impl Attributes { if let Some(mi) = attr.meta() { if let Some(value) = mi.value_str() { // Extracted #[doc = "..."] - doc_strings.push(value.to_string()); + let value = value.to_string(); + let line = doc_line; + doc_line += value.lines().count(); + + if attr.is_sugared_doc { + doc_strings.push(DocFragment::SugaredDoc(line, attr.span, value)); + } else { + doc_strings.push(DocFragment::RawDoc(line, attr.span, value)); + } + if sp.is_none() { sp = Some(attr.span); } @@ -633,6 +751,14 @@ impl Attributes { Err(e) => diagnostic.span_err(e.span, e.msg), } return None; + } else if let Some((filename, contents)) = Attributes::extract_include(&mi) + { + let line = doc_line; + doc_line += contents.lines().count(); + doc_strings.push(DocFragment::Include(line, + attr.span, + filename, + contents)); } } } @@ -650,7 +776,17 @@ impl Attributes { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. pub fn doc_value<'a>(&'a self) -> Option<&'a str> { - self.doc_strings.first().map(|s| &s[..]) + self.doc_strings.first().map(|s| s.as_str()) + } + + /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined + /// with newlines. + pub fn collapsed_doc_value(&self) -> Option<String> { + if !self.doc_strings.is_empty() { + Some(self.doc_strings.iter().collect()) + } else { + None + } } } @@ -872,8 +1008,8 @@ impl Clean<Lifetime> for hir::Lifetime { let hir_id = cx.tcx.hir.node_to_hir_id(self.id); let def = cx.tcx.named_region(hir_id); match def { - Some(rl::Region::EarlyBound(_, node_id)) | - Some(rl::Region::LateBound(_, node_id)) | + Some(rl::Region::EarlyBound(_, node_id, _)) | + Some(rl::Region::LateBound(_, node_id, _)) | Some(rl::Region::Free(_, node_id)) => { if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { return lt; @@ -1331,19 +1467,31 @@ impl Clean<FunctionRetTy> for hir::FunctionRetTy { } } +impl GetDefId for FunctionRetTy { + fn def_id(&self) -> Option<DefId> { + match *self { + Return(ref ty) => ty.def_id(), + DefaultReturn => None, + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Trait { pub unsafety: hir::Unsafety, pub items: Vec<Item>, pub generics: Generics, pub bounds: Vec<TyParamBound>, + pub is_spotlight: bool, } impl Clean<Item> for doctree::Trait { fn clean(&self, cx: &DocContext) -> Item { + let attrs = self.attrs.clean(cx); + let is_spotlight = attrs.has_doc_flag("spotlight"); Item { name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), + attrs: attrs, source: self.whence.clean(cx), def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), @@ -1354,6 +1502,7 @@ impl Clean<Item> for doctree::Trait { items: self.items.clean(cx), generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), + is_spotlight: is_spotlight, }), } } @@ -1960,9 +2109,8 @@ impl Clean<Type> for hir::Ty { } } TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)), - TyImplTraitExistential(ref bounds) | - TyImplTraitUniversal(_, ref bounds) => - ImplTrait(bounds.clean(cx)), + TyImplTraitExistential(ref exist_ty, ref _lts) => ImplTrait(exist_ty.bounds.clean(cx)), + TyImplTraitUniversal(_, ref bounds) => ImplTrait(bounds.clean(cx)), TyInfer | TyErr => Infer, TyTypeof(..) => panic!("Unimplemented type {:?}", self.node), } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e79a63fb8d8..cf557b1c661 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -36,6 +36,7 @@ pub use self::ExternalLocation::*; #[cfg(stage0)] use std::ascii::AsciiExt; +use std::borrow::Cow; use std::cell::RefCell; use std::cmp::Ordering; use std::collections::{BTreeMap, HashSet}; @@ -143,6 +144,23 @@ impl SharedContext { } } +impl SharedContext { + /// Returns whether the `collapse-docs` pass was run on this crate. + pub fn was_collapsed(&self) -> bool { + self.passes.contains("collapse-docs") + } + + /// Based on whether the `collapse-docs` pass was run, return either the `doc_value` or the + /// `collapsed_doc_value` of the given item. + pub fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<Cow<'a, str>> { + if self.was_collapsed() { + item.collapsed_doc_value().map(|s| s.into()) + } else { + item.doc_value().map(|s| s.into()) + } + } +} + /// Indicates where an external crate can be found. pub enum ExternalLocation { /// Remote URL root of the external crate @@ -1817,6 +1835,9 @@ fn plain_summary_line(s: Option<&str>) -> String { } fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result { + if let Some(ref name) = item.name { + info!("Documenting {}", name); + } document_stability(w, cx, item)?; let prefix = render_assoc_const_value(item); document_full(w, item, cx, &prefix)?; @@ -1893,8 +1914,9 @@ fn render_assoc_const_value(item: &clean::Item) -> String { fn document_full(w: &mut fmt::Formatter, item: &clean::Item, cx: &Context, prefix: &str) -> fmt::Result { - if let Some(s) = item.doc_value() { - render_markdown(w, s, item.source.clone(), cx.render_type, prefix, &cx.shared)?; + if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) { + debug!("Doc block: =====\n{}\n=====", s); + render_markdown(w, &*s, item.source.clone(), cx.render_type, prefix, &cx.shared)?; } else if !prefix.is_empty() { write!(w, "<div class='docblock'>{}</div>", prefix)?; } @@ -2268,7 +2290,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, AbiSpace(f.abi), it.name.as_ref().unwrap(), f.generics).len(); - write!(w, "<pre class='rust fn'>")?; + write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)?)?; render_attributes(w, it)?; write!(w, "{vis}{constness}{unsafety}{abi}fn \ {name}{generics}{decl}{where_clause}</pre>", @@ -2402,8 +2424,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let item_type = m.type_(); let id = derive_id(format!("{}.{}", item_type, name)); let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); - write!(w, "<h3 id='{id}' class='method'>\ + write!(w, "{extra}<h3 id='{id}' class='method'>\ <span id='{ns_id}' class='invisible'><code>", + extra = render_spotlight_traits(m)?, id = id, ns_id = ns_id)?; render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl)?; @@ -2605,10 +2628,10 @@ fn assoc_const(w: &mut fmt::Formatter, Ok(()) } -fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item, - bounds: &Vec<clean::TyParamBound>, - default: Option<&clean::Type>, - link: AssocItemLink) -> fmt::Result { +fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item, + bounds: &Vec<clean::TyParamBound>, + default: Option<&clean::Type>, + link: AssocItemLink) -> fmt::Result { write!(w, "type <a href='{}' class=\"type\">{}</a>", naive_assoc_href(it, link), it.name.as_ref().unwrap())?; @@ -3239,6 +3262,69 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { } } +fn render_spotlight_traits(item: &clean::Item) -> Result<String, fmt::Error> { + let mut out = String::new(); + + match item.inner { + clean::FunctionItem(clean::Function { ref decl, .. }) | + clean::TyMethodItem(clean::TyMethod { ref decl, .. }) | + clean::MethodItem(clean::Method { ref decl, .. }) | + clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => { + out = spotlight_decl(decl)?; + } + _ => {} + } + + Ok(out) +} + +fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> { + let mut out = String::new(); + let mut trait_ = String::new(); + + if let Some(did) = decl.output.def_id() { + let c = cache(); + if let Some(impls) = c.impls.get(&did) { + for i in impls { + let impl_ = i.inner_impl(); + if impl_.trait_.def_id().and_then(|d| c.traits.get(&d)) + .map_or(false, |t| t.is_spotlight) { + if out.is_empty() { + out.push_str( + &format!("<h3 class=\"important\">Important traits for {}</h3>\ + <code class=\"content\">", + impl_.for_)); + trait_.push_str(&format!("{}", impl_.for_)); + } + + //use the "where" class here to make it small + out.push_str(&format!("<span class=\"where fmt-newline\">{}</span>", impl_)); + let t_did = impl_.trait_.def_id().unwrap(); + for it in &impl_.items { + if let clean::TypedefItem(ref tydef, _) = it.inner { + out.push_str("<span class=\"where fmt-newline\"> "); + assoc_type(&mut out, it, &vec![], + Some(&tydef.type_), + AssocItemLink::GotoSource(t_did, &FxHashSet()))?; + out.push_str(";</span>"); + } + } + } + } + } + } + + if !out.is_empty() { + out.insert_str(0, &format!("<div class=\"important-traits\"><div class='tooltip'>ⓘ\ + <span class='tooltiptext'>Important traits for {}</span></div>\ + <div class=\"content hidden\">", + trait_)); + out.push_str("</code></div></div>"); + } + + Ok(out) +} + fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink, render_mode: RenderMode, outer_version: Option<&str>, show_def_docs: bool) -> fmt::Result { @@ -3262,8 +3348,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } write!(w, "</span>")?; write!(w, "</h3>\n")?; - if let Some(ref dox) = i.impl_item.doc_value() { - write!(w, "<div class='docblock'>{}</div>", Markdown(dox, cx.render_type))?; + if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { + write!(w, "<div class='docblock'>{}</div>", Markdown(&*dox, cx.render_type))?; } } @@ -3280,12 +3366,14 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi }; match item.inner { - clean::MethodItem(..) | clean::TyMethodItem(..) => { + clean::MethodItem(clean::Method { ref decl, .. }) | + clean::TyMethodItem(clean::TyMethod{ ref decl, .. }) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = derive_id(format!("{}.{}", item_type, name)); let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?; + write!(w, "{}", spotlight_decl(decl)?)?; write!(w, "<span id='{}' class='invisible'>", ns_id)?; write!(w, "<code>")?; render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?; @@ -3332,6 +3420,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi if render_method_item || render_mode == RenderMode::Normal { let prefix = render_assoc_const_value(item); + if !is_default_item { if let Some(t) = trait_ { // The trait item may have been stripped so we might not @@ -3613,18 +3702,24 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { } let mut links = HashSet::new(); let ret = v.iter() - .filter_map(|i| if let Some(ref i) = i.inner_impl().trait_ { - let i_display = format!("{:#}", i); - let out = Escape(&i_display); - let encoded = small_url_encode(&format!("{:#}", i)); - let generated = format!("<a href=\"#impl-{}\">{}</a>", encoded, out); - if !links.contains(&generated) && links.insert(generated.clone()) { - Some(generated) + .filter_map(|i| { + let is_negative_impl = is_negative_impl(i.inner_impl()); + if let Some(ref i) = i.inner_impl().trait_ { + let i_display = format!("{:#}", i); + let out = Escape(&i_display); + let encoded = small_url_encode(&format!("{:#}", i)); + let generated = format!("<a href=\"#impl-{}\">{}{}</a>", + encoded, + if is_negative_impl { "!" } else { "" }, + out); + if !links.contains(&generated) && links.insert(generated.clone()) { + Some(generated) + } else { + None + } } else { None } - } else { - None }) .collect::<String>(); if !ret.is_empty() { @@ -3671,6 +3766,10 @@ fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> { } } +fn is_negative_impl(i: &clean::Impl) -> bool { + i.polarity == Some(clean::ImplPolarity::Negative) +} + fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item, t: &clean::Trait) -> fmt::Result { let mut sidebar = String::new(); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index a3957ccdcb3..a47e89fb948 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -216,6 +216,7 @@ var help = document.getElementById("help"); switch (getVirtualKey(ev)) { case "Escape": + hideModal(); var search = document.getElementById("search"); if (!hasClass(help, "hidden")) { displayHelp(false, ev); @@ -229,6 +230,7 @@ case "s": case "S": displayHelp(false, ev); + hideModal(); ev.preventDefault(); focusSearchBar(); break; @@ -241,6 +243,7 @@ case "?": if (ev.shiftKey) { + hideModal(); displayHelp(true, ev); } break; @@ -374,11 +377,10 @@ results = {}, split = valLower.split("::"); - // remove empty keywords - for (var j = 0; j < split.length; ++j) { - split[j].toLowerCase(); - if (split[j] === "") { - split.splice(j, 1); + for (var z = 0; z < split.length; ++z) { + if (split[z] === "") { + split.splice(z, 1); + z -= 1; } } @@ -405,9 +407,7 @@ if (obj.generics && obj.generics.length >= val.generics.length) { var elems = obj.generics.slice(0); - for (var y = 0; - y < val.generics.length; - ++y) { + for (var y = 0; y < val.generics.length; ++y) { // The point here is to find the type that matches the most. var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; for (var x = 0; x < elems.length; ++x) { @@ -529,6 +529,49 @@ return literalSearch === true ? false : lev_distance; } + function checkPath(startsWith, lastElem, ty) { + var ret_lev = MAX_LEV_DISTANCE + 1; + var path = ty.path.split("::"); + + if (ty.parent && ty.parent.name) { + path.push(ty.parent.name.toLowerCase()); + } + + if (startsWith.length > path.length) { + return MAX_LEV_DISTANCE + 1; + } + for (var i = 0; i < path.length; ++i) { + if (i + startsWith.length > path.length) { + break; + } + var lev_total = 0; + var aborted = false; + for (var x = 0; x < startsWith.length; ++x) { + var lev = levenshtein(path[i + x], startsWith[x]); + if (lev > MAX_LEV_DISTANCE) { + aborted = true; + break; + } + lev_total += lev; + } + if (aborted === false) { + var extra = MAX_LEV_DISTANCE + 1; + if (i + startsWith.length < path.length) { + extra = levenshtein(path[i + startsWith.length], lastElem); + } + if (extra > MAX_LEV_DISTANCE) { + extra = levenshtein(ty.name, lastElem); + } + if (extra < MAX_LEV_DISTANCE + 1) { + lev_total += extra; + ret_lev = Math.min(ret_lev, + Math.round(lev_total / (startsWith.length + 1))); + } + } + } + return ret_lev; + } + function typePassesFilter(filter, type) { // No filter if (filter < 0) return true; @@ -665,86 +708,107 @@ query.search = val; // gather matching search results up to a certain maximum val = val.replace(/\_/g, ""); - var valGenerics = extractGenerics(val); + var results_length = 0; - for (var i = 0; i < split.length; ++i) { - for (var j = 0; j < nSearchWords; ++j) { - var lev_distance; - var ty = searchIndex[j]; - if (!ty) { + var valGenerics = extractGenerics(val); + + var paths = valLower.split("::"); + var j; + for (j = 0; j < paths.length; ++j) { + if (paths[j] === "") { + paths.splice(j, 1); + j -= 1; + } + } + val = paths[paths.length - 1]; + var startsWith = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); + + for (j = 0; j < nSearchWords; ++j) { + var lev_distance; + var ty = searchIndex[j]; + if (!ty) { + continue; + } + var lev_add = 0; + if (paths.length > 1) { + var lev = checkPath(startsWith, paths[paths.length - 1], ty); + if (lev > MAX_LEV_DISTANCE) { continue; + } else if (lev > 0) { + lev_add = 1; } - var returned = false; - var in_args = false; - var index = -1; - // we want lev results to go lower than others - var lev = MAX_LEV_DISTANCE; - var fullId = itemTypes[ty.ty] + ty.path + ty.name; - - if (searchWords[j].indexOf(split[i]) > -1 || - searchWords[j].indexOf(val) > -1 || - searchWords[j].replace(/_/g, "").indexOf(val) > -1) - { - // filter type: ... queries - if (typePassesFilter(typeFilter, ty) && - results[fullId] === undefined) { - index = searchWords[j].replace(/_/g, "").indexOf(val); - } + } + + var returned = false; + var in_args = false; + var index = -1; + // we want lev results to go lower than others + var lev = MAX_LEV_DISTANCE + 1; + var fullId = itemTypes[ty.ty] + ty.path + ty.name; + + if (searchWords[j].indexOf(val) > -1 || + searchWords[j].replace(/_/g, "").indexOf(val) > -1) + { + // filter type: ... queries + if (typePassesFilter(typeFilter, ty) && + results[fullId] === undefined) { + index = searchWords[j].replace(/_/g, "").indexOf(val); } - if ((lev_distance = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { - if (typePassesFilter(typeFilter, ty) && - (results[fullId] === undefined || - results[fullId].lev > lev_distance)) { - lev = Math.min(lev, lev_distance); - index = Math.max(0, index); - } + } + if ((lev_distance = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { + if (typePassesFilter(typeFilter, ty) && + (results[fullId] === undefined || + results[fullId].lev > lev_distance)) { + lev = Math.min(lev, lev_distance); + index = Math.max(0, index); } - if ((lev_distance = findArg(searchIndex[j], valGenerics)) - <= MAX_LEV_DISTANCE) { - if (typePassesFilter(typeFilter, ty) && - (results[fullId] === undefined || - results[fullId].lev > lev_distance)) { - in_args = true; - lev = Math.min(lev_distance, lev); - index = Math.max(0, index); - } + } + if ((lev_distance = findArg(searchIndex[j], valGenerics)) + <= MAX_LEV_DISTANCE) { + if (typePassesFilter(typeFilter, ty) && + (results[fullId] === undefined || + results[fullId].lev > lev_distance)) { + in_args = true; + lev = Math.min(lev_distance, lev); + index = Math.max(0, index); } - if ((lev_distance = checkReturned(searchIndex[j], valGenerics)) <= - MAX_LEV_DISTANCE) { - if (typePassesFilter(typeFilter, ty) && - (results[fullId] === undefined || - results[fullId].lev > lev_distance)) { - returned = true; - lev = Math.min(lev_distance, lev); - index = Math.max(0, index); - } + } + if ((lev_distance = checkReturned(searchIndex[j], valGenerics)) <= + MAX_LEV_DISTANCE) { + if (typePassesFilter(typeFilter, ty) && + (results[fullId] === undefined || + results[fullId].lev > lev_distance)) { + returned = true; + lev = Math.min(lev_distance, lev); + index = Math.max(0, index); } - if (index !== -1) { - if (results[fullId] === undefined) { - results[fullId] = { - id: j, - index: index, - lev: lev, - in_args: in_args, - returned: returned, - }; - results_length += 1; - } else { - if (results[fullId].lev > lev) { - results[fullId].lev = lev; - } - if (in_args === true) { - results[fullId].in_args = true; - } - if (returned === true) { - results[fullId].returned = true; - } + } + lev += lev_add; + if (index !== -1) { + if (results[fullId] === undefined) { + results[fullId] = { + id: j, + index: index, + lev: lev, + in_args: in_args, + returned: returned, + }; + results_length += 1; + } else { + if (results[fullId].lev > lev) { + results[fullId].lev = lev; + } + if (in_args === true) { + results[fullId].in_args = true; + } + if (returned === true) { + results[fullId].returned = true; } - } - if (results_length === max) { - break; } } + if (results_length === max) { + break; + } } } @@ -834,16 +898,14 @@ var result = results[i]; // this validation does not make sense when searching by types - if (result.dontValidate) { + if (result.dontValidate || result.returned === true && result.param === true) { continue; } var name = result.item.name.toLowerCase(), path = result.item.path.toLowerCase(), parent = result.item.parent; - if (result.returned === false && result.param === false && - validateResult(name, path, split, parent) === false) - { + if (validateResult(name, path, split, parent) === false) { result.id = -1; } } @@ -1713,6 +1775,31 @@ } }); + function showModal(content) { + var modal = document.createElement('div'); + modal.id = "important"; + addClass(modal, 'modal'); + modal.innerHTML = '<div class="modal-content"><div class="close" id="modal-close">✕</div>' + + '<div class="whiter"></div><span class="docblock">' + content + + '</span></div>'; + document.getElementsByTagName('body')[0].appendChild(modal); + document.getElementById('modal-close').onclick = hideModal; + modal.onclick = hideModal; + } + + function hideModal() { + var modal = document.getElementById("important"); + if (modal) { + modal.parentNode.removeChild(modal); + } + } + + onEach(document.getElementsByClassName('important-traits'), function(e) { + e.onclick = function() { + showModal(e.lastElementChild.innerHTML); + }; + }); + var search_input = document.getElementsByClassName("search-input")[0]; if (search_input) { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 55acc575152..d7f4674908c 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -89,7 +89,7 @@ h2 { h3 { font-size: 1.3em; } -h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { font-weight: 500; margin: 20px 0 15px 0; padding-bottom: 6px; @@ -141,9 +141,12 @@ code, pre { border-radius: 3px; padding: 0 0.2em; } -.docblock pre code, .docblock-short pre code { +.docblock pre code, .docblock-short pre code, .docblock code.spotlight { padding: 0; } +.docblock code.spotlight :last-child { + padding-bottom: 0.6em; +} pre { padding: 14px; } @@ -435,10 +438,11 @@ h4 > code, h3 > code, .invisible > code { font-size: 0.8em; } -.content .methods > div { margin-left: 40px; } +.content .methods > div:not(.important-traits) { margin-left: 40px; } .content .impl-items .docblock, .content .impl-items .stability { margin-left: 40px; + margin-bottom: .6em; } .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { margin-left: 20px; @@ -951,3 +955,102 @@ pre.rust { color: #888; font-size: 16px; } + +.important-traits { + cursor: pointer; + z-index: 2; +} + +h4 > .important-traits { + position: absolute; + left: -44px; + top: 2px; +} + +.modal { + position: fixed; + width: 100vw; + height: 100vh; + background-color: rgba(0,0,0,0.3); + z-index: 10000; + top: 0; + left: 0; +} + +.modal-content { + display: block; + max-width: 60%; + min-width: 200px; + background-color: #eee; + padding: 8px; + top: 40%; + position: absolute; + left: 50%; + transform: translate(-50%, -40%); + border: 1px solid #999; + border-radius: 4px; + border-top-right-radius: 0; +} + +.modal-content > .docblock { + margin: 0; +} + +h3.important { + margin: 0; + margin-bottom: 13px; + font-size: 19px; +} + +.modal-content > .docblock > code.content { + margin: 0; + padding: 0; + font-size: 20px; +} + +.modal-content > .close { + position: absolute; + font-weight: 900; + right: -25px; + top: -1px; + font-size: 18px; + background-color: #eee; + width: 25px; + padding-right: 2px; + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + text-align: center; + border: 1px solid #999; + border-right: 0; + cursor: pointer; +} + +.modal-content > .close:hover { + background-color: #ff1f1f; + color: white; +} + +.modal-content > .whiter { + height: 25px; + position: absolute; + width: 3px; + background-color: #eee; + right: -2px; + top: 0px; +} + +.modal-content > .close:hover + .whiter { + background-color: #ff1f1f; +} + +#main > div.important-traits { + position: absolute; + left: -24px; + margin-top: 16px; +} + +.content > .methods > div.important-traits { + position: absolute; + left: -42px; + margin-top: 2px; +} \ No newline at end of file diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index 3c63302127c..a2d651d29de 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -8,10 +8,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use clean::{self, Item}; +use clean::{self, DocFragment, Item}; use plugins; use fold; use fold::DocFolder; +use std::mem::replace; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum DocFragmentKind { + Sugared, + Raw, + Include, +} + +impl DocFragment { + fn kind(&self) -> DocFragmentKind { + match *self { + DocFragment::SugaredDoc(..) => DocFragmentKind::Sugared, + DocFragment::RawDoc(..) => DocFragmentKind::Raw, + DocFragment::Include(..) => DocFragmentKind::Include, + } + } +} pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult { Collapser.fold_crate(krate) @@ -26,15 +44,51 @@ impl fold::DocFolder for Collapser { } } -impl clean::Attributes { - pub fn collapse_doc_comments(&mut self) { - let mut doc_string = self.doc_strings.join("\n"); - if doc_string.is_empty() { - self.doc_strings = vec![]; +fn collapse(doc_strings: &mut Vec<DocFragment>) { + let mut docs = vec![]; + let mut last_frag: Option<DocFragment> = None; + + for frag in replace(doc_strings, vec![]) { + if let Some(mut curr_frag) = last_frag.take() { + let curr_kind = curr_frag.kind(); + let new_kind = frag.kind(); + + if curr_kind == DocFragmentKind::Include || curr_kind != new_kind { + match curr_frag { + DocFragment::SugaredDoc(_, _, ref mut doc_string) + | DocFragment::RawDoc(_, _, ref mut doc_string) => { + // add a newline for extra padding between segments + doc_string.push('\n'); + } + _ => {} + } + docs.push(curr_frag); + last_frag = Some(frag); + } else { + match curr_frag { + DocFragment::SugaredDoc(_, ref mut span, ref mut doc_string) + | DocFragment::RawDoc(_, ref mut span, ref mut doc_string) => { + doc_string.push('\n'); + doc_string.push_str(frag.as_str()); + *span = span.to(frag.span()); + } + _ => unreachable!(), + } + last_frag = Some(curr_frag); + } } else { - // FIXME(eddyb) Is this still needed? - doc_string.push('\n'); - self.doc_strings = vec![doc_string]; + last_frag = Some(frag); } } + + if let Some(frag) = last_frag.take() { + docs.push(frag); + } + *doc_strings = docs; +} + +impl clean::Attributes { + pub fn collapse_doc_comments(&mut self) { + collapse(&mut self.doc_strings); + } } diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 59fef8d2027..912c7646a06 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -12,7 +12,7 @@ use std::cmp; use std::string::String; use std::usize; -use clean::{self, Item}; +use clean::{self, DocFragment, Item}; use plugins; use fold::{self, DocFolder}; @@ -31,8 +31,17 @@ impl fold::DocFolder for CommentCleaner { impl clean::Attributes { pub fn unindent_doc_comments(&mut self) { - for doc_string in &mut self.doc_strings { - *doc_string = unindent(doc_string); + unindent_fragments(&mut self.doc_strings); + } +} + +fn unindent_fragments(docs: &mut Vec<DocFragment>) { + for fragment in docs { + match *fragment { + DocFragment::SugaredDoc(_, _, ref mut doc_string) | + DocFragment::RawDoc(_, _, ref mut doc_string) | + DocFragment::Include(_, _, _, ref mut doc_string) => + *doc_string = unindent(doc_string), } } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9bbd16355be..3aa674415f0 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -81,7 +81,9 @@ pub fn run(input: &str, let codemap = Rc::new(CodeMap::new(sessopts.file_path_mapping())); let handler = - errors::Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(codemap.clone())); + errors::Handler::with_tty_emitter(ColorConfig::Auto, + true, false, + Some(codemap.clone())); let cstore = Rc::new(CStore::new(box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( @@ -661,14 +663,16 @@ impl<'a, 'hir> HirCollector<'a, 'hir> { attrs.collapse_doc_comments(); attrs.unindent_doc_comments(); - if let Some(doc) = attrs.doc_value() { + // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with + // anything else, this will combine them for us + if let Some(doc) = attrs.collapsed_doc_value() { if self.collector.render_type == RenderType::Pulldown { - markdown::old_find_testable_code(doc, self.collector, + markdown::old_find_testable_code(&doc, self.collector, attrs.span.unwrap_or(DUMMY_SP)); - markdown::find_testable_code(doc, self.collector, + markdown::find_testable_code(&doc, self.collector, attrs.span.unwrap_or(DUMMY_SP)); } else { - markdown::old_find_testable_code(doc, self.collector, + markdown::old_find_testable_code(&doc, self.collector, attrs.span.unwrap_or(DUMMY_SP)); } } diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 14f0edc3690..e5b1394f070 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -9,8 +9,9 @@ // except according to those terms. //! This module provides constants which are specific to the implementation -//! of the `f32` floating point data type. Mathematically significant -//! numbers are provided in the `consts` sub-module. +//! of the `f32` floating point data type. +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. //! //! *[See also the `f32` primitive type](../primitive.f32.html).* @@ -997,10 +998,13 @@ impl f32 { /// Raw transmutation to `u32`. /// - /// Converts the `f32` into its raw memory representation, - /// similar to the `transmute` function. + /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms. + /// + /// See `from_bits` for some discussion of the portability of this operation + /// (there are almost no issues). /// - /// Note that this function is distinct from casting. + /// Note that this function is distinct from `as` casting, which attempts to + /// preserve the *numeric* value, and not the bitwise value. /// /// # Examples /// @@ -1017,17 +1021,33 @@ impl f32 { /// Raw transmutation from `u32`. /// - /// Converts the given `u32` containing the float's raw memory - /// representation into the `f32` type, similar to the - /// `transmute` function. + /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms. + /// It turns out this is incredibly portable, for two reasons: + /// + /// * Floats and Ints have the same endianess on all supported platforms. + /// * IEEE-754 very precisely specifies the bit layout of floats. + /// + /// However there is one caveat: prior to the 2008 version of IEEE-754, how + /// to interpret the NaN signaling bit wasn't actually specified. Most platforms + /// (notably x86 and ARM) picked the interpretation that was ultimately + /// standardized in 2008, but some didn't (notably MIPS). As a result, all + /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa. + /// + /// Rather than trying to preserve signaling-ness cross-platform, this + /// implementation favours preserving the exact bits. This means that + /// any payloads encoded in NaNs will be preserved even if the result of + /// this method is sent over the network from an x86 machine to a MIPS one. + /// + /// If the results of this method are only manipulated by the same + /// architecture that produced them, then there is no portability concern. /// - /// There is only one difference to a bare `transmute`: - /// Due to the implications onto Rust's safety promises being - /// uncertain, if the representation of a signaling NaN "sNaN" float - /// is passed to the function, the implementation is allowed to - /// return a quiet NaN instead. + /// If the input isn't NaN, then there is no portability concern. /// - /// Note that this function is distinct from casting. + /// If you don't care about signalingness (very likely), then there is no + /// portability concern. + /// + /// Note that this function is distinct from `as` casting, which attempts to + /// preserve the *numeric* value, and not the bitwise value. /// /// # Examples /// @@ -1036,25 +1056,11 @@ impl f32 { /// let v = f32::from_bits(0x41480000); /// let difference = (v - 12.5).abs(); /// assert!(difference <= 1e-5); - /// // Example for a signaling NaN value: - /// let snan = 0x7F800001; - /// assert_ne!(f32::from_bits(snan).to_bits(), snan); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] #[inline] - pub fn from_bits(mut v: u32) -> Self { - const EXP_MASK: u32 = 0x7F800000; - const FRACT_MASK: u32 = 0x007FFFFF; - if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 { - // While IEEE 754-2008 specifies encodings for quiet NaNs - // and signaling ones, certain MIPS and PA-RISC - // CPUs treat signaling NaNs differently. - // Therefore to be safe, we pass a known quiet NaN - // if v is any kind of NaN. - // The check above only assumes IEEE 754-1985 to be - // valid. - v = unsafe { ::mem::transmute(NAN) }; - } + pub fn from_bits(v: u32) -> Self { + // It turns out the safety issues with sNaN were overblown! Hooray! unsafe { ::mem::transmute(v) } } } @@ -1645,25 +1651,15 @@ mod tests { assert_approx_eq!(f32::from_bits(0x41480000), 12.5); assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0); assert_approx_eq!(f32::from_bits(0xc1640000), -14.25); - } - #[test] - fn test_snan_masking() { - // NOTE: this test assumes that our current platform - // implements IEEE 754-2008 that specifies the difference - // in encoding of quiet and signaling NaNs. - // If you are porting Rust to a platform that does not - // implement IEEE 754-2008 (but e.g. IEEE 754-1985, which - // only says that "Signaling NaNs shall be reserved operands" - // but doesn't specify the actual setup), feel free to - // cfg out this test. - let snan: u32 = 0x7F801337; - const QNAN_MASK: u32 = 0x00400000; - let nan_masked_fl = f32::from_bits(snan); - let nan_masked = nan_masked_fl.to_bits(); - // Ensure that signaling NaNs don't stay the same - assert_ne!(nan_masked, snan); - // Ensure that we have a quiet NaN - assert_ne!(nan_masked & QNAN_MASK, 0); - assert!(nan_masked_fl.is_nan()); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA; + let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555; + assert!(f32::from_bits(masked_nan1).is_nan()); + assert!(f32::from_bits(masked_nan2).is_nan()); + + assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1); + assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2); } } diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index e0f0acc6ac4..f4d804fd508 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -9,8 +9,9 @@ // except according to those terms. //! This module provides constants which are specific to the implementation -//! of the `f64` floating point data type. Mathematically significant -//! numbers are provided in the `consts` sub-module. +//! of the `f64` floating point data type. +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. //! //! *[See also the `f64` primitive type](../primitive.f64.html).* @@ -952,10 +953,13 @@ impl f64 { /// Raw transmutation to `u64`. /// - /// Converts the `f64` into its raw memory representation, - /// similar to the `transmute` function. + /// This is currently identical to `transmute::<f64, u64>(self)` on all platforms. + /// + /// See `from_bits` for some discussion of the portability of this operation + /// (there are almost no issues). /// - /// Note that this function is distinct from casting. + /// Note that this function is distinct from `as` casting, which attempts to + /// preserve the *numeric* value, and not the bitwise value. /// /// # Examples /// @@ -972,17 +976,33 @@ impl f64 { /// Raw transmutation from `u64`. /// - /// Converts the given `u64` containing the float's raw memory - /// representation into the `f64` type, similar to the - /// `transmute` function. + /// This is currently identical to `transmute::<u64, f64>(v)` on all platforms. + /// It turns out this is incredibly portable, for two reasons: + /// + /// * Floats and Ints have the same endianess on all supported platforms. + /// * IEEE-754 very precisely specifies the bit layout of floats. + /// + /// However there is one caveat: prior to the 2008 version of IEEE-754, how + /// to interpret the NaN signaling bit wasn't actually specified. Most platforms + /// (notably x86 and ARM) picked the interpretation that was ultimately + /// standardized in 2008, but some didn't (notably MIPS). As a result, all + /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa. + /// + /// Rather than trying to preserve signaling-ness cross-platform, this + /// implementation favours preserving the exact bits. This means that + /// any payloads encoded in NaNs will be preserved even if the result of + /// this method is sent over the network from an x86 machine to a MIPS one. /// - /// There is only one difference to a bare `transmute`: - /// Due to the implications onto Rust's safety promises being - /// uncertain, if the representation of a signaling NaN "sNaN" float - /// is passed to the function, the implementation is allowed to - /// return a quiet NaN instead. + /// If the results of this method are only manipulated by the same + /// architecture that produced them, then there is no portability concern. /// - /// Note that this function is distinct from casting. + /// If the input isn't NaN, then there is no portability concern. + /// + /// If you don't care about signalingness (very likely), then there is no + /// portability concern. + /// + /// Note that this function is distinct from `as` casting, which attempts to + /// preserve the *numeric* value, and not the bitwise value. /// /// # Examples /// @@ -991,25 +1011,11 @@ impl f64 { /// let v = f64::from_bits(0x4029000000000000); /// let difference = (v - 12.5).abs(); /// assert!(difference <= 1e-5); - /// // Example for a signaling NaN value: - /// let snan = 0x7FF0000000000001; - /// assert_ne!(f64::from_bits(snan).to_bits(), snan); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] #[inline] - pub fn from_bits(mut v: u64) -> Self { - const EXP_MASK: u64 = 0x7FF0000000000000; - const FRACT_MASK: u64 = 0x000FFFFFFFFFFFFF; - if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 { - // While IEEE 754-2008 specifies encodings for quiet NaNs - // and signaling ones, certain MIPS and PA-RISC - // CPUs treat signaling NaNs differently. - // Therefore to be safe, we pass a known quiet NaN - // if v is any kind of NaN. - // The check above only assumes IEEE 754-1985 to be - // valid. - v = unsafe { ::mem::transmute(NAN) }; - } + pub fn from_bits(v: u64) -> Self { + // It turns out the safety issues with sNaN were overblown! Hooray! unsafe { ::mem::transmute(v) } } } @@ -1596,5 +1602,15 @@ mod tests { assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5); assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0); assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + assert!(f64::from_bits(masked_nan1).is_nan()); + assert!(f64::from_bits(masked_nan2).is_nan()); + + assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1); + assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2); } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 57f8c39756e..54ee8880ec3 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -366,16 +366,13 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize> fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> { let start_len = buf.len(); let mut g = Guard { len: buf.len(), buf: buf }; - let mut new_write_size = 16; let ret; loop { if g.len == g.buf.len() { - if new_write_size < DEFAULT_BUF_SIZE { - new_write_size *= 2; - } unsafe { - g.buf.reserve(new_write_size); - g.buf.set_len(g.len + new_write_size); + g.buf.reserve(32); + let capacity = g.buf.capacity(); + g.buf.set_len(capacity); r.initializer().initialize(&mut g.buf[g.len..]); } } @@ -419,14 +416,8 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> /// /// [`File`]s implement `Read`: /// -/// [`read()`]: trait.Read.html#tymethod.read -/// [`std::io`]: ../../std/io/index.html -/// [`File`]: ../fs/struct.File.html -/// [`BufRead`]: trait.BufRead.html -/// [`BufReader`]: struct.BufReader.html -/// /// ``` -/// use std::io; +/// # use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// @@ -449,7 +440,34 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> /// # Ok(()) /// # } /// ``` +/// +/// Read from `&str` because [`&[u8]`] implements [`Read`]: +/// +/// ``` +/// # use std::io; +/// use std::io::prelude::*; +/// +/// # fn foo() -> io::Result<()> { +/// let mut b = "This string will be read".as_bytes(); +/// let mut buffer = [0; 10]; +/// +/// // read up to 10 bytes +/// b.read(&mut buffer)?; +/// +/// // etc... it works exactly as a File does! +/// # Ok(()) +/// # } +/// ``` +/// +/// [`read()`]: trait.Read.html#tymethod.read +/// [`std::io`]: ../../std/io/index.html +/// [`File`]: ../fs/struct.File.html +/// [`BufRead`]: trait.BufRead.html +/// [`BufReader`]: struct.BufReader.html +/// [`&[u8]`]: primitive.slice.html +/// #[stable(feature = "rust1", since = "1.0.0")] +#[doc(spotlight)] pub trait Read { /// Pull some bytes from this source into the specified buffer, returning /// how many bytes were read. @@ -968,6 +986,7 @@ impl Initializer { /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[doc(spotlight)] pub trait Write { /// Write a buffer into this object, returning how many bytes were written. /// diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 37cc7a49b52..9587bb424bd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -329,8 +329,10 @@ #![feature(vec_push_all)] #![feature(doc_cfg)] #![feature(doc_masked)] +#![feature(doc_spotlight)] #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(const_atomic_ptr_new))] +#![cfg_attr(windows, feature(used))] #![default_lib_allocator] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index e1d7a2531b6..1ca7e66ed9c 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -759,7 +759,7 @@ impl hash::Hash for SocketAddrV6 { /// ``` /// /// [`TcpStream::connect`] is an example of an function that utilizes -/// `ToSocketsAddr` as a trait bound on its parameter in order to accept +/// `ToSocketAddrs` as a trait bound on its parameter in order to accept /// different types: /// /// ```no_run diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 385076e50dd..219e55d6c12 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Panic support in the standard library +//! Panic support in the standard library. #![stable(feature = "std_panic", since = "1.9.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 69922470cff..4e35cf840de 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -3752,7 +3752,7 @@ mod tests { } #[test] - fn test_eq_recievers() { + fn test_eq_receivers() { use borrow::Cow; let borrowed: &Path = Path::new("foo/bar"); diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 35c33f40253..2335695ae42 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -712,8 +712,10 @@ impl Command { /// Executes the command as a child process, waiting for it to finish and /// collecting all of its output. /// - /// By default, stdin, stdout and stderr are captured (and used to - /// provide the resulting output). + /// By default, stdout and stderr are captured (and used to provide the + /// resulting output). Stdin is not inherited from the parent and any + /// attempt by the child process to read from the stdin stream will result + /// in the stream immediately closing. /// /// # Examples /// diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index eb507858b92..81f5594bc52 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -382,6 +382,17 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex<T> { } } +#[stable(feature = "mutex_from", since = "1.22.0")] +impl<T> From<T> for Mutex<T> { + /// Creates a new mutex in an unlocked state ready for use. + /// This is equivalent to [`Mutex::new`]. + /// + /// [`Mutex::new`]: #method.new + fn from(t: T) -> Self { + Mutex::new(t) + } +} + #[stable(feature = "mutex_default", since = "1.10.0")] impl<T: ?Sized + Default> Default for Mutex<T> { /// Creates a `Mutex<T>`, with the `Default` value for T. diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 6216d78528d..fd6cff6b69c 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -457,6 +457,17 @@ impl<T: Default> Default for RwLock<T> { } } +#[stable(feature = "rw_lock_from", since = "1.22.0")] +impl<T> From<T> for RwLock<T> { + /// Creates a new instance of an `RwLock<T>` which is unlocked. + /// This is equivalent to [`RwLock::new`]. + /// + /// [`RwLock::new`]: #method.new + fn from(t: T) -> Self { + RwLock::new(t) + } +} + impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> { diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/redox/os.rs index c27e2ee172c..480765b77a0 100644 --- a/src/libstd/sys/redox/os.rs +++ b/src/libstd/sys/redox/os.rs @@ -213,3 +213,7 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { syscall::getpid().unwrap() as u32 } + +pub fn getppid() -> u32 { + syscall::getppid().unwrap() as u32 +} diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index cde21b089a2..60309bec6d4 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -191,3 +191,9 @@ impl IntoRawFd for process::ChildStderr { self.into_inner().into_fd().into_raw() } } + +/// Returns the OS-assigned process identifier associated with this process's parent. +#[unstable(feature = "unix_ppid", issue = "46104")] +pub fn parent_id() -> u32 { + ::sys::os::getppid() +} diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 40b73f1b307..7e965b4b4c5 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -515,3 +515,7 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { unsafe { libc::getpid() as u32 } } + +pub fn getppid() -> u32 { + unsafe { libc::getppid() as u32 } +} diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index 7ae9ed917bd..cdad320e122 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -200,8 +200,9 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) { // the address of the symbol to ensure it sticks around. #[link_section = ".CRT$XLB"] -#[linkage = "external"] #[allow(dead_code, unused_variables)] +#[used] // we don't want LLVM eliminating this symbol for any reason, and + // when the symbol makes it to the linker the linker will take over pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) = on_tls_callback; diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index e20937c6c7b..0faf5bd9121 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -57,6 +57,7 @@ pub use tables::{UnicodeVersion, UNICODE_VERSION}; /// [`to_lowercase`]: ../../std/primitive.char.html#method.to_lowercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug)] pub struct ToLowercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -78,6 +79,7 @@ impl FusedIterator for ToLowercase {} /// [`to_uppercase`]: ../../std/primitive.char.html#method.to_uppercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug)] pub struct ToUppercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -91,6 +93,7 @@ impl Iterator for ToUppercase { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for ToUppercase {} +#[derive(Debug)] enum CaseMappingIter { Three(char, char, char), Two(char, char), @@ -1450,7 +1453,7 @@ impl char { /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. #[stable(feature = "decode_utf16", since = "1.9.0")] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct DecodeUtf16<I> where I: Iterator<Item = u16> { diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index 65058b6554a..22f8bdab2f7 100644 --- a/src/libstd_unicode/lib.rs +++ b/src/libstd_unicode/lib.rs @@ -28,6 +28,7 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] #![deny(warnings)] +#![deny(missing_debug_implementations)] #![no_std] #![feature(ascii_ctype)] diff --git a/src/libstd_unicode/lossy.rs b/src/libstd_unicode/lossy.rs index 253dcb6a159..cc8e93308a5 100644 --- a/src/libstd_unicode/lossy.rs +++ b/src/libstd_unicode/lossy.rs @@ -38,6 +38,7 @@ impl Utf8Lossy { /// Iterator over lossy UTF-8 string #[unstable(feature = "str_internals", issue = "0")] +#[allow(missing_debug_implementations)] pub struct Utf8LossyChunksIter<'a> { source: &'a [u8], } diff --git a/src/libstd_unicode/u_str.rs b/src/libstd_unicode/u_str.rs index 0046e3f7bd0..5d1611acb7e 100644 --- a/src/libstd_unicode/u_str.rs +++ b/src/libstd_unicode/u_str.rs @@ -76,6 +76,7 @@ impl UnicodeStr for str { /// Iterator adaptor for encoding `char`s to UTF-16. #[derive(Clone)] +#[allow(missing_debug_implementations)] pub struct Utf16Encoder<I> { chars: I, extra: u16, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 99dff4edaad..ad9d5865120 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -96,10 +96,15 @@ impl Path { } } + // Add starting "crate root" segment to all paths except those that + // already have it or start with `self`, `super`, `Self` or `$crate`. pub fn default_to_global(mut self) -> Path { - if !self.is_global() && - !::parse::token::Ident(self.segments[0].identifier).is_path_segment_keyword() { - self.segments.insert(0, PathSegment::crate_root(self.span)); + if !self.is_global() { + let ident = self.segments[0].identifier; + if !::parse::token::Ident(ident).is_path_segment_keyword() || + ident.name == keywords::Crate.name() { + self.segments.insert(0, PathSegment::crate_root(self.span)); + } } self } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index b1f796084df..8bd7399092f 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -371,11 +371,13 @@ impl Attribute { let meta = mk_name_value_item_str( Symbol::intern("doc"), Symbol::intern(&strip_doc_comment_decoration(&comment.as_str()))); - if self.style == ast::AttrStyle::Outer { - f(&mk_attr_outer(self.span, self.id, meta)) + let mut attr = if self.style == ast::AttrStyle::Outer { + mk_attr_outer(self.span, self.id, meta) } else { - f(&mk_attr_inner(self.span, self.id, meta)) - } + mk_attr_inner(self.span, self.id, meta) + }; + attr.is_sugared_doc = true; + f(&attr) } else { f(self) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0e05cce35e2..6c96692f719 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -665,6 +665,7 @@ pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub ecfg: expand::ExpansionConfig<'a>, pub crate_root: Option<&'static str>, + pub root_path: PathBuf, pub resolver: &'a mut Resolver, pub resolve_err_count: usize, pub current_expansion: ExpansionData, @@ -680,6 +681,7 @@ impl<'a> ExtCtxt<'a> { parse_sess, ecfg, crate_root: None, + root_path: PathBuf::new(), resolver, resolve_err_count: 0, current_expansion: ExpansionData { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 491dbed01f1..0d1b1c65a29 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -11,7 +11,7 @@ use ast::{self, Block, Ident, NodeId, PatKind, Path}; use ast::{MacStmtStyle, StmtKind, ItemKind}; use attr::{self, HasAttrs}; -use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; +use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, dummy_spanned}; use config::{is_test_or_bench, StripUnconfigured}; use errors::FatalError; use ext::base::*; @@ -35,6 +35,8 @@ use util::small_vector::SmallVector; use visit::Visitor; use std::collections::HashMap; +use std::fs::File; +use std::io::Read; use std::mem; use std::rc::Rc; @@ -223,6 +225,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { directory: self.cx.codemap().span_to_unmapped_path(krate.span), }; module.directory.pop(); + self.cx.root_path = module.directory.clone(); self.cx.current_expansion.module = Rc::new(module); let orig_mod_span = krate.module.inner; @@ -843,6 +846,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { feature_gate::check_attribute(attr, self.cx.parse_sess, features); } } + + fn check_attribute(&mut self, at: &ast::Attribute) { + let features = self.cx.ecfg.features.unwrap(); + feature_gate::check_attribute(at, self.cx.parse_sess, features); + } } pub fn find_attr_invoc(attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> { @@ -1063,6 +1071,84 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } } + fn fold_attribute(&mut self, at: ast::Attribute) -> Option<ast::Attribute> { + // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename", + // contents="file contents")]` attributes + if !at.check_name("doc") { + return noop_fold_attribute(at, self); + } + + if let Some(list) = at.meta_item_list() { + if !list.iter().any(|it| it.check_name("include")) { + return noop_fold_attribute(at, self); + } + + let mut items = vec![]; + + for it in list { + if !it.check_name("include") { + items.push(noop_fold_meta_list_item(it, self)); + continue; + } + + if let Some(file) = it.value_str() { + let err_count = self.cx.parse_sess.span_diagnostic.err_count(); + self.check_attribute(&at); + if self.cx.parse_sess.span_diagnostic.err_count() > err_count { + // avoid loading the file if they haven't enabled the feature + return noop_fold_attribute(at, self); + } + + let mut buf = vec![]; + let filename = self.cx.root_path.join(file.to_string()); + + match File::open(&filename).and_then(|mut f| f.read_to_end(&mut buf)) { + Ok(..) => {} + Err(e) => { + self.cx.span_warn(at.span, + &format!("couldn't read {}: {}", + filename.display(), + e)); + } + } + + match String::from_utf8(buf) { + Ok(src) => { + let include_info = vec![ + dummy_spanned(ast::NestedMetaItemKind::MetaItem( + attr::mk_name_value_item_str("file".into(), + file))), + dummy_spanned(ast::NestedMetaItemKind::MetaItem( + attr::mk_name_value_item_str("contents".into(), + (&*src).into()))), + ]; + + items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem( + attr::mk_list_item("include".into(), include_info)))); + } + Err(_) => { + self.cx.span_warn(at.span, + &format!("{} wasn't a utf-8 file", + filename.display())); + } + } + } else { + items.push(noop_fold_meta_list_item(it, self)); + } + } + + let meta = attr::mk_list_item("doc".into(), items); + match at.style { + ast::AttrStyle::Inner => + Some(attr::mk_spanned_attr_inner(at.span, at.id, meta)), + ast::AttrStyle::Outer => + Some(attr::mk_spanned_attr_outer(at.span, at.id, meta)), + } + } else { + noop_fold_attribute(at, self) + } + } + fn new_id(&mut self, id: ast::NodeId) -> ast::NodeId { if self.monotonic { assert_eq!(id, ast::DUMMY_NODE_ID); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ebe7853b8ab..89d1a3699e8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -33,7 +33,7 @@ use syntax_pos::Span; use errors::{DiagnosticBuilder, Handler, FatalError}; use visit::{self, FnKind, Visitor}; use parse::ParseSess; -use symbol::Symbol; +use symbol::{keywords, Symbol}; use std::env; @@ -381,6 +381,10 @@ declare_features! ( (active, doc_cfg, "1.21.0", Some(43781)), // #[doc(masked)] (active, doc_masked, "1.21.0", Some(44027)), + // #[doc(spotlight)] + (active, doc_spotlight, "1.22.0", Some(45040)), + // #[doc(include="some-file")] + (active, external_doc, "1.22.0", Some(44732)), // allow `#[must_use]` on functions and comparison operators (RFC 1940) (active, fn_must_use, "1.21.0", Some(43302)), @@ -418,6 +422,12 @@ declare_features! ( // #![wasm_import_memory] attribute (active, wasm_import_memory, "1.22.0", None), + + // `crate` in paths + (active, crate_in_paths, "1.23.0", Some(45477)), + + // In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`) + (active, in_band_lifetimes, "1.23.0", Some(44524)), ); declare_features! ( @@ -1023,6 +1033,14 @@ impl<'a> Context<'a> { if name == n { if let Gated(_, name, desc, ref has_feature) = *gateage { gate_feature_fn!(self, has_feature, attr.span, name, desc, GateStrength::Hard); + } else if name == "doc" { + if let Some(content) = attr.meta_item_list() { + if content.iter().any(|c| c.check_name("include")) { + gate_feature!(self, external_doc, attr.span, + "#[doc(include = \"...\")] is experimental" + ); + } + } } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); return; @@ -1300,6 +1318,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, doc_masked, attr.span, "#[doc(masked)] is experimental" ); + } else if content.iter().any(|c| c.check_name("spotlight")) { + gate_feature_post!(&self, doc_spotlight, attr.span, + "#[doc(spotlight)] is experimental" + ); } } } @@ -1628,6 +1650,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_impl_item(self, ii); } + fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) { + for segment in &path.segments { + if segment.identifier.name == keywords::Crate.name() { + gate_feature_post!(&self, crate_in_paths, segment.span, + "`crate` in paths is experimental"); + } + } + + visit::walk_path(self, path); + } + fn visit_vis(&mut self, vis: &'a ast::Visibility) { if let ast::Visibility::Crate(span, ast::CrateSugar::JustCrate) = *vis { gate_feature_post!(&self, crate_visibility_modifier, span, diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index e739c6d04e1..80ac0cb4faf 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -24,11 +24,12 @@ use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan}; use errors::registry::Registry; use errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, CodeMapper}; use errors::DiagnosticId; -use errors::emitter::Emitter; +use errors::emitter::{Emitter, EmitterWriter}; use std::rc::Rc; use std::io::{self, Write}; use std::vec; +use std::sync::{Arc, Mutex}; use rustc_serialize::json::{as_json, as_pretty_json}; @@ -95,7 +96,7 @@ struct Diagnostic { spans: Vec<DiagnosticSpan>, /// Associated diagnostic messages. children: Vec<Diagnostic>, - /// The message as rustc would render it. Currently this is always `None` + /// The message as rustc would render it. rendered: Option<String>, } @@ -170,6 +171,27 @@ impl Diagnostic { rendered: None, } }); + + // generate regular command line output and store it in the json + + // A threadsafe buffer for writing. + #[derive(Default, Clone)] + struct BufWriter(Arc<Mutex<Vec<u8>>>); + + impl Write for BufWriter { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.0.lock().unwrap().write(buf) + } + fn flush(&mut self) -> io::Result<()> { + self.0.lock().unwrap().flush() + } + } + let buf = BufWriter::default(); + let output = buf.clone(); + EmitterWriter::new(Box::new(buf), Some(je.cm.clone()), false).emit(db); + let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); + let output = String::from_utf8(output).unwrap(); + Diagnostic { message: db.message(), code: DiagnosticCode::map_opt_string(db.code.clone(), je), @@ -178,7 +200,7 @@ impl Diagnostic { children: db.children.iter().map(|c| { Diagnostic::from_sub_diagnostic(c, je) }).chain(sugg).collect(), - rendered: None, + rendered: Some(output), } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 078e86aa294..49a697edf41 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -58,7 +58,7 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { }; if !self.obsolete_set.contains(&kind) && - (error || self.sess.span_diagnostic.can_emit_warnings) { + (error || self.sess.span_diagnostic.flags.can_emit_warnings) { err.note(desc); self.obsolete_set.insert(kind); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c1819307928..0b03429ea2e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3916,6 +3916,10 @@ impl<'a> Parser<'a> { self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()) } + fn is_crate_vis(&self) -> bool { + self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep) + } + fn eat_auto_trait(&mut self) -> bool { if self.token.is_keyword(keywords::Auto) && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) @@ -4026,10 +4030,15 @@ impl<'a> Parser<'a> { node: StmtKind::Item(macro_def), span: lo.to(self.prev_span), } - // Starts like a simple path, but not a union item. + // Starts like a simple path, but not a union item or item with `crate` visibility. + // Our goal here is to parse an arbitrary path `a::b::c` but not something that starts + // like a path (1 token), but it fact not a path. + // `union::b::c` - path, `union U { ... }` - not a path. + // `crate::b::c` - path, `crate struct S;` - not a path. } else if self.token.is_path_start() && !self.token.is_qpath_start() && - !self.is_union_item() { + !self.is_union_item() && + !self.is_crate_vis() { let pth = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { @@ -5399,7 +5408,9 @@ impl<'a> Parser<'a> { pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> { maybe_whole!(self, NtVis, |x| x); - if self.eat_keyword(keywords::Crate) { + self.expected_tokens.push(TokenType::Keyword(keywords::Crate)); + if self.is_crate_vis() { + self.bump(); // `crate` return Ok(Visibility::Crate(self.prev_span, CrateSugar::JustCrate)); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f83343bf9af..ff87f146c0a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -347,6 +347,7 @@ impl Token { Some(id) => id.name == keywords::Super.name() || id.name == keywords::SelfValue.name() || id.name == keywords::SelfType.name() || + id.name == keywords::Crate.name() || id.name == keywords::DollarCrate.name(), None => false, } diff --git a/src/llvm b/src/llvm -Subproject 51f104bf1cc6c3a588a11c90a3b4a4a18ee080a +Subproject e45c75de1148456a9eb1a67c14a66df4dfb50c9 diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 7f76861c077..591ebdc9ddb 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -66,7 +66,7 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { case LLVMRustArchiveKind::COFF: return Archive::K_COFF; default: - llvm_unreachable("Bad ArchiveKind."); + report_fatal_error("Bad ArchiveKind."); } } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index d0c042e6451..4a359fb3ad3 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -235,7 +235,7 @@ static CodeModel::Model fromRust(LLVMRustCodeModel Model) { case LLVMRustCodeModel::Large: return CodeModel::Large; default: - llvm_unreachable("Bad CodeModel."); + report_fatal_error("Bad CodeModel."); } } @@ -258,7 +258,7 @@ static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) { case LLVMRustCodeGenOptLevel::Aggressive: return CodeGenOpt::Aggressive; default: - llvm_unreachable("Bad CodeGenOptLevel."); + report_fatal_error("Bad CodeGenOptLevel."); } } @@ -302,7 +302,7 @@ static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) { break; #endif } - llvm_unreachable("Bad RelocModel."); + report_fatal_error("Bad RelocModel."); } #if LLVM_RUSTLLVM @@ -511,7 +511,7 @@ static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) { case LLVMRustFileType::ObjectFile: return TargetMachine::CGFT_ObjectFile; default: - llvm_unreachable("Bad FileType."); + report_fatal_error("Bad FileType."); } } @@ -1197,7 +1197,7 @@ extern "C" bool LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *BcFile) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } struct LLVMRustThinLTOData { @@ -1211,32 +1211,32 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules, const char **preserved_symbols, int num_symbols) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" void LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } struct LLVMRustThinLTOBuffer { @@ -1244,22 +1244,22 @@ struct LLVMRustThinLTOBuffer { extern "C" LLVMRustThinLTOBuffer* LLVMRustThinLTOBufferCreate(LLVMModuleRef M) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" void LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" const void* LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" size_t LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } extern "C" LLVMModuleRef @@ -1267,6 +1267,6 @@ LLVMRustParseBitcodeForThinLTO(LLVMContextRef Context, const char *data, size_t len, const char *identifier) { - llvm_unreachable("ThinLTO not available"); + report_fatal_error("ThinLTO not available"); } #endif // LLVM_VERSION_GE(4, 0) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9aa172591b8..424b226bcf7 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -54,7 +54,7 @@ static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) { return AtomicOrdering::SequentiallyConsistent; } - llvm_unreachable("Invalid LLVMAtomicOrdering value!"); + report_fatal_error("Invalid LLVMAtomicOrdering value!"); } static LLVM_THREAD_LOCAL char *LastError; @@ -161,7 +161,7 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { case SanitizeMemory: return Attribute::SanitizeMemory; } - llvm_unreachable("bad AttributeKind"); + report_fatal_error("bad AttributeKind"); } extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index, @@ -356,7 +356,7 @@ static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { case LLVMRustSynchronizationScope::CrossThread: return SyncScope::System; default: - llvm_unreachable("bad SynchronizationScope."); + report_fatal_error("bad SynchronizationScope."); } } #else @@ -367,7 +367,7 @@ static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) { case LLVMRustSynchronizationScope::CrossThread: return CrossThread; default: - llvm_unreachable("bad SynchronizationScope."); + report_fatal_error("bad SynchronizationScope."); } } #endif @@ -397,7 +397,7 @@ static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) { case LLVMRustAsmDialect::Intel: return InlineAsm::AD_Intel; default: - llvm_unreachable("bad AsmDialect."); + report_fatal_error("bad AsmDialect."); } } @@ -748,7 +748,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags) #if LLVM_VERSION_GE(4, 0) , - AlignInBits + AlignInBits #endif )); } else { @@ -1149,7 +1149,7 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { return LLVMTokenTypeKind; #endif } - llvm_unreachable("Unhandled TypeID."); + report_fatal_error("Unhandled TypeID."); } extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C, @@ -1370,7 +1370,7 @@ static LLVMRustLinkage toRust(LLVMLinkage Linkage) { case LLVMCommonLinkage: return LLVMRustLinkage::CommonLinkage; default: - llvm_unreachable("Invalid LLVMRustLinkage value!"); + report_fatal_error("Invalid LLVMRustLinkage value!"); } } @@ -1399,7 +1399,7 @@ static LLVMLinkage fromRust(LLVMRustLinkage Linkage) { case LLVMRustLinkage::CommonLinkage: return LLVMCommonLinkage; } - llvm_unreachable("Invalid LLVMRustLinkage value!"); + report_fatal_error("Invalid LLVMRustLinkage value!"); } extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) { @@ -1447,7 +1447,7 @@ static LLVMRustVisibility toRust(LLVMVisibility Vis) { case LLVMProtectedVisibility: return LLVMRustVisibility::Protected; } - llvm_unreachable("Invalid LLVMRustVisibility value!"); + report_fatal_error("Invalid LLVMRustVisibility value!"); } static LLVMVisibility fromRust(LLVMRustVisibility Vis) { @@ -1459,7 +1459,7 @@ static LLVMVisibility fromRust(LLVMRustVisibility Vis) { case LLVMRustVisibility::Protected: return LLVMProtectedVisibility; } - llvm_unreachable("Invalid LLVMRustVisibility value!"); + report_fatal_error("Invalid LLVMRustVisibility value!"); } extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) { diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index 0380454b827..0bc29e8b5aa 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -106,7 +106,7 @@ result is then compared against reference files named those files doesn't exist, the output must be empty. If the test run fails, we will print out the current output, but it is also saved in `build/<target-triple>/test/ui/hello_world/main.stdout` (this path is -printed as part of the test failure mesage), so you can run `diff` and +printed as part of the test failure message), so you can run `diff` and so forth. ### Editing and updating the reference files diff --git a/src/test/compile-fail/E0657.rs b/src/test/compile-fail/E0657.rs new file mode 100644 index 00000000000..b72a8f03089 --- /dev/null +++ b/src/test/compile-fail/E0657.rs @@ -0,0 +1,36 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![allow(warnings)] +#![feature(conservative_impl_trait)] + +trait Id<T> {} +trait Lt<'a> {} + +impl<'a> Lt<'a> for () {} +impl<T> Id<T> for T {} + +fn free_fn_capture_hrtb_in_impl_trait() + -> impl for<'a> Id<impl Lt<'a>> + //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657] +{ + () +} + +struct Foo; +impl Foo { + fn impl_fn_capture_hrtb_in_impl_trait() + -> impl for<'a> Id<impl Lt<'a>> + //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level + { + () + } +} + +fn main() {} diff --git a/src/test/compile-fail/bogus-tag.rs b/src/test/compile-fail/bogus-tag.rs index c388d47da6e..a629f76d8b3 100644 --- a/src/test/compile-fail/bogus-tag.rs +++ b/src/test/compile-fail/bogus-tag.rs @@ -10,11 +10,14 @@ enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), } +//~^ NOTE variant `hsl` not found here fn main() { let red: color = color::rgb(255, 0, 0); match red { color::rgb(r, g, b) => { println!("rgb"); } - color::hsl(h, s, l) => { println!("hsl"); } //~ ERROR no function + color::hsl(h, s, l) => { println!("hsl"); } + //~^ ERROR no variant + //~| NOTE variant not found in `color` } } diff --git a/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs b/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs index 0b6b9bf7d48..c40470a927c 100644 --- a/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs +++ b/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs @@ -70,7 +70,7 @@ fn f() { let c1 = || get(&*x); *x = 5; //[ast]~ ERROR cannot assign //[mir]~^ ERROR cannot assign to `*x` because it is borrowed (Ast) - //[mir]~| ERROR cannot assign to `(*x)` because it is borrowed (Mir) + //[mir]~| ERROR cannot assign to `*x` because it is borrowed (Mir) } fn g() { @@ -82,7 +82,7 @@ fn g() { let c1 = || get(&*x.f); *x.f = 5; //[ast]~ ERROR cannot assign to `*x.f` //[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed (Ast) - //[mir]~| ERROR cannot assign to `(*x.f)` because it is borrowed (Mir) + //[mir]~| ERROR cannot assign to `*x.f` because it is borrowed (Mir) } fn h() { diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs index d1cf08ac754..32052fff90d 100644 --- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs @@ -252,7 +252,7 @@ fn main() { fn bump<'a>(mut block: &mut Block<'a>) { let x = &mut block; let p: &'a u8 = &*block.current; - //[mir]~^ ERROR cannot borrow `(*block.current)` as immutable because it is also borrowed as mutable (Mir) + //[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable (Mir) // No errors in AST because of issue rust#38899 } } @@ -266,7 +266,7 @@ fn main() { unsafe fn bump2(mut block: *mut Block2) { let x = &mut block; let p : *const u8 = &*(*block).current; - //[mir]~^ ERROR cannot borrow `(*block.current)` as immutable because it is also borrowed as mutable (Mir) + //[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable (Mir) // No errors in AST because of issue rust#38899 } } @@ -279,7 +279,7 @@ fn main() { //[ast]~^ ERROR cannot use `v[..].y` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..].y` because it was mutably borrowed (Ast) //[mir]~| ERROR cannot use `v[..].y` because it was mutably borrowed (Mir) - //[mir]~| ERROR cannot use `(*v)` because it was mutably borrowed (Mir) + //[mir]~| ERROR cannot use `*v` because it was mutably borrowed (Mir) } // Field of constant index { @@ -300,7 +300,7 @@ fn main() { let y = &mut x; &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time //[mir]~^ ERROR cannot borrow `**x` as mutable more than once at a time (Ast) - //[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir) + //[mir]~| ERROR cannot borrow `x` as mutable more than once at a time (Mir) *y = 1; }; } @@ -312,9 +312,20 @@ fn main() { let y = &mut x; &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time //[mir]~^ ERROR cannot borrow `**x` as mutable more than once at a time (Ast) - //[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir) + //[mir]~| ERROR cannot borrow `x` as mutable more than once at a time (Mir) *y = 1; } }; } + { + fn foo(x: Vec<i32>) { + let c = || { + drop(x); + drop(x); //[ast]~ ERROR use of moved value: `x` + //[mir]~^ ERROR use of moved value: `x` (Ast) + //[mir]~| ERROR use of moved value: `x` (Mir) + }; + c(); + } + } } diff --git a/src/test/compile-fail/changing-crates.rs b/src/test/compile-fail/changing-crates.rs index f74855a0849..89310706b52 100644 --- a/src/test/compile-fail/changing-crates.rs +++ b/src/test/compile-fail/changing-crates.rs @@ -17,8 +17,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on +//~| NOTE: the following crate versions were found //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: fn main() {} diff --git a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs index 16ed73e9095..513a17e2ef2 100644 --- a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs +++ b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs @@ -13,8 +13,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static { fn foo(x: &()) { bar(|| { - //~^ ERROR cannot infer - //~| ERROR does not fulfill + //~^ ERROR does not fulfill let _ = x; }) } diff --git a/src/test/compile-fail/coerce-overloaded-autoderef.rs b/src/test/compile-fail/coerce-overloaded-autoderef.rs index 43b771ce5db..1060c3f468c 100644 --- a/src/test/compile-fail/coerce-overloaded-autoderef.rs +++ b/src/test/compile-fail/coerce-overloaded-autoderef.rs @@ -22,7 +22,7 @@ fn double_mut_borrow<T>(x: &mut Box<T>) { let z = borrow_mut(x); //[ast]~^ ERROR cannot borrow `*x` as mutable more than once at a time //[mir]~^^ ERROR cannot borrow `*x` as mutable more than once at a time (Ast) - //[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir) + //[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir) } fn double_imm_borrow(x: &mut Box<i32>) { @@ -31,21 +31,21 @@ fn double_imm_borrow(x: &mut Box<i32>) { **x += 1; //[ast]~^ ERROR cannot assign to `**x` because it is borrowed //[mir]~^^ ERROR cannot assign to `**x` because it is borrowed (Ast) - //[mir]~| ERROR cannot assign to `(*(*x))` because it is borrowed (Mir) + //[mir]~| ERROR cannot assign to `**x` because it is borrowed (Mir) } fn double_mut_borrow2<T>(x: &mut Box<T>) { borrow_mut2(x, x); //[ast]~^ ERROR cannot borrow `*x` as mutable more than once at a time //[mir]~^^ ERROR cannot borrow `*x` as mutable more than once at a time (Ast) - //[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir) + //[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir) } fn double_borrow2<T>(x: &mut Box<T>) { borrow2(x, x); //[ast]~^ ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable //[mir]~^^ ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable (Ast) - //[mir]~| ERROR cannot borrow `(*x)` as immutable because it is also borrowed as mutable (Mir) + //[mir]~| ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable (Mir) } pub fn main() {} diff --git a/src/test/compile-fail/dollar-crate-is-keyword-2.rs b/src/test/compile-fail/dollar-crate-is-keyword-2.rs index ac96279d614..87a29038035 100644 --- a/src/test/compile-fail/dollar-crate-is-keyword-2.rs +++ b/src/test/compile-fail/dollar-crate-is-keyword-2.rs @@ -13,8 +13,8 @@ mod a {} macro_rules! m { () => { use a::$crate; //~ ERROR unresolved import `a::$crate` - use a::$crate::b; //~ ERROR unresolved import `a::$crate` - type A = a::$crate; //~ ERROR cannot find type `$crate` in module `a` + use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position + type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position } } diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs index d4e85e9744d..3096e8f8313 100644 --- a/src/test/compile-fail/empty-struct-braces-expr.rs +++ b/src/test/compile-fail/empty-struct-braces-expr.rs @@ -29,6 +29,6 @@ fn main() { let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1` - let xe3 = XE::Empty3; //~ ERROR no associated item named `Empty3` found for type - let xe3 = XE::Empty3(); //~ ERROR no associated item named `Empty3` found for type + let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type + let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type } diff --git a/src/test/compile-fail/feature-gate-doc_spotlight.rs b/src/test/compile-fail/feature-gate-doc_spotlight.rs new file mode 100644 index 00000000000..6369358538d --- /dev/null +++ b/src/test/compile-fail/feature-gate-doc_spotlight.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[doc(spotlight)] //~ ERROR: #[doc(spotlight)] is experimental +trait SomeTrait {} + +fn main() {} diff --git a/src/test/compile-fail/feature-gate-external_doc.rs b/src/test/compile-fail/feature-gate-external_doc.rs new file mode 100644 index 00000000000..fa0a2a29078 --- /dev/null +++ b/src/test/compile-fail/feature-gate-external_doc.rs @@ -0,0 +1,12 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[doc(include="asdf.md")] //~ ERROR: #[doc(include = "...")] is experimental +fn main() {} diff --git a/src/test/compile-fail/feature-gate-in_band_lifetimes.rs b/src/test/compile-fail/feature-gate-in_band_lifetimes.rs new file mode 100644 index 00000000000..ae1f81c2f57 --- /dev/null +++ b/src/test/compile-fail/feature-gate-in_band_lifetimes.rs @@ -0,0 +1,72 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] + +fn foo(x: &'x u8) -> &'x u8 { x } +//~^ ERROR use of undeclared lifetime name +//~^^ ERROR use of undeclared lifetime name + +struct X<'a>(&'a u8); + +impl<'a> X<'a> { + fn inner(&self) -> &'a u8 { + self.0 + } +} + +impl<'a> X<'b> { +//~^ ERROR use of undeclared lifetime name + fn inner_2(&self) -> &'b u8 { + //~^ ERROR use of undeclared lifetime name + self.0 + } +} + +impl X<'b> { +//~^ ERROR use of undeclared lifetime name + fn inner_3(&self) -> &'b u8 { + //~^ ERROR use of undeclared lifetime name + self.0 + } +} + +struct Y<T>(T); + +impl Y<&'a u8> { + //~^ ERROR use of undeclared lifetime name + fn inner(&self) -> &'a u8 { + //~^ ERROR use of undeclared lifetime name + self.0 + } +} + +trait MyTrait<'a> { + fn my_lifetime(&self) -> &'a u8; + fn any_lifetime() -> &'b u8; + //~^ ERROR use of undeclared lifetime name + fn borrowed_lifetime(&'b self) -> &'b u8; + //~^ ERROR use of undeclared lifetime name + //~^^ ERROR use of undeclared lifetime name +} + +impl MyTrait<'a> for Y<&'a u8> { +//~^ ERROR use of undeclared lifetime name +//~^^ ERROR use of undeclared lifetime name + fn my_lifetime(&self) -> &'a u8 { self.0 } + //~^ ERROR use of undeclared lifetime name + fn any_lifetime() -> &'b u8 { &0 } + //~^ ERROR use of undeclared lifetime name + fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } + //~^ ERROR use of undeclared lifetime name + //~^^ ERROR use of undeclared lifetime name +} + +fn main() {} diff --git a/src/test/compile-fail/generator-yielding-or-returning-itself.rs b/src/test/compile-fail/generator-yielding-or-returning-itself.rs new file mode 100644 index 00000000000..13abdf616b2 --- /dev/null +++ b/src/test/compile-fail/generator-yielding-or-returning-itself.rs @@ -0,0 +1,45 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generator_trait)] +#![feature(generators)] + +// Test that we cannot create a generator that returns a value of its +// own type. + +use std::ops::Generator; + +pub fn want_cyclic_generator_return<T>(_: T) + where T: Generator<Yield = (), Return = T> +{ +} + +fn supply_cyclic_generator_return() { + want_cyclic_generator_return(|| { + //~^ ERROR type mismatch + if false { yield None.unwrap(); } + None.unwrap() + }) +} + +pub fn want_cyclic_generator_yield<T>(_: T) + where T: Generator<Yield = T, Return = ()> +{ +} + +fn supply_cyclic_generator_yield() { + want_cyclic_generator_yield(|| { + //~^ ERROR type mismatch + if false { yield None.unwrap(); } + None.unwrap() + }) +} + +fn main() { } diff --git a/src/test/compile-fail/impl-trait/lifetimes.rs b/src/test/compile-fail/impl-trait/lifetimes.rs deleted file mode 100644 index 9d9f6bf7297..00000000000 --- a/src/test/compile-fail/impl-trait/lifetimes.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(conservative_impl_trait)] - -// Helper creating a fake borrow, captured by the impl Trait. -fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () } - -fn stack() -> impl Copy { - //~^ ERROR only named lifetimes are allowed in `impl Trait` - let x = 0; - &x -} - -fn late_bound(x: &i32) -> impl Copy { - //~^ ERROR only named lifetimes are allowed in `impl Trait` - x -} - -// FIXME(#34511) Should work but doesn't at the moment, -// region-checking needs an overhault to support this. -fn early_bound<'a>(x: &'a i32) -> impl Copy { - //~^ ERROR only named lifetimes are allowed in `impl Trait` - x -} - -fn ambiguous<'a, 'b>(x: &'a [u32], y: &'b [u32]) -> impl Iterator<Item=u32> { - //~^ ERROR only named lifetimes are allowed in `impl Trait` - if x.len() < y.len() { - x.iter().cloned() - } else { - y.iter().cloned() - } -} - -fn main() {} diff --git a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs new file mode 100644 index 00000000000..837160bc2fc --- /dev/null +++ b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs @@ -0,0 +1,39 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(conservative_impl_trait)] + +use std::fmt::Debug; + +fn elided(x: &i32) -> impl Copy { x } +//~^ ERROR cannot infer an appropriate lifetime + +fn explicit<'a>(x: &'a i32) -> impl Copy { x } +//~^ ERROR cannot infer an appropriate lifetime + +trait LifetimeTrait<'a> {} +impl<'a> LifetimeTrait<'a> for &'a i32 {} + +fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } +//~^ ERROR cannot infer an appropriate lifetime + +// Tests that a closure type contianing 'b cannot be returned from a type where +// only 'a was expected. +fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { + //~^ ERROR lifetime mismatch + move |_| println!("{}", y) +} + +fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { + //~^ ERROR the parameter type `T` may not live long enough + x +} + +fn main() {} diff --git a/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs new file mode 100644 index 00000000000..2a06580fe60 --- /dev/null +++ b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(conservative_impl_trait)] + +use std::fmt::Debug; + +trait MultiRegionTrait<'a, 'b> {} +impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {} + +fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { +//~^ ERROR ambiguous lifetime bound + (x, y) +} + +fn main() {} diff --git a/src/test/compile-fail/impl-trait/type_parameters_captured.rs b/src/test/compile-fail/impl-trait/type_parameters_captured.rs new file mode 100644 index 00000000000..c6ff762b905 --- /dev/null +++ b/src/test/compile-fail/impl-trait/type_parameters_captured.rs @@ -0,0 +1,24 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(conservative_impl_trait)] + +use std::fmt::Debug; + +trait Any {} +impl<T> Any for T {} + +// Check that type parameters are captured and not considered 'static +fn foo<T>(x: T) -> impl Any + 'static { + //~^ ERROR the parameter type `T` may not live long enough + x +} + +fn main() {} diff --git a/src/test/compile-fail/issue-22638.rs b/src/test/compile-fail/issue-22638.rs index 53b0d9f4e9f..1c534ebbd43 100644 --- a/src/test/compile-fail/issue-22638.rs +++ b/src/test/compile-fail/issue-22638.rs @@ -19,7 +19,6 @@ struct A (B); impl A { pub fn matches<F: Fn()>(&self, f: &F) { - //~^ ERROR reached the recursion limit while instantiating `A::matches::<[closure let &A(ref term) = self; term.matches(f); } @@ -59,6 +58,7 @@ struct D (Box<A>); impl D { pub fn matches<F: Fn()>(&self, f: &F) { + //~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure let &D(ref a) = self; a.matches(f) } diff --git a/src/test/compile-fail/issue-22933-2.rs b/src/test/compile-fail/issue-22933-2.rs index 97456c2da87..583f2ace4ba 100644 --- a/src/test/compile-fail/issue-22933-2.rs +++ b/src/test/compile-fail/issue-22933-2.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum Delicious { +enum Delicious { //~ NOTE variant `PIE` not found here Pie = 0x1, Apple = 0x2, ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, - //~^ ERROR no associated item named `PIE` found for type `Delicious` + //~^ ERROR no variant named `PIE` found for type `Delicious` + //~| NOTE variant not found in `Delicious` } fn main() {} diff --git a/src/test/compile-fail/issue-23173.rs b/src/test/compile-fail/issue-23173.rs index 946e4b9e96e..c0983eb0e52 100644 --- a/src/test/compile-fail/issue-23173.rs +++ b/src/test/compile-fail/issue-23173.rs @@ -9,9 +9,27 @@ // except according to those terms. enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } +//~^ NOTE variant `Homura` not found here +struct Struct { + //~^ NOTE function or associated item `method` not found for this + //~| NOTE function or associated item `method` not found for this + //~| NOTE associated item `Assoc` not found for this + a: usize, +} fn use_token(token: &Token) { unimplemented!() } fn main() { - use_token(&Token::Homura); //~ ERROR no associated item named + use_token(&Token::Homura); + //~^ ERROR no variant named `Homura` + //~| NOTE variant not found in `Token` + Struct::method(); + //~^ ERROR no function or associated item named `method` found for type + //~| NOTE function or associated item not found in `Struct` + Struct::method; + //~^ ERROR no function or associated item named `method` found for type + //~| NOTE function or associated item not found in `Struct` + Struct::Assoc; + //~^ ERROR no associated item named `Assoc` found for type `Struct` in + //~| NOTE associated item not found in `Struct` } diff --git a/src/test/compile-fail/issue-23217.rs b/src/test/compile-fail/issue-23217.rs index 95f6526f115..cce0b99c04d 100644 --- a/src/test/compile-fail/issue-23217.rs +++ b/src/test/compile-fail/issue-23217.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub enum SomeEnum { +pub enum SomeEnum { //~ NOTE variant `A` not found here B = SomeEnum::A, - //~^ ERROR no associated item named `A` found for type `SomeEnum` + //~^ ERROR no variant named `A` found for type `SomeEnum` + //~| NOTE variant not found in `SomeEnum` } fn main() {} diff --git a/src/test/run-pass/issue-25439.rs b/src/test/compile-fail/issue-25439.rs index 88c48f42c51..6e33fd5ae71 100644 --- a/src/test/run-pass/issue-25439.rs +++ b/src/test/compile-fail/issue-25439.rs @@ -15,5 +15,5 @@ fn fix<F>(f: F) -> i32 where F: Fn(Helper<F>, i32) -> i32 { } fn main() { - fix(|_, x| x); + fix(|_, x| x); //~ ERROR closure/generator type that references itself [E0644] } diff --git a/src/test/compile-fail/issue-28971.rs b/src/test/compile-fail/issue-28971.rs index 1d14b71a40e..10be4d6210d 100644 --- a/src/test/compile-fail/issue-28971.rs +++ b/src/test/compile-fail/issue-28971.rs @@ -10,13 +10,15 @@ // This should not cause an ICE -enum Foo { +enum Foo { //~ NOTE variant `Baz` not found here Bar(u8) } fn main(){ foo(|| { match Foo::Bar(1) { - Foo::Baz(..) => (), //~ ERROR no associated + Foo::Baz(..) => (), + //~^ ERROR no variant named `Baz` found for type `Foo` + //~| NOTE variant not found in `Foo` _ => (), } }); diff --git a/src/test/compile-fail/issue-31221.rs b/src/test/compile-fail/issue-31221.rs index e2b80215caf..8701ca0178f 100644 --- a/src/test/compile-fail/issue-31221.rs +++ b/src/test/compile-fail/issue-31221.rs @@ -13,8 +13,6 @@ #![allow(non_snake_case)] #![deny(unreachable_patterns)] //~^ NOTE lint level defined here -//~^^ NOTE lint level defined here -//~^^^ NOTE lint level defined here #[derive(Clone, Copy)] enum Enum { diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index f45e80f5252..d6ca5e6b1d9 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -74,7 +74,7 @@ pub enum pub_enum3 { enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used enum used_enum { foo3, - bar3 //~ ERROR variant is never used + bar3 //~ ERROR variant is never constructed } fn f<T>() {} diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs index 3df089fc200..1296cf46e6f 100644 --- a/src/test/compile-fail/lint-dead-code-4.rs +++ b/src/test/compile-fail/lint-dead-code-4.rs @@ -22,8 +22,8 @@ fn field_read(f: Foo) -> usize { } enum XYZ { - X, //~ ERROR variant is never used - Y { //~ ERROR variant is never used + X, //~ ERROR variant is never constructed + Y { //~ ERROR variant is never constructed a: String, b: i32, c: i32, @@ -43,13 +43,13 @@ enum ABC { //~ ERROR enum is never used // ensure struct variants get warning for their fields enum IJK { - I, //~ ERROR variant is never used + I, //~ ERROR variant is never constructed J { a: String, b: i32, //~ ERROR field is never used c: i32, //~ ERROR field is never used }, - K //~ ERROR variant is never used + K //~ ERROR variant is never constructed } diff --git a/src/test/compile-fail/lint-dead-code-5.rs b/src/test/compile-fail/lint-dead-code-5.rs index 04d6547d938..ee5cf24823d 100644 --- a/src/test/compile-fail/lint-dead-code-5.rs +++ b/src/test/compile-fail/lint-dead-code-5.rs @@ -13,15 +13,15 @@ enum Enum1 { Variant1(isize), - Variant2 //~ ERROR: variant is never used + Variant2 //~ ERROR: variant is never constructed } enum Enum2 { Variant3(bool), #[allow(dead_code)] Variant4(isize), - Variant5 { _x: isize }, //~ ERROR: variant is never used: `Variant5` - Variant6(isize), //~ ERROR: variant is never used: `Variant6` + Variant5 { _x: isize }, //~ ERROR: variant is never constructed: `Variant5` + Variant6(isize), //~ ERROR: variant is never constructed: `Variant6` _Variant7, } diff --git a/src/test/compile-fail/lint-dead-code-variant.rs b/src/test/compile-fail/lint-dead-code-variant.rs index 0116d63caf2..3301560c315 100644 --- a/src/test/compile-fail/lint-dead-code-variant.rs +++ b/src/test/compile-fail/lint-dead-code-variant.rs @@ -12,7 +12,7 @@ #[derive(Clone)] enum Enum { - Variant1, //~ ERROR: variant is never used + Variant1, //~ ERROR: variant is never constructed Variant2, } diff --git a/src/test/compile-fail/lint-output-format-2.rs b/src/test/compile-fail/lint-output-format-2.rs index 8dc46558cb0..29d7c6caec4 100644 --- a/src/test/compile-fail/lint-output-format-2.rs +++ b/src/test/compile-fail/lint-output-format-2.rs @@ -25,6 +25,5 @@ use lint_output_format::{foo, bar}; fn main() { //~ ERROR: compilation successful let _x = foo(); //~^ WARNING use of deprecated item 'lint_output_format::foo': text - //~| NOTE #[warn(deprecated)] on by default let _y = bar(); } diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs index 94e189aa47f..bee5a2c45be 100644 --- a/src/test/compile-fail/lint-unconditional-recursion.rs +++ b/src/test/compile-fail/lint-unconditional-recursion.rs @@ -10,19 +10,7 @@ #![deny(unconditional_recursion)] //~^ NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here -//~| NOTE lint level defined here + #![allow(dead_code)] fn foo() { //~ ERROR function cannot return without recurring foo(); //~ NOTE recursive call site diff --git a/src/test/compile-fail/mut-pattern-internal-mutability.rs b/src/test/compile-fail/mut-pattern-internal-mutability.rs index 1c7bc9d7303..a1b7a314f21 100644 --- a/src/test/compile-fail/mut-pattern-internal-mutability.rs +++ b/src/test/compile-fail/mut-pattern-internal-mutability.rs @@ -27,5 +27,5 @@ fn main() { let &mut ref x = foo; *foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed //[mir]~^ ERROR cannot assign to `*foo` because it is borrowed (Ast) - //[mir]~| ERROR cannot assign to `(*foo)` because it is borrowed (Mir) + //[mir]~| ERROR cannot assign to `*foo` because it is borrowed (Mir) } diff --git a/src/test/compile-fail/nll/reference-carried-through-struct-field.rs b/src/test/compile-fail/nll/reference-carried-through-struct-field.rs new file mode 100644 index 00000000000..afde2540829 --- /dev/null +++ b/src/test/compile-fail/nll/reference-carried-through-struct-field.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +//revisions: ast mir +//[mir] compile-flags: -Z emit-end-regions -Z borrowck-mir -Z nll + +#![allow(unused_assignments)] + +struct Wrap<'a> { w: &'a mut u32 } + +fn foo() { + let mut x = 22; + let wrapper = Wrap { w: &mut x }; + x += 1; //[ast]~ ERROR cannot assign to `x` because it is borrowed [E0506] + //[mir]~^ ERROR cannot assign to `x` because it is borrowed (Ast) [E0506] + //[mir]~^^ ERROR cannot assign to `x` because it is borrowed (Mir) [E0506] + //[mir]~^^^ ERROR cannot use `x` because it was mutably borrowed (Mir) [E0503] + *wrapper.w += 1; +} + +fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs index a276af83dee..5d162fe944e 100644 --- a/src/test/compile-fail/occurs-check-2.rs +++ b/src/test/compile-fail/occurs-check-2.rs @@ -16,7 +16,5 @@ fn main() { g = f; f = box g; //~^ ERROR mismatched types - //~| expected type `_` - //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index 5b6a11e58c2..2c784365ea9 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -14,7 +14,5 @@ fn main() { let f; f = box f; //~^ ERROR mismatched types - //~| expected type `_` - //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs b/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs new file mode 100644 index 00000000000..75c2a5f5bc4 --- /dev/null +++ b/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(crate_in_paths)] + +struct S; + +mod m { + fn f() { + let s = crate::S; //~ ERROR `crate` can only be used in absolute paths + } +} + +fn main() {} diff --git a/src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs b/src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs new file mode 100644 index 00000000000..8c5a971c2f7 --- /dev/null +++ b/src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(crate_in_paths)] +#![feature(crate_visibility_modifier)] + +mod m { + pub struct Z; + pub struct S1(crate (::m::Z)); // OK + pub struct S2(::crate ::m::Z); // OK + pub struct S3(crate ::m::Z); //~ ERROR `crate` can only be used in absolute paths +} + +fn main() { + crate struct S; // OK (item in statement position) +} diff --git a/src/test/compile-fail/rfc-2126-crate-paths/feature-gate-crate_in_paths.rs b/src/test/compile-fail/rfc-2126-crate-paths/feature-gate-crate_in_paths.rs new file mode 100644 index 00000000000..830ec5959b7 --- /dev/null +++ b/src/test/compile-fail/rfc-2126-crate-paths/feature-gate-crate_in_paths.rs @@ -0,0 +1,15 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S; + +fn main() { + let _ = ::crate::S; //~ ERROR `crate` in paths is experimental +} diff --git a/src/test/parse-fail/keyword-crate-as-identifier.rs b/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs index 8a914ca7b17..2c94f7b0f59 100644 --- a/src/test/parse-fail/keyword-crate-as-identifier.rs +++ b/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z parse-only - -// This file was auto-generated using 'src/etc/generate-keyword-tests.py crate' +#![feature(crate_in_paths)] fn main() { - let crate = "foo"; //~ error: expected pattern, found keyword `crate` + let crate = 0; //~ ERROR `crate` can only be used in absolute paths } diff --git a/src/test/compile-fail/super-at-top-level.rs b/src/test/compile-fail/super-at-top-level.rs index 4db673e2006..c607711c44f 100644 --- a/src/test/compile-fail/super-at-top-level.rs +++ b/src/test/compile-fail/super-at-top-level.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::f; //~ ERROR unresolved import `super` [E0432] - //~^ There are too many initial `super`s. +use super::f; //~ ERROR There are too many initial `super`s fn main() { } diff --git a/src/test/compile-fail/svh-change-lit.rs b/src/test/compile-fail/svh-change-lit.rs index 1638caaa923..f24a3905cc3 100644 --- a/src/test/compile-fail/svh-change-lit.rs +++ b/src/test/compile-fail/svh-change-lit.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-change-significant-cfg.rs b/src/test/compile-fail/svh-change-significant-cfg.rs index 99523ca699f..7a197fc6ae9 100644 --- a/src/test/compile-fail/svh-change-significant-cfg.rs +++ b/src/test/compile-fail/svh-change-significant-cfg.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-change-trait-bound.rs b/src/test/compile-fail/svh-change-trait-bound.rs index dcf4859792d..560feb960f6 100644 --- a/src/test/compile-fail/svh-change-trait-bound.rs +++ b/src/test/compile-fail/svh-change-trait-bound.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-change-type-arg.rs b/src/test/compile-fail/svh-change-type-arg.rs index 7e51ca456b2..b8928c09562 100644 --- a/src/test/compile-fail/svh-change-type-arg.rs +++ b/src/test/compile-fail/svh-change-type-arg.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-change-type-ret.rs b/src/test/compile-fail/svh-change-type-ret.rs index 54ca87d84c1..14973baafbd 100644 --- a/src/test/compile-fail/svh-change-type-ret.rs +++ b/src/test/compile-fail/svh-change-type-ret.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-change-type-static.rs b/src/test/compile-fail/svh-change-type-static.rs index ea90faaf610..cac95b4df8c 100644 --- a/src/test/compile-fail/svh-change-type-static.rs +++ b/src/test/compile-fail/svh-change-type-static.rs @@ -18,8 +18,7 @@ extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on //~| NOTE: perhaps that crate needs to be recompiled -//~| NOTE: crate `a` path #1: -//~| NOTE: crate `b` path #1: +//~| NOTE: the following crate versions were found: fn main() { b::foo() diff --git a/src/test/compile-fail/svh-use-trait.rs b/src/test/compile-fail/svh-use-trait.rs index c0a5a0a17eb..c875fa8a0b2 100644 --- a/src/test/compile-fail/svh-use-trait.rs +++ b/src/test/compile-fail/svh-use-trait.rs @@ -23,8 +23,7 @@ extern crate uta; extern crate utb; //~ ERROR: found possibly newer version of crate `uta` which `utb` depends //~| NOTE: perhaps that crate needs to be recompiled? -//~| NOTE: crate `uta` path #1: -//~| NOTE: crate `utb` path #1: +//~| NOTE: the following crate versions were found: fn main() { utb::foo() diff --git a/src/test/compile-fail/use-super-global-path.rs b/src/test/compile-fail/use-super-global-path.rs index 4162e037cf3..fc1a72f6f2b 100644 --- a/src/test/compile-fail/use-super-global-path.rs +++ b/src/test/compile-fail/use-super-global-path.rs @@ -18,7 +18,7 @@ mod foo { pub fn g() { use ::super::main; //~ ERROR global paths cannot start with `super` - main(); + main(); //~ ERROR cannot find function `main` in this scope } } diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index f9e8fb026ca..403ea905681 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -370,7 +370,16 @@ impl Foo { #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeckTables")] + // Warning: Note that `TypeckTables` are coming up clean here. + // The addition or removal of lifetime parameters that don't + // appear in the arguments or fn body in any way does not, in + // fact, affect the `TypeckTables` in any semantic way (at least + // as of this writing). **However,** altering the order of + // lowering **can** cause it appear to affect the `TypeckTables`: + // if we lower generics before the body, then the `HirId` for + // things in the body will be affected. So if you start to see + // `TypeckTables` appear dirty, that might be the cause. -nmatsakis + #[rustc_clean(cfg="cfail2", except="Hir,HirBody")] #[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] @@ -391,9 +400,18 @@ impl Foo { #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] impl Foo { + // Warning: Note that `TypeckTables` are coming up clean here. + // The addition or removal of type parameters that don't appear in + // the arguments or fn body in any way does not, in fact, affect + // the `TypeckTables` in any semantic way (at least as of this + // writing). **However,** altering the order of lowering **can** + // cause it appear to affect the `TypeckTables`: if we lower + // generics before the body, then the `HirId` for things in the + // body will be affected. So if you start to see `TypeckTables` + // appear dirty, that might be the cause. -nmatsakis #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem,TypeckTables", + except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem", )] #[rustc_clean(cfg="cfail3")] #[rustc_metadata_dirty(cfg="cfail2")] @@ -439,8 +457,17 @@ impl Foo { #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] impl Foo { + // Warning: Note that `TypeckTables` are coming up clean here. + // The addition or removal of bounds that don't appear in the + // arguments or fn body in any way does not, in fact, affect the + // `TypeckTables` in any semantic way (at least as of this + // writing). **However,** altering the order of lowering **can** + // cause it appear to affect the `TypeckTables`: if we lower + // generics before the body, then the `HirId` for things in the + // body will be affected. So if you start to see `TypeckTables` + // appear dirty, that might be the cause. -nmatsakis #[rustc_clean(cfg="cfail2", except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,\ - TypeOfItem,TypeckTables")] + TypeOfItem")] #[rustc_clean(cfg="cfail3")] #[rustc_metadata_dirty(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] @@ -461,7 +488,16 @@ impl Foo { #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem,TypeckTables")] + // Warning: Note that `TypeckTables` are coming up clean here. + // The addition or removal of bounds that don't appear in the + // arguments or fn body in any way does not, in fact, affect the + // `TypeckTables` in any semantic way (at least as of this + // writing). **However,** altering the order of lowering **can** + // cause it appear to affect the `TypeckTables`: if we lower + // generics before the body, then the `HirId` for things in the + // body will be affected. So if you start to see `TypeckTables` + // appear dirty, that might be the cause. -nmatsakis + #[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem")] #[rustc_clean(cfg="cfail3")] #[rustc_metadata_dirty(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index d46fbd36760..dd8bd8fcff2 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -32,26 +32,9 @@ pub fn change_name() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] -#[rustc_metadata_clean(cfg="cfail2")] -#[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_clean(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] pub fn change_name() { let _y = 2u64; } @@ -65,26 +48,11 @@ pub fn add_type() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_clean(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_clean(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn add_type() { let _x: u32 = 2u32; } @@ -98,26 +66,11 @@ pub fn change_type() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_type() { let _x: u8 = 2; } @@ -131,26 +84,11 @@ pub fn change_mutability_of_reference_type() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_clean(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_mutability_of_reference_type() { let _x: &mut u64; } @@ -164,26 +102,11 @@ pub fn change_mutability_of_slot() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_mutability_of_slot() { let _x: u64 = 0; } @@ -197,26 +120,11 @@ pub fn change_simple_binding_to_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_simple_binding_to_pattern() { let (_a, _b) = (0u8, 'x'); } @@ -230,26 +138,11 @@ pub fn change_name_in_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_clean(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_name_in_pattern() { let (_a, _c) = (1u8, 'y'); } @@ -263,26 +156,11 @@ pub fn add_ref_in_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn add_ref_in_pattern() { let (ref _a, _b) = (1u8, 'y'); } @@ -296,18 +174,11 @@ pub fn add_amp_in_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] pub fn add_amp_in_pattern() { let (&_a, _b) = (&1u8, 'y'); } @@ -321,26 +192,11 @@ pub fn change_mutability_of_binding_in_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); } @@ -354,26 +210,11 @@ pub fn add_initializer() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,TypeckTables,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_dirty(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn add_initializer() { let _x: i16 = 3i16; } @@ -387,26 +228,11 @@ pub fn change_initializer() { } #[cfg(not(cfail1))] -#[rustc_clean(label="Hir", cfg="cfail2")] -#[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_dirty(label="HirBody", cfg="cfail2")] -#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_clean(cfg="cfail2", + except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] -#[rustc_dirty(label="MirValidated", cfg="cfail2")] -#[rustc_clean(label="MirValidated", cfg="cfail3")] -#[rustc_dirty(label="MirOptimized", cfg="cfail2")] -#[rustc_clean(label="MirOptimized", cfg="cfail3")] -#[rustc_clean(label="TypeckTables", cfg="cfail2")] -#[rustc_clean(label="TypeckTables", cfg="cfail3")] -#[rustc_clean(label="TypeOfItem", cfg="cfail2")] -#[rustc_clean(label="TypeOfItem", cfg="cfail3")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail2")] -#[rustc_clean(label="GenericsOfItem", cfg="cfail3")] -#[rustc_clean(label="FnSignature", cfg="cfail2")] -#[rustc_clean(label="FnSignature", cfg="cfail3")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")] -#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")] pub fn change_initializer() { let _x = 5u16; } diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline-closure-borrows-arg.rs new file mode 100644 index 00000000000..de7b38d5519 --- /dev/null +++ b/src/test/mir-opt/inline-closure-borrows-arg.rs @@ -0,0 +1,50 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z span_free_formats + +// Tests that MIR inliner can handle closure arguments, +// even when (#45894) + +fn main() { + println!("{}", foo(0, &14)); +} + +fn foo<T: Copy>(_t: T, q: &i32) -> i32 { + let x = |r: &i32, _s: &i32| { + let variable = &*r; + *variable + }; + x(q, q) +} + +// END RUST SOURCE +// START rustc.foo.Inline.after.mir +// ... +// bb0: { +// ... +// _3 = [closure@NodeId(39)]; +// ... +// _4 = &_3; +// ... +// _6 = &(*_2); +// ... +// _7 = &(*_2); +// _5 = (_6, _7); +// _9 = (_5.0: &i32); +// _10 = (_5.1: &i32); +// StorageLive(_8); +// _8 = (*_9); +// _0 = _8; +// ... +// return; +// } +// ... +// END rustc.foo.Inline.after.mir diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline-closure.rs index 3f3428714d1..9d3fb923f5b 100644 --- a/src/test/mir-opt/inline-closure.rs +++ b/src/test/mir-opt/inline-closure.rs @@ -34,9 +34,11 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 { // ... // _7 = _2; // _5 = (_6, _7); -// _0 = (_5.0: i32); +// _8 = (_5.0: i32); +// _9 = (_5.1: i32); +// _0 = _8; // ... // return; // } // ... -// END rustc.foo.Inline.after.mir \ No newline at end of file +// END rustc.foo.Inline.after.mir diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index 47eeffe35a8..4d2ba5e2b12 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -12,7 +12,7 @@ // 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 -// types of the impl, which would trigger a cycle. We supressed this +// 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. #![feature(rustc_attrs)] diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs new file mode 100644 index 00000000000..4626dc17e1f --- /dev/null +++ b/src/test/mir-opt/lower_128bit_debug_test.rs @@ -0,0 +1,145 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z lower_128bit_ops -C debug_assertions=yes + +#![feature(i128_type)] +#![feature(lang_items)] + +#[lang="i128_div"] +fn i128_div(_x: i128, _y: i128) -> i128 { 3 } +#[lang="u128_div"] +fn u128_div(_x: u128, _y: u128) -> u128 { 4 } +#[lang="i128_rem"] +fn i128_rem(_x: i128, _y: i128) -> i128 { 5 } +#[lang="u128_rem"] +fn u128_rem(_x: u128, _y: u128) -> u128 { 6 } + +#[lang="i128_addo"] +fn i128_addo(_x: i128, _y: i128) -> (i128, bool) { (0, false) } +#[lang="u128_addo"] +fn u128_addo(_x: u128, _y: u128) -> (u128, bool) { (1, false) } +#[lang="i128_subo"] +fn i128_subo(_x: i128, _y: i128) -> (i128, bool) { (2, false) } +#[lang="u128_subo"] +fn u128_subo(_x: u128, _y: u128) -> (u128, bool) { (3, false) } +#[lang="i128_mulo"] +fn i128_mulo(_x: i128, _y: i128) -> (i128, bool) { (4, false) } +#[lang="u128_mulo"] +fn u128_mulo(_x: u128, _y: u128) -> (u128, bool) { (5, false) } +#[lang="i128_shlo"] +fn i128_shlo(_x: i128, _y: u128) -> (i128, bool) { (6, false) } +#[lang="u128_shlo"] +fn u128_shlo(_x: u128, _y: u128) -> (u128, bool) { (6, false) } +#[lang="i128_shro"] +fn i128_shro(_x: i128, _y: u128) -> (i128, bool) { (7, false) } +#[lang="u128_shro"] +fn u128_shro(_x: u128, _y: u128) -> (u128, bool) { (8, false) } + +fn test_signed(mut x: i128) -> i128 { + x += 1; + x -= 2; + x *= 3; + x /= 4; + x %= 5; + x <<= 6; + x >>= 7; + x +} + +fn test_unsigned(mut x: u128) -> u128 { + x += 1; + x -= 2; + x *= 3; + x /= 4; + x %= 5; + x <<= 6; + x >>= 7; + x +} + +fn main() { + test_signed(-200); + test_unsigned(200); +} + +// END RUST SOURCE + +// START rustc.test_signed.Lower128Bit.after.mir +// _2 = const i128_addo(_1, const 1i128) -> bb10; +// ... +// _1 = (_2.0: i128); +// _3 = const i128_subo(_1, const 2i128) -> bb11; +// ... +// _1 = (_3.0: i128); +// _4 = const i128_mulo(_1, const 3i128) -> bb12; +// ... +// _1 = (_4.0: i128); +// ... +// _1 = const i128_div(_1, const 4i128) -> bb13; +// ... +// _1 = const i128_rem(_1, const 5i128) -> bb15; +// ... +// _1 = (_13.0: i128); +// ... +// _17 = const 7i32 as u128 (Misc); +// _14 = const i128_shro(_1, _17) -> bb16; +// ... +// _1 = (_14.0: i128); +// ... +// assert(!(_2.1: bool), "attempt to add with overflow") -> bb1; +// ... +// assert(!(_3.1: bool), "attempt to subtract with overflow") -> bb2; +// ... +// assert(!(_4.1: bool), "attempt to multiply with overflow") -> bb3; +// ... +// assert(!(_13.1: bool), "attempt to shift left with overflow") -> bb8; +// ... +// _16 = const 6i32 as u128 (Misc); +// _13 = const i128_shlo(_1, _16) -> bb14; +// ... +// assert(!(_14.1: bool), "attempt to shift right with overflow") -> bb9; +// END rustc.test_signed.Lower128Bit.after.mir + +// START rustc.test_unsigned.Lower128Bit.after.mir +// _2 = const u128_addo(_1, const 1u128) -> bb8; +// ... +// _1 = (_2.0: u128); +// _3 = const u128_subo(_1, const 2u128) -> bb9; +// ... +// _1 = (_3.0: u128); +// _4 = const u128_mulo(_1, const 3u128) -> bb10; +// ... +// _1 = (_4.0: u128); +// ... +// _1 = const u128_div(_1, const 4u128) -> bb11; +// ... +// _1 = const u128_rem(_1, const 5u128) -> bb13; +// ... +// _1 = (_7.0: u128); +// ... +// _11 = const 7i32 as u128 (Misc); +// _8 = const u128_shro(_1, _11) -> bb14; +// ... +// _1 = (_8.0: u128); +// ... +// assert(!(_2.1: bool), "attempt to add with overflow") -> bb1; +// ... +// assert(!(_3.1: bool), "attempt to subtract with overflow") -> bb2; +// ... +// assert(!(_4.1: bool), "attempt to multiply with overflow") -> bb3; +// ... +// assert(!(_7.1: bool), "attempt to shift left with overflow") -> bb6; +// ... +// _10 = const 6i32 as u128 (Misc); +// _7 = const u128_shlo(_1, _10) -> bb12; +// ... +// assert(!(_8.1: bool), "attempt to shift right with overflow") -> bb7; +// END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs new file mode 100644 index 00000000000..207cd0ac57e --- /dev/null +++ b/src/test/mir-opt/lower_128bit_test.rs @@ -0,0 +1,108 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z lower_128bit_ops -C debug_assertions=no + +#![feature(i128_type)] +#![feature(lang_items)] + +#[lang="i128_add"] +fn i128_add(_x: i128, _y: i128) -> i128 { 0 } +#[lang="u128_add"] +fn u128_add(_x: u128, _y: u128) -> u128 { 0 } +#[lang="i128_sub"] +fn i128_sub(_x: i128, _y: i128) -> i128 { 1 } +#[lang="u128_sub"] +fn u128_sub(_x: u128, _y: u128) -> u128 { 1 } +#[lang="i128_mul"] +fn i128_mul(_x: i128, _y: i128) -> i128 { 2 } +#[lang="u128_mul"] +fn u128_mul(_x: u128, _y: u128) -> u128 { 2 } +#[lang="i128_div"] +fn i128_div(_x: i128, _y: i128) -> i128 { 3 } +#[lang="u128_div"] +fn u128_div(_x: u128, _y: u128) -> u128 { 4 } +#[lang="i128_rem"] +fn i128_rem(_x: i128, _y: i128) -> i128 { 5 } +#[lang="u128_rem"] +fn u128_rem(_x: u128, _y: u128) -> u128 { 6 } +#[lang="i128_shl"] +fn i128_shl(_x: i128, _y: u32) -> i128 { 7 } +#[lang="u128_shl"] +fn u128_shl(_x: u128, _y: u32) -> u128 { 7 } +#[lang="i128_shr"] +fn i128_shr(_x: i128, _y: u32) -> i128 { 8 } +#[lang="u128_shr"] +fn u128_shr(_x: u128, _y: u32) -> u128 { 9 } + +fn test_signed(mut x: i128) -> i128 { + x += 1; + x -= 2; + x *= 3; + x /= 4; + x %= 5; + x <<= 6; + x >>= 7; + x +} + +fn test_unsigned(mut x: u128) -> u128 { + x += 1; + x -= 2; + x *= 3; + x /= 4; + x %= 5; + x <<= 6; + x >>= 7; + x +} + +fn main() { + test_signed(-200); + test_unsigned(200); +} + +// END RUST SOURCE + +// START rustc.test_signed.Lower128Bit.after.mir +// _1 = const i128_add(_1, const 1i128) -> bb7; +// ... +// _1 = const i128_div(_1, const 4i128) -> bb8; +// ... +// _1 = const i128_rem(_1, const 5i128) -> bb11; +// ... +// _1 = const i128_mul(_1, const 3i128) -> bb5; +// ... +// _1 = const i128_sub(_1, const 2i128) -> bb6; +// ... +// _11 = const 7i32 as u32 (Misc); +// _1 = const i128_shr(_1, _11) -> bb9; +// ... +// _12 = const 6i32 as u32 (Misc); +// _1 = const i128_shl(_1, _12) -> bb10; +// END rustc.test_signed.Lower128Bit.after.mir + +// START rustc.test_unsigned.Lower128Bit.after.mir +// _1 = const u128_add(_1, const 1u128) -> bb5; +// ... +// _1 = const u128_div(_1, const 4u128) -> bb6; +// ... +// _1 = const u128_rem(_1, const 5u128) -> bb9; +// ... +// _1 = const u128_mul(_1, const 3u128) -> bb3; +// ... +// _1 = const u128_sub(_1, const 2u128) -> bb4; +// ... +// _5 = const 7i32 as u32 (Misc); +// _1 = const u128_shr(_1, _5) -> bb7; +// ... +// _6 = const 6i32 as u32 (Misc); +// _1 = const u128_shl(_1, _6) -> bb8; +// END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index f4d1caa6a95..b7360a0e087 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -30,7 +30,7 @@ fn main() { // END RUST SOURCE // START rustc.{{impl}}-foo.EraseRegions.after.mir // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[317d]::{{impl}}[0]::foo[0] }, BrAnon(0)) Test, _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[317d]::{{impl}}[0]::foo[0] }, BrAnon(1)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/0:5 ~ validate_1[317d]::{{impl}}[0]::foo[0]), BrAnon(0)) Test, _2: &ReFree(DefId(0/0:5 ~ validate_1[317d]::{{impl}}[0]::foo[0]), BrAnon(1)) mut i32]); // ... // return; // } @@ -62,7 +62,7 @@ fn main() { // fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[317d]::main[0]::{{closure}}[0] }, BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 }))), [(*_2): i32]); // _3 = &ReErased (*_2); diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs index 80224ddc586..39438af4b44 100644 --- a/src/test/mir-opt/validate_4.rs +++ b/src/test/mir-opt/validate_4.rs @@ -51,8 +51,8 @@ fn main() { // fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[317d]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]); -// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[317d]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(22)], _2: *mut i32]); +// Validate(Release, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(22)], _2: *mut i32]); // (*_2) = const 23i32; // return; // } @@ -62,8 +62,8 @@ fn main() { // fn test(_1: &ReErased mut i32) -> () { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[317d]::test[0] }, BrAnon(0)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[317d]::test[0] }, BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); +// Validate(Release, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); // ... // _2 = const write_42(_3) -> bb1; // } @@ -78,8 +78,8 @@ fn main() { // fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrAnon(0)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); +// Validate(Release, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // ... // _0 = const write_42(_3) -> bb1; diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index a945b7dbc5f..043338c8089 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -37,7 +37,7 @@ fn main() { // fn test(_1: &ReErased mut i32) -> () { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_5[317d]::test[0] }, BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_5[317d]::test[0]), BrAnon(0)) mut i32]); // ... // Validate(Release, [_2: bool, _3: *mut i32]); // _2 = const write_42(_3) -> bb1; @@ -49,7 +49,7 @@ fn main() { // fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[317d]::main[0]::{{closure}}[0] }, BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // StorageLive(_4); // Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]); diff --git a/src/test/run-make/hir-tree/Makefile b/src/test/run-make/hir-tree/Makefile new file mode 100644 index 00000000000..59e4ae8a30d --- /dev/null +++ b/src/test/run-make/hir-tree/Makefile @@ -0,0 +1,9 @@ +-include ../tools.mk + +# Test that hir-tree output doens't crash and includes +# the string constant we would expect to see. + +all: + $(RUSTC) -o $(TMPDIR)/input.hir -Z unstable-options \ + --unpretty=hir-tree input.rs + grep '"Hello, Rustaceans!\\n"' $(TMPDIR)/input.hir diff --git a/src/test/run-pass/issue-21410.rs b/src/test/run-make/hir-tree/input.rs index bc525ba54c3..12adc083bcd 100644 --- a/src/test/run-pass/issue-21410.rs +++ b/src/test/run-make/hir-tree/input.rs @@ -1,4 +1,4 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn g<F>(_: F) where F: FnOnce(Option<F>) {} - fn main() { - g(|_| { }); + println!("Hello, Rustaceans!"); } diff --git a/src/test/run-make/many-crates-but-no-match/Makefile b/src/test/run-make/many-crates-but-no-match/Makefile index 239b689b526..0371dff1585 100644 --- a/src/test/run-make/many-crates-but-no-match/Makefile +++ b/src/test/run-make/many-crates-but-no-match/Makefile @@ -29,6 +29,5 @@ all: $(RUSTC) -L $(A2) -L $(A3) crateC.rs >$(LOG) 2>&1 || true grep "found possibly newer version of crate \`crateA\` which \`crateB\` depends on" $(LOG) grep "note: perhaps that crate needs to be recompiled?" $(LOG) - grep "note: crate \`crateA\` path #1:" $(LOG) - grep "note: crate \`crateA\` path #2:" $(LOG) - grep "note: crate \`crateB\` path #1:" $(LOG) + grep "crate \`crateA\`:" $(LOG) # this will match two entries + grep "crate \`crateB\`:" $(LOG) diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile index b18dd1d45ed..fa6f7626fcc 100644 --- a/src/test/run-make/sanitizer-leak/Makefile +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -1,10 +1,19 @@ -include ../tools.mk +LOG := $(TMPDIR)/log.txt + +# FIXME(#46126) ThinLTO for libstd broke this test +ifeq (1,0) all: ifeq ($(TARGET),x86_64-unknown-linux-gnu) ifdef SANITIZER_SUPPORT $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan - $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' + $(TMPDIR)/leak 2>&1 | tee $(LOG) + grep -q 'detected memory leaks' $(LOG) +endif endif + +else +all: endif diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs new file mode 100644 index 00000000000..1e19e7f6a13 --- /dev/null +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -0,0 +1,97 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(conservative_impl_trait)] +#![allow(warnings)] + +use std::fmt::Debug; + +fn any_lifetime<'a>() -> &'a u32 { &5 } + +fn static_lifetime() -> &'static u32 { &5 } + +fn any_lifetime_as_static_impl_trait() -> impl Debug { + any_lifetime() +} + +fn lifetimes_as_static_impl_trait() -> impl Debug { + static_lifetime() +} + +fn no_params_or_lifetimes_is_static() -> impl Debug + 'static { + lifetimes_as_static_impl_trait() +} + +fn static_input_type_is_static<T: Debug + 'static>(x: T) -> impl Debug + 'static { x } + +fn type_outlives_reference_lifetime<'a, T: Debug>(x: &'a T) -> impl Debug + 'a { x } + +trait SingleRegionTrait<'a> {} +impl<'a> SingleRegionTrait<'a> for u32 {} + +fn simple_type_hrtb<'b>() -> impl for<'a> SingleRegionTrait<'a> { 5 } +fn closure_hrtb() -> impl for<'a> Fn(&'a u32) { |_| () } + +fn mixed_lifetimes<'a>() -> impl for<'b: 'a> Fn(&'b u32) { |_| () } +fn mixed_as_static() -> impl Fn(&'static u32) { mixed_lifetimes() } + +trait MultiRegionTrait<'a, 'b>: Debug {} + +#[derive(Debug)] +struct MultiRegionStruct<'a, 'b>(&'a u32, &'b u32); +impl<'a, 'b> MultiRegionTrait<'a, 'b> for MultiRegionStruct<'a, 'b> {} + +#[derive(Debug)] +struct NoRegionStruct; +impl<'a, 'b> MultiRegionTrait<'a, 'b> for NoRegionStruct {} + +fn finds_least_region<'a: 'b, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound<'a: 'b, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound_even_without_least_region<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + NoRegionStruct +} + +/* FIXME: `impl Trait<'a> + 'b` should live as long as 'b, even if 'b outlives 'a +fn outlives_bounds_even_with_contained_regions<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug + 'b +{ + finds_explicit_bound_even_without_least_region(x, y) +} +*/ + +fn unnamed_lifetimes_arent_contained_in_impl_trait_and_will_unify<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug +{ + fn deref<'lt>(x: &'lt u32) -> impl Debug { *x } + + if true { deref(x) } else { deref(y) } +} + +fn can_add_region_bound_to_static_type<'a, 'b>(_: &'a u32) -> impl Debug + 'a { 5 } + +struct MyVec(Vec<Vec<u8>>); + +impl<'unnecessary_lifetime> MyVec { + fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator<Item = &'s u8> { + self.0.iter().flat_map(|inner_vec| inner_vec.iter()) + } +} + +fn main() {} diff --git a/src/test/run-pass/in-band-lifetimes.rs b/src/test/run-pass/in-band-lifetimes.rs new file mode 100644 index 00000000000..95cc3c3759e --- /dev/null +++ b/src/test/run-pass/in-band-lifetimes.rs @@ -0,0 +1,104 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes, universal_impl_trait, conservative_impl_trait)] + +fn foo(x: &'x u8) -> &'x u8 { x } +fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x } + +fn check_in_band_can_be_late_bound() { + let _: for<'x> fn(&'x u8, &u8) -> &'x u8 = foo2; +} + +struct ForInherentNoParams; + +impl ForInherentNoParams { + fn foo(x: &'a u32, y: &u32) -> &'a u32 { x } +} + +struct X<'a>(&'a u8); + +impl<'a> X<'a> { + fn inner(&self) -> &'a u8 { + self.0 + } + + fn same_lifetime_as_parameter(&mut self, x: &'a u8) { + self.0 = x; + } +} + +impl X<'b> { + fn inner_2(&self) -> &'b u8 { + self.0 + } + + fn reference_already_introduced_in_band_from_method_with_explicit_binders<'a>( + &'b self, x: &'a u32 + ) {} +} + +struct Y<T>(T); + +impl Y<&'a u8> { + fn inner(&self) -> &'a u8 { + self.0 + } +} + +trait MyTrait<'a> { + fn my_lifetime(&self) -> &'a u8; + fn any_lifetime() -> &'b u8; + fn borrowed_lifetime(&'b self) -> &'b u8; + fn default_impl(&self, x: &'b u32, y: &u32) -> &'b u32 { x } + fn in_band_def_explicit_impl(&self, x: &'b u8); +} + +impl MyTrait<'a> for Y<&'a u8> { + fn my_lifetime(&self) -> &'a u8 { self.0 } + fn any_lifetime() -> &'b u8 { &0 } + fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } + fn in_band_def_explicit_impl<'b>(&self, x: &'b u8) {} +} + +fn test_hrtb_defined_lifetime_where<F>(_: F) where for<'a> F: Fn(&'a u8) {} +fn test_hrtb_defined_lifetime_polytraitref<F>(_: F) where F: for<'a> Fn(&'a u8) {} + +fn reference_in_band_from_locals(x: &'test u32) -> &'test u32 { + let y: &'test u32 = x; + y +} + +fn in_generics_in_band<T: MyTrait<'a>>(x: &T) {} +fn where_clause_in_band<T>(x: &T) where T: MyTrait<'a> {} +fn impl_trait_in_band(x: &impl MyTrait<'a>) {} + +// Tests around using in-band lifetimes within existential traits. + +trait FunkyTrait<'a> { } +impl<'a, T> FunkyTrait<'a> for T { } +fn existential_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { + x +} +fn existential_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { + x +} +fn existential_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { + x +} +fn existential_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { + x +} +fn existential_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { + x +} + +fn main() {} diff --git a/src/test/run-pass/lto-still-runs-thread-dtors.rs b/src/test/run-pass/lto-still-runs-thread-dtors.rs new file mode 100644 index 00000000000..91fb7aa51d4 --- /dev/null +++ b/src/test/run-pass/lto-still-runs-thread-dtors.rs @@ -0,0 +1,41 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C lto +// no-prefer-dynamic +// ignore-emscripten no threads support + +use std::thread; + +static mut HIT: usize = 0; + +thread_local!(static A: Foo = Foo); + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { + HIT += 1; + } + } +} + +fn main() { + unsafe { + assert_eq!(HIT, 0); + thread::spawn(|| { + assert_eq!(HIT, 0); + A.with(|_| ()); + assert_eq!(HIT, 0); + }).join().unwrap(); + assert_eq!(HIT, 1); + } +} diff --git a/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs b/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs new file mode 100644 index 00000000000..172c34e79d2 --- /dev/null +++ b/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs @@ -0,0 +1,36 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(crate_in_paths)] + +use crate::m::f; + +mod m { + pub fn f() -> u8 { 1 } + pub fn g() -> u8 { 2 } + + // OK, visibilities are implicitly absolute like imports + pub(in crate::m) struct S; +} + +mod n +{ + use crate::m::f; + pub fn check() { + assert_eq!(f(), 1); + assert_eq!(::crate::m::g(), 2); + } +} + +fn main() { + assert_eq!(f(), 1); + assert_eq!(::crate::m::g(), 2); + n::check(); +} diff --git a/src/test/rustdoc/auxiliary/external-cross-doc.md b/src/test/rustdoc/auxiliary/external-cross-doc.md new file mode 100644 index 00000000000..8b4e6edc699 --- /dev/null +++ b/src/test/rustdoc/auxiliary/external-cross-doc.md @@ -0,0 +1,4 @@ +# Cross-crate imported docs + +This file is to make sure `#[doc(include="file.md")]` works when you re-export an item with included +docs. diff --git a/src/test/rustdoc/auxiliary/external-cross.rs b/src/test/rustdoc/auxiliary/external-cross.rs new file mode 100644 index 00000000000..cb14fec7abe --- /dev/null +++ b/src/test/rustdoc/auxiliary/external-cross.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(external_doc)] + +#[doc(include="external-cross-doc.md")] +pub struct NeedMoreDocs; diff --git a/src/test/rustdoc/auxiliary/external-doc.md b/src/test/rustdoc/auxiliary/external-doc.md new file mode 100644 index 00000000000..38478c1635a --- /dev/null +++ b/src/test/rustdoc/auxiliary/external-doc.md @@ -0,0 +1,3 @@ +# External Docs + +This file is here to test the `#[doc(include="file")]` attribute. diff --git a/src/test/rustdoc/doc-spotlight.rs b/src/test/rustdoc/doc-spotlight.rs new file mode 100644 index 00000000000..a570aa2d398 --- /dev/null +++ b/src/test/rustdoc/doc-spotlight.rs @@ -0,0 +1,46 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(doc_spotlight)] + +pub struct Wrapper<T> { + inner: T, +} + +impl<T: SomeTrait> SomeTrait for Wrapper<T> {} + +#[doc(spotlight)] +pub trait SomeTrait { + // @has doc_spotlight/trait.SomeTrait.html + // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>' + fn wrap_me(self) -> Wrapper<Self> where Self: Sized { + Wrapper { + inner: self, + } + } +} + +pub struct SomeStruct; +impl SomeTrait for SomeStruct {} + +impl SomeStruct { + // @has doc_spotlight/struct.SomeStruct.html + // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' + // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>' + pub fn new() -> SomeStruct { + SomeStruct + } +} + +// @has doc_spotlight/fn.bare_fn.html +// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' +pub fn bare_fn() -> SomeStruct { + SomeStruct +} diff --git a/src/test/rustdoc/external-cross.rs b/src/test/rustdoc/external-cross.rs new file mode 100644 index 00000000000..f4a59cee32d --- /dev/null +++ b/src/test/rustdoc/external-cross.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:external-cross.rs +// ignore-cross-compile + +#![crate_name="host"] + +extern crate external_cross; + +// @has host/struct.NeedMoreDocs.html +// @has - '//h1' 'Cross-crate imported docs' +pub use external_cross::NeedMoreDocs; diff --git a/src/test/rustdoc/external-doc.rs b/src/test/rustdoc/external-doc.rs new file mode 100644 index 00000000000..07e784a6ccf --- /dev/null +++ b/src/test/rustdoc/external-doc.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(external_doc)] + +// @has external_doc/struct.CanHasDocs.html +// @has - '//h1' 'External Docs' +// @has - '//h2' 'Inline Docs' +#[doc(include = "auxiliary/external-doc.md")] +/// ## Inline Docs +pub struct CanHasDocs; diff --git a/src/test/rustdoc/issue-42760.rs b/src/test/rustdoc/issue-42760.rs new file mode 100644 index 00000000000..f5f5c4f97fd --- /dev/null +++ b/src/test/rustdoc/issue-42760.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// @has issue_42760/struct.NonGen.html +// @has - '//h1' 'Example' + +/// Item docs. +/// +#[doc="Hello there!"] +/// +/// # Example +/// +/// ```rust +/// // some code here +/// ``` +pub struct NonGen; diff --git a/src/test/rustdoc/negative-impl-sidebar.rs b/src/test/rustdoc/negative-impl-sidebar.rs new file mode 100644 index 00000000000..dc27b26241d --- /dev/null +++ b/src/test/rustdoc/negative-impl-sidebar.rs @@ -0,0 +1,19 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] +#![crate_name = "foo"] + +pub struct Foo; + +// @has foo/struct.Foo.html +// @has - '//*[@class="sidebar-title"][@href="#implementations"]' 'Trait Implementations' +// @has - '//*[@class="sidebar-links"]/a' '!Sync' +impl !Sync for Foo {} diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.rs b/src/test/ui-fulldeps/custom-derive/issue-36935.rs index 2231c3c2422..4fd87632067 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.rs +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.rs @@ -15,7 +15,7 @@ #[macro_use] extern crate plugin; -#[derive(Foo, Bar)] +#[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked struct Baz { a: i32, b: i32, diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr index 46cc7a42b04..55848c6553c 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr @@ -1,7 +1,7 @@ error: proc-macro derive panicked --> $DIR/issue-36935.rs:18:15 | -18 | #[derive(Foo, Bar)] +18 | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked | ^^^ | = help: message: lolnope diff --git a/src/test/ui/span/loan-extend.rs b/src/test/ui-fulldeps/issue-44953/issue-44953.rs index a4b951daab4..de798e2cf0b 100644 --- a/src/test/ui/span/loan-extend.rs +++ b/src/test/ui-fulldeps/issue-44953/issue-44953.rs @@ -7,18 +7,14 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. +// + -#![feature(conservative_impl_trait)] +#![feature(proc_macro)] +#![allow(unused_macros)] -// Helper creating a fake borrow, captured by the impl Trait. -fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () } +#[macro_use] extern crate log; //~ ERROR use of unstable library feature -fn main() { - let long; - let mut short = 0; - long = borrow(&mut short); - //~^ NOTE borrow occurs here +pub fn main() { + info!("This is a log message."); } -//~^ ERROR `short` does not live long enough -//~| NOTE `short` dropped here while still borrowed -//~| NOTE values in a scope are dropped in the opposite order they are created diff --git a/src/test/ui-fulldeps/issue-44953/issue-44953.stderr b/src/test/ui-fulldeps/issue-44953/issue-44953.stderr new file mode 100644 index 00000000000..4493ec14024 --- /dev/null +++ b/src/test/ui-fulldeps/issue-44953/issue-44953.stderr @@ -0,0 +1,19 @@ +error: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812) + --> $DIR/issue-44953.rs:16:14 + | +16 | #[macro_use] extern crate log; //~ ERROR use of unstable library feature + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(rustc_private)] to the crate attributes to enable + +error: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812) + --> $DIR/issue-44953.rs:19:5 + | +19 | info!("This is a log message."); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(rustc_private)] to the crate attributes to enable + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.rs b/src/test/ui-fulldeps/proc-macro/three-equals.rs index 016e05c51f5..ef2d1605290 100644 --- a/src/test/ui-fulldeps/proc-macro/three-equals.rs +++ b/src/test/ui-fulldeps/proc-macro/three-equals.rs @@ -22,17 +22,17 @@ fn main() { three_equals!(===); // Need exactly three equals. - three_equals!(==); + three_equals!(==); //~ ERROR found 2 equal signs, need exactly 3 // Need exactly three equals. - three_equals!(=====); + three_equals!(=====); //~ ERROR expected EOF // Only equals accepted. - three_equals!(abc); + three_equals!(abc); //~ ERROR expected `=` // Only equals accepted. - three_equals!(!!); + three_equals!(!!); //~ ERROR expected `=` // Only three characters expected. - three_equals!(===a); + three_equals!(===a); //~ ERROR expected EOF } diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.stderr b/src/test/ui-fulldeps/proc-macro/three-equals.stderr index 1afe0be2800..0ffaf161078 100644 --- a/src/test/ui-fulldeps/proc-macro/three-equals.stderr +++ b/src/test/ui-fulldeps/proc-macro/three-equals.stderr @@ -1,7 +1,7 @@ error: found 2 equal signs, need exactly 3 --> $DIR/three-equals.rs:25:5 | -25 | three_equals!(==); +25 | three_equals!(==); //~ ERROR found 2 equal signs, need exactly 3 | ^^^^^^^^^^^^^^^^^^ | = help: input must be: `===` @@ -9,38 +9,38 @@ error: found 2 equal signs, need exactly 3 error: expected EOF, found `=`. --> $DIR/three-equals.rs:28:21 | -28 | three_equals!(=====); +28 | three_equals!(=====); //~ ERROR expected EOF | ^^ | note: last good input was here --> $DIR/three-equals.rs:28:21 | -28 | three_equals!(=====); +28 | three_equals!(=====); //~ ERROR expected EOF | ^^ = help: input must be: `===` error: expected `=`, found `abc`. --> $DIR/three-equals.rs:31:19 | -31 | three_equals!(abc); +31 | three_equals!(abc); //~ ERROR expected `=` | ^^^ error: expected `=`, found `!`. --> $DIR/three-equals.rs:34:19 | -34 | three_equals!(!!); +34 | three_equals!(!!); //~ ERROR expected `=` | ^ error: expected EOF, found `a`. --> $DIR/three-equals.rs:37:22 | -37 | three_equals!(===a); +37 | three_equals!(===a); //~ ERROR expected EOF | ^ | note: last good input was here --> $DIR/three-equals.rs:37:21 | -37 | three_equals!(===a); +37 | three_equals!(===a); //~ ERROR expected EOF | ^ = help: input must be: `===` diff --git a/src/test/ui-fulldeps/resolve-error.rs b/src/test/ui-fulldeps/resolve-error.rs index dfaa1d7a32e..ae94a7f13e2 100644 --- a/src/test/ui-fulldeps/resolve-error.rs +++ b/src/test/ui-fulldeps/resolve-error.rs @@ -35,29 +35,39 @@ macro_rules! attr_proc_mac { } #[derive(FooWithLongNan)] +//~^ ERROR cannot find struct Foo; #[attr_proc_macra] +//~^ ERROR cannot find struct Bar; #[FooWithLongNan] +//~^ ERROR cannot find struct Asdf; #[derive(Dlone)] +//~^ ERROR cannot find struct A; #[derive(Dlona)] +//~^ ERROR cannot find struct B; #[derive(attr_proc_macra)] +//~^ ERROR cannot find struct C; fn main() { FooWithLongNama!(); + //~^ ERROR cannot find attr_proc_macra!(); + //~^ ERROR cannot find Dlona!(); + //~^ ERROR cannot find bang_proc_macrp!(); + //~^ ERROR cannot find } diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui-fulldeps/resolve-error.stderr index 754f6bc4f1c..be7ebae70ad 100644 --- a/src/test/ui-fulldeps/resolve-error.stderr +++ b/src/test/ui-fulldeps/resolve-error.stderr @@ -5,57 +5,57 @@ error: cannot find derive macro `FooWithLongNan` in this scope | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` error: cannot find attribute macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:40:3 + --> $DIR/resolve-error.rs:41:3 | -40 | #[attr_proc_macra] +41 | #[attr_proc_macra] | ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro` error: cannot find attribute macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:43:3 + --> $DIR/resolve-error.rs:45:3 | -43 | #[FooWithLongNan] +45 | #[FooWithLongNan] | ^^^^^^^^^^^^^^ error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:46:10 + --> $DIR/resolve-error.rs:49:10 | -46 | #[derive(Dlone)] +49 | #[derive(Dlone)] | ^^^^^ help: try: `Clone` error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:49:10 + --> $DIR/resolve-error.rs:53:10 | -49 | #[derive(Dlona)] +53 | #[derive(Dlona)] | ^^^^^ help: try: `Clona` error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:52:10 + --> $DIR/resolve-error.rs:57:10 | -52 | #[derive(attr_proc_macra)] +57 | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find macro `FooWithLongNama!` in this scope - --> $DIR/resolve-error.rs:56:5 + --> $DIR/resolve-error.rs:62:5 | -56 | FooWithLongNama!(); +62 | FooWithLongNama!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam!` error: cannot find macro `attr_proc_macra!` in this scope - --> $DIR/resolve-error.rs:58:5 + --> $DIR/resolve-error.rs:65:5 | -58 | attr_proc_macra!(); +65 | attr_proc_macra!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac!` error: cannot find macro `Dlona!` in this scope - --> $DIR/resolve-error.rs:60:5 + --> $DIR/resolve-error.rs:68:5 | -60 | Dlona!(); +68 | Dlona!(); | ^^^^^ error: cannot find macro `bang_proc_macrp!` in this scope - --> $DIR/resolve-error.rs:62:5 + --> $DIR/resolve-error.rs:71:5 | -62 | bang_proc_macrp!(); +71 | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro!` error: aborting due to 10 previous errors diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.rs b/src/test/ui/anonymous-higher-ranked-lifetime.rs index f2d04c16d99..295e3d1a735 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.rs +++ b/src/test/ui/anonymous-higher-ranked-lifetime.rs @@ -9,17 +9,17 @@ // except according to those terms. fn main() { - f1(|_: (), _: ()| {}); - f2(|_: (), _: ()| {}); - f3(|_: (), _: ()| {}); - f4(|_: (), _: ()| {}); - f5(|_: (), _: ()| {}); - g1(|_: (), _: ()| {}); - g2(|_: (), _: ()| {}); - g3(|_: (), _: ()| {}); - g4(|_: (), _: ()| {}); - h1(|_: (), _: (), _: (), _: ()| {}); - h2(|_: (), _: (), _: (), _: ()| {}); + f1(|_: (), _: ()| {}); //~ ERROR type mismatch + f2(|_: (), _: ()| {}); //~ ERROR type mismatch + f3(|_: (), _: ()| {}); //~ ERROR type mismatch + f4(|_: (), _: ()| {}); //~ ERROR type mismatch + f5(|_: (), _: ()| {}); //~ ERROR type mismatch + g1(|_: (), _: ()| {}); //~ ERROR type mismatch + g2(|_: (), _: ()| {}); //~ ERROR type mismatch + g3(|_: (), _: ()| {}); //~ ERROR type mismatch + g4(|_: (), _: ()| {}); //~ ERROR type mismatch + h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch } // Basic diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index f962b772203..6f684f13e6f 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -1,7 +1,7 @@ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 | -12 | f1(|_: (), _: ()| {}); +12 | f1(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` @@ -11,7 +11,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5 | -13 | f2(|_: (), _: ()| {}); +13 | f2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` @@ -21,7 +21,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 | -14 | f3(|_: (), _: ()| {}); +14 | f3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` @@ -31,7 +31,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5 | -15 | f4(|_: (), _: ()| {}); +15 | f4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` @@ -41,7 +41,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 | -16 | f5(|_: (), _: ()| {}); +16 | f5(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` @@ -51,7 +51,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5 | -17 | g1(|_: (), _: ()| {}); +17 | g1(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _` @@ -61,7 +61,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 | -18 | g2(|_: (), _: ()| {}); +18 | g2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` @@ -71,7 +71,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5 | -19 | g3(|_: (), _: ()| {}); +19 | g3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _` @@ -81,7 +81,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 | -20 | g4(|_: (), _: ()| {}); +20 | g4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ ----------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` @@ -91,7 +91,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5 | -21 | h1(|_: (), _: (), _: (), _: ()| {}); +21 | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _` | | | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` @@ -101,7 +101,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 | -22 | h2(|_: (), _: (), _: (), _: ()| {}); +22 | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _` | | | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` diff --git a/src/test/ui/block-result/issue-11714.rs b/src/test/ui/block-result/issue-11714.rs index 192f78e41cb..255eb771694 100644 --- a/src/test/ui/block-result/issue-11714.rs +++ b/src/test/ui/block-result/issue-11714.rs @@ -11,7 +11,7 @@ fn blah() -> i32 { //~ ERROR mismatched types 1 - ; //~ HELP consider removing this semicolon: + ; //~ HELP consider removing this semicolon } fn main() { } diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 376834beab0..4daf40e6172 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | __________________^ 12 | | 1 13 | | -14 | | ; //~ HELP consider removing this semicolon: +14 | | ; //~ HELP consider removing this semicolon | | - help: consider removing this semicolon 15 | | } | |_^ expected i32, found () diff --git a/src/test/ui/block-result/issue-3563.rs b/src/test/ui/block-result/issue-3563.rs index 7928c04b9df..31a363a6b86 100644 --- a/src/test/ui/block-result/issue-3563.rs +++ b/src/test/ui/block-result/issue-3563.rs @@ -12,7 +12,6 @@ trait A { fn a(&self) { || self.b() //~^ ERROR no method named `b` found for type `&Self` in the current scope - //~| ERROR mismatched types } } fn main() {} diff --git a/src/test/ui/block-result/issue-3563.stderr b/src/test/ui/block-result/issue-3563.stderr index e3f0df6fb5f..c3d5f21b0a5 100644 --- a/src/test/ui/block-result/issue-3563.stderr +++ b/src/test/ui/block-result/issue-3563.stderr @@ -6,16 +6,5 @@ error[E0599]: no method named `b` found for type `&Self` in the current scope | = help: did you mean `a`? -error[E0308]: mismatched types - --> $DIR/issue-3563.rs:13:9 - | -12 | fn a(&self) { - | - possibly return type missing here? -13 | || self.b() - | ^^^^^^^^^^^ expected (), found closure - | - = note: expected type `()` - found type `[closure@$DIR/issue-3563.rs:13:9: 13:20 self:_]` - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/block-result/unexpected-return-on-unit.rs b/src/test/ui/block-result/unexpected-return-on-unit.rs index 291b7a16f14..3cf76365c77 100644 --- a/src/test/ui/block-result/unexpected-return-on-unit.rs +++ b/src/test/ui/block-result/unexpected-return-on-unit.rs @@ -16,7 +16,7 @@ fn foo() -> usize { } fn bar() { - foo() + foo() //~ ERROR mismatched types } fn main() { diff --git a/src/test/ui/block-result/unexpected-return-on-unit.stderr b/src/test/ui/block-result/unexpected-return-on-unit.stderr index f0528838152..3881bb46258 100644 --- a/src/test/ui/block-result/unexpected-return-on-unit.stderr +++ b/src/test/ui/block-result/unexpected-return-on-unit.stderr @@ -1,14 +1,14 @@ error[E0308]: mismatched types --> $DIR/unexpected-return-on-unit.rs:19:5 | -19 | foo() +19 | foo() //~ ERROR mismatched types | ^^^^^ expected (), found usize | = note: expected type `()` found type `usize` help: try adding a semicolon | -19 | foo(); +19 | foo(); //~ ERROR mismatched types | ^ help: try adding a return type | diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.rs b/src/test/ui/borrowck/borrowck-closures-two-mut.rs index 182b3d75442..6d7a84ebc93 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.rs +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.rs @@ -22,6 +22,7 @@ fn a() { let mut x = 3; let c1 = to_fn_mut(|| x = 4); let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once + //~| ERROR cannot borrow `x` as mutable more than once } fn set(x: &mut isize) { @@ -32,12 +33,14 @@ fn b() { let mut x = 3; let c1 = to_fn_mut(|| set(&mut x)); let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + //~| ERROR cannot borrow `x` as mutable more than once } fn c() { let mut x = 3; let c1 = to_fn_mut(|| x = 5); let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + //~| ERROR cannot borrow `x` as mutable more than once } fn d() { @@ -45,6 +48,7 @@ fn d() { let c1 = to_fn_mut(|| x = 5); let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) //~^ ERROR cannot borrow `x` as mutable more than once + //~| ERROR cannot borrow `x` as mutable more than once } fn g() { @@ -56,6 +60,7 @@ fn g() { let c1 = to_fn_mut(|| set(&mut *x.f)); let c2 = to_fn_mut(|| set(&mut *x.f)); //~^ ERROR cannot borrow `x` as mutable more than once + //~| ERROR cannot borrow `x` as mutable more than once } fn main() { diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index fc8a7f2ab60..0ec744f4a07 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -9,65 +9,68 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -25 | } +25 | //~| ERROR cannot borrow `x` as mutable more than once +26 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:34:24 + --> $DIR/borrowck-closures-two-mut.rs:35:24 | -33 | let c1 = to_fn_mut(|| set(&mut x)); +34 | let c1 = to_fn_mut(|| set(&mut x)); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -34 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once +35 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -35 | } +36 | //~| ERROR cannot borrow `x` as mutable more than once +37 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:40:24 + --> $DIR/borrowck-closures-two-mut.rs:42:24 | -39 | let c1 = to_fn_mut(|| x = 5); +41 | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -40 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once +42 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -41 | } +43 | //~| ERROR cannot borrow `x` as mutable more than once +44 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:46:24 + --> $DIR/borrowck-closures-two-mut.rs:49:24 | -45 | let c1 = to_fn_mut(|| x = 5); +48 | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -46 | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) +49 | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -47 | //~^ ERROR cannot borrow `x` as mutable more than once -48 | } +... +52 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:57:24 + --> $DIR/borrowck-closures-two-mut.rs:61:24 | -56 | let c1 = to_fn_mut(|| set(&mut *x.f)); +60 | let c1 = to_fn_mut(|| set(&mut *x.f)); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -57 | let c2 = to_fn_mut(|| set(&mut *x.f)); +61 | let c2 = to_fn_mut(|| set(&mut *x.f)); | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -58 | //~^ ERROR cannot borrow `x` as mutable more than once -59 | } +... +64 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) @@ -81,65 +84,68 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -25 | } +25 | //~| ERROR cannot borrow `x` as mutable more than once +26 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:34:24 + --> $DIR/borrowck-closures-two-mut.rs:35:24 | -33 | let c1 = to_fn_mut(|| set(&mut x)); +34 | let c1 = to_fn_mut(|| set(&mut x)); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -34 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once +35 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -35 | } +36 | //~| ERROR cannot borrow `x` as mutable more than once +37 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:40:24 + --> $DIR/borrowck-closures-two-mut.rs:42:24 | -39 | let c1 = to_fn_mut(|| x = 5); +41 | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -40 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once +42 | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -41 | } +43 | //~| ERROR cannot borrow `x` as mutable more than once +44 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:46:24 + --> $DIR/borrowck-closures-two-mut.rs:49:24 | -45 | let c1 = to_fn_mut(|| x = 5); +48 | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -46 | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) +49 | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -47 | //~^ ERROR cannot borrow `x` as mutable more than once -48 | } +... +52 | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:57:24 + --> $DIR/borrowck-closures-two-mut.rs:61:24 | -56 | let c1 = to_fn_mut(|| set(&mut *x.f)); +60 | let c1 = to_fn_mut(|| set(&mut *x.f)); | -- - previous borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here -57 | let c2 = to_fn_mut(|| set(&mut *x.f)); +61 | let c2 = to_fn_mut(|| set(&mut *x.f)); | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -58 | //~^ ERROR cannot borrow `x` as mutable more than once -59 | } +... +64 | } | - first borrow ends here error: aborting due to 10 previous errors diff --git a/src/test/ui/borrowck/borrowck-in-static.rs b/src/test/ui/borrowck/borrowck-in-static.rs index 9244c12347d..b30234811ac 100644 --- a/src/test/ui/borrowck/borrowck-in-static.rs +++ b/src/test/ui/borrowck/borrowck-in-static.rs @@ -11,8 +11,9 @@ // check that borrowck looks inside consts/statics static FN : &'static (Fn() -> (Box<Fn()->Box<i32>>) + Sync) = &|| { - let x = Box::new(0); //~ NOTE moved + let x = Box::new(0); //~ NOTE captured outer variable Box::new(|| x) //~ ERROR cannot move out of captured outer variable + //~^ NOTE cannot move out of captured outer variable }; fn main() { diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr index 6083a82b1b6..92ca36e117e 100644 --- a/src/test/ui/borrowck/borrowck-in-static.stderr +++ b/src/test/ui/borrowck/borrowck-in-static.stderr @@ -1,7 +1,7 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure --> $DIR/borrowck-in-static.rs:15:17 | -14 | let x = Box::new(0); //~ NOTE moved +14 | let x = Box::new(0); //~ NOTE captured outer variable | - captured outer variable 15 | Box::new(|| x) //~ ERROR cannot move out of captured outer variable | ^ cannot move out of captured outer variable in an `Fn` closure diff --git a/src/test/ui/borrowck/borrowck-reinit.rs b/src/test/ui/borrowck/borrowck-reinit.rs index 5547cb3ae52..e72eb7f03a6 100644 --- a/src/test/ui/borrowck/borrowck-reinit.rs +++ b/src/test/ui/borrowck/borrowck-reinit.rs @@ -15,5 +15,6 @@ fn main() { let _u = x; // error shouldn't note this move x = Box::new(1); drop(x); - let _ = (1,x); + let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) + //~^ ERROR use of moved value: `x` (Mir) } diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr index 767d65c1e60..12511030579 100644 --- a/src/test/ui/borrowck/borrowck-reinit.stderr +++ b/src/test/ui/borrowck/borrowck-reinit.stderr @@ -3,7 +3,7 @@ error[E0382]: use of moved value: `x` (Ast) | 17 | drop(x); | - value moved here -18 | let _ = (1,x); +18 | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) | ^ value used here after move | = note: move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait @@ -13,7 +13,7 @@ error[E0382]: use of moved value: `x` (Mir) | 17 | drop(x); | - value moved here -18 | let _ = (1,x); +18 | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) | ^ value use here after move error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.rs b/src/test/ui/borrowck/mut-borrow-in-loop.rs index addda427753..31b50d8e531 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.rs +++ b/src/test/ui/borrowck/mut-borrow-in-loop.rs @@ -17,20 +17,20 @@ struct FuncWrapper<'a, T : 'a> { impl<'a, T : 'a> FuncWrapper<'a, T> { fn in_loop(self, arg : &'a mut T) { loop { - (self.func)(arg) + (self.func)(arg) //~ ERROR cannot borrow } } fn in_while(self, arg : &'a mut T) { while true { - (self.func)(arg) + (self.func)(arg) //~ ERROR cannot borrow } } fn in_for(self, arg : &'a mut T) { let v : Vec<()> = vec![]; for _ in v.iter() { - (self.func)(arg) + (self.func)(arg) //~ ERROR cannot borrow } } } diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr index a34d524d28f..2b614561d82 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr @@ -1,7 +1,7 @@ error[E0499]: cannot borrow `*arg` as mutable more than once at a time --> $DIR/mut-borrow-in-loop.rs:20:25 | -20 | (self.func)(arg) +20 | (self.func)(arg) //~ ERROR cannot borrow | ^^^ mutable borrow starts here in previous iteration of loop 21 | } 22 | } @@ -10,7 +10,7 @@ error[E0499]: cannot borrow `*arg` as mutable more than once at a time error[E0499]: cannot borrow `*arg` as mutable more than once at a time --> $DIR/mut-borrow-in-loop.rs:26:25 | -26 | (self.func)(arg) +26 | (self.func)(arg) //~ ERROR cannot borrow | ^^^ mutable borrow starts here in previous iteration of loop 27 | } 28 | } @@ -19,7 +19,7 @@ error[E0499]: cannot borrow `*arg` as mutable more than once at a time error[E0499]: cannot borrow `*arg` as mutable more than once at a time --> $DIR/mut-borrow-in-loop.rs:33:25 | -33 | (self.func)(arg) +33 | (self.func)(arg) //~ ERROR cannot borrow | ^^^ mutable borrow starts here in previous iteration of loop 34 | } 35 | } diff --git a/src/test/ui/borrowck/mut-borrow-outside-loop.rs b/src/test/ui/borrowck/mut-borrow-outside-loop.rs index 97092b7f9d7..a1ab41bab33 100644 --- a/src/test/ui/borrowck/mut-borrow-outside-loop.rs +++ b/src/test/ui/borrowck/mut-borrow-outside-loop.rs @@ -14,13 +14,13 @@ fn main() { let mut void = (); let first = &mut void; - let second = &mut void; + let second = &mut void; //~ ERROR cannot borrow loop { let mut inner_void = (); let inner_first = &mut inner_void; - let inner_second = &mut inner_void; + let inner_second = &mut inner_void; //~ ERROR cannot borrow } } diff --git a/src/test/ui/borrowck/mut-borrow-outside-loop.stderr b/src/test/ui/borrowck/mut-borrow-outside-loop.stderr index 02b32dc363a..716edd21982 100644 --- a/src/test/ui/borrowck/mut-borrow-outside-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-outside-loop.stderr @@ -3,7 +3,7 @@ error[E0499]: cannot borrow `void` as mutable more than once at a time | 16 | let first = &mut void; | ---- first mutable borrow occurs here -17 | let second = &mut void; +17 | let second = &mut void; //~ ERROR cannot borrow | ^^^^ second mutable borrow occurs here ... 25 | } @@ -14,7 +14,7 @@ error[E0499]: cannot borrow `inner_void` as mutable more than once at a time | 22 | let inner_first = &mut inner_void; | ---------- first mutable borrow occurs here -23 | let inner_second = &mut inner_void; +23 | let inner_second = &mut inner_void; //~ ERROR cannot borrow | ^^^^^^^^^^ second mutable borrow occurs here 24 | } | - first borrow ends here diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs index 9c89c26de00..788d68caa52 100644 --- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs +++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs @@ -16,9 +16,10 @@ fn call<F>(f: F) where F : Fn() { } fn main() { - let y = vec![format!("World")]; //~ NOTE moved + let y = vec![format!("World")]; //~ NOTE captured outer variable call(|| { y.into_iter(); //~^ ERROR cannot move out of captured outer variable in an `Fn` closure + //~| NOTE cannot move out of }); } diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr index dbfcb2e0c2f..895ce1ba318 100644 --- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr +++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr @@ -1,7 +1,7 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:21:9 | -19 | let y = vec![format!("World")]; //~ NOTE moved +19 | let y = vec![format!("World")]; //~ NOTE captured outer variable | - captured outer variable 20 | call(|| { 21 | y.into_iter(); diff --git a/src/test/ui/cast-to-unsized-trait-object-suggestion.rs b/src/test/ui/cast-to-unsized-trait-object-suggestion.rs index c7934547982..010b5a1b106 100644 --- a/src/test/ui/cast-to-unsized-trait-object-suggestion.rs +++ b/src/test/ui/cast-to-unsized-trait-object-suggestion.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() { - &1 as Send; - Box::new(1) as Send; + &1 as Send; //~ ERROR cast to unsized + Box::new(1) as Send; //~ ERROR cast to unsized } diff --git a/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr b/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr index 4d4eb7b4ecf..55d41848b17 100644 --- a/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr +++ b/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr @@ -1,7 +1,7 @@ error[E0620]: cast to unsized type: `&{integer}` as `std::marker::Send` --> $DIR/cast-to-unsized-trait-object-suggestion.rs:12:5 | -12 | &1 as Send; +12 | &1 as Send; //~ ERROR cast to unsized | ^^^^^^---- | | | help: try casting to a reference instead: `&Send` @@ -9,7 +9,7 @@ error[E0620]: cast to unsized type: `&{integer}` as `std::marker::Send` error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `std::marker::Send` --> $DIR/cast-to-unsized-trait-object-suggestion.rs:13:5 | -13 | Box::new(1) as Send; +13 | Box::new(1) as Send; //~ ERROR cast to unsized | ^^^^^^^^^^^^^^^---- | | | help: try casting to a `Box` instead: `Box<Send>` diff --git a/src/test/ui/check_match/issue-35609.rs b/src/test/ui/check_match/issue-35609.rs index 6497f69035d..d52718b7bf4 100644 --- a/src/test/ui/check_match/issue-35609.rs +++ b/src/test/ui/check_match/issue-35609.rs @@ -17,36 +17,36 @@ struct S(Enum, ()); struct Sd { x: Enum, y: () } fn main() { - match (A, ()) { + match (A, ()) { //~ ERROR non-exhaustive (A, _) => {} } - match (A, A) { + match (A, A) { //~ ERROR non-exhaustive (_, A) => {} } - match ((A, ()), ()) { + match ((A, ()), ()) { //~ ERROR non-exhaustive ((A, ()), _) => {} } - match ((A, ()), A) { + match ((A, ()), A) { //~ ERROR non-exhaustive ((A, ()), _) => {} } - match ((A, ()), ()) { + match ((A, ()), ()) { //~ ERROR non-exhaustive ((A, _), _) => {} } - match S(A, ()) { + match S(A, ()) { //~ ERROR non-exhaustive S(A, _) => {} } - match (Sd { x: A, y: () }) { + match (Sd { x: A, y: () }) { //~ ERROR non-exhaustive Sd { x: A, y: _ } => {} } - match Some(A) { + match Some(A) { //~ ERROR non-exhaustive Some(A) => (), None => () } diff --git a/src/test/ui/check_match/issue-35609.stderr b/src/test/ui/check_match/issue-35609.stderr index 0aafe3f17b3..1fc1d05636e 100644 --- a/src/test/ui/check_match/issue-35609.stderr +++ b/src/test/ui/check_match/issue-35609.stderr @@ -1,49 +1,49 @@ error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered --> $DIR/issue-35609.rs:20:11 | -20 | match (A, ()) { +20 | match (A, ()) { //~ ERROR non-exhaustive | ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered --> $DIR/issue-35609.rs:24:11 | -24 | match (A, A) { +24 | match (A, A) { //~ ERROR non-exhaustive | ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:28:11 | -28 | match ((A, ()), ()) { +28 | match ((A, ()), ()) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:32:11 | -32 | match ((A, ()), A) { +32 | match ((A, ()), A) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:36:11 | -36 | match ((A, ()), ()) { +36 | match ((A, ()), ()) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered --> $DIR/issue-35609.rs:41:11 | -41 | match S(A, ()) { +41 | match S(A, ()) { //~ ERROR non-exhaustive | ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered --> $DIR/issue-35609.rs:45:11 | -45 | match (Sd { x: A, y: () }) { +45 | match (Sd { x: A, y: () }) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered --> $DIR/issue-35609.rs:49:11 | -49 | match Some(A) { +49 | match Some(A) { //~ ERROR non-exhaustive | ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered error: aborting due to 8 previous errors diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.rs b/src/test/ui/closure_context/issue-26046-fn-mut.rs index 5ed7ace5437..3b179a475e7 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.rs +++ b/src/test/ui/closure_context/issue-26046-fn-mut.rs @@ -11,7 +11,7 @@ fn foo() -> Box<Fn()> { let num = 5; - let closure = || { + let closure = || { //~ ERROR expected a closure that num += 1; }; diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr index 42fc2909dfb..82c83da4dae 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr @@ -1,7 +1,7 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` --> $DIR/issue-26046-fn-mut.rs:14:19 | -14 | let closure = || { +14 | let closure = || { //~ ERROR expected a closure that | ___________________^ 15 | | num += 1; 16 | | }; diff --git a/src/test/ui/closure_context/issue-26046-fn-once.rs b/src/test/ui/closure_context/issue-26046-fn-once.rs index de06de530c6..cf15985ee83 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.rs +++ b/src/test/ui/closure_context/issue-26046-fn-once.rs @@ -11,7 +11,7 @@ fn get_closure() -> Box<Fn() -> Vec<u8>> { let vec = vec![1u8, 2u8]; - let closure = move || { + let closure = move || { //~ ERROR expected a closure vec }; diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr index 7bfe72d3d6c..0bc84872dde 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr @@ -1,7 +1,7 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/issue-26046-fn-once.rs:14:19 | -14 | let closure = move || { +14 | let closure = move || { //~ ERROR expected a closure | ___________________^ 15 | | vec 16 | | }; diff --git a/src/test/ui/closure_context/issue-42065.rs b/src/test/ui/closure_context/issue-42065.rs index 409964082f2..276c6a941b2 100644 --- a/src/test/ui/closure_context/issue-42065.rs +++ b/src/test/ui/closure_context/issue-42065.rs @@ -14,12 +14,13 @@ fn main() { let dict: HashMap<i32, i32> = HashMap::new(); let debug_dump_dict = || { for (key, value) in dict { + //~^ NOTE closure cannot be invoked more than once println!("{:?} - {:?}", key, value); } }; debug_dump_dict(); + //~^ NOTE: value moved here debug_dump_dict(); //~^ ERROR use of moved value: `debug_dump_dict` - //~| NOTE closure cannot be invoked more than once because it moves the - //~| variable `dict` out of its environment + //~| NOTE value used here after move } diff --git a/src/test/ui/closure_context/issue-42065.stderr b/src/test/ui/closure_context/issue-42065.stderr index c195940ade6..b31322f6d16 100644 --- a/src/test/ui/closure_context/issue-42065.stderr +++ b/src/test/ui/closure_context/issue-42065.stderr @@ -1,9 +1,10 @@ error[E0382]: use of moved value: `debug_dump_dict` - --> $DIR/issue-42065.rs:21:5 + --> $DIR/issue-42065.rs:23:5 | -20 | debug_dump_dict(); - | --------------- value moved here 21 | debug_dump_dict(); + | --------------- value moved here +22 | //~^ NOTE: value moved here +23 | debug_dump_dict(); | ^^^^^^^^^^^^^^^ value used here after move | note: closure cannot be invoked more than once because it moves the variable `dict` out of its environment diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index 87255dfe774..7faabc6b3a6 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -4,7 +4,7 @@ error: requires at least a format string argument 12 | format!(); | ^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: expected token: `,` --> $DIR/bad-format-args.rs:13:5 @@ -12,7 +12,7 @@ error: expected token: `,` 13 | format!("" 1); | ^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: expected token: `,` --> $DIR/bad-format-args.rs:14:5 @@ -20,7 +20,7 @@ error: expected token: `,` 14 | format!("", 1 1); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs index a72ad0351e3..532d173011d 100644 --- a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs +++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs @@ -11,6 +11,6 @@ #![allow(dead_code)] trait C {} -impl C { fn f() {} } +impl C { fn f() {} } //~ ERROR duplicate impl C { fn f() {} } fn main() { } diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr index 7f1ab929c6f..a7d52301476 100644 --- a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr +++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr @@ -1,7 +1,7 @@ error[E0592]: duplicate definitions with name `f` --> $DIR/coherence-overlapping-inherent-impl-trait.rs:14:10 | -14 | impl C { fn f() {} } +14 | impl C { fn f() {} } //~ ERROR duplicate | ^^^^^^^^^ duplicate definitions for `f` 15 | impl C { fn f() {} } | --------- other definition for `f` diff --git a/src/test/ui/codemap_tests/empty_span.rs b/src/test/ui/codemap_tests/empty_span.rs index 2cf3b66dd77..8e0395e3c50 100644 --- a/src/test/ui/codemap_tests/empty_span.rs +++ b/src/test/ui/codemap_tests/empty_span.rs @@ -14,5 +14,5 @@ fn main() { impl !Sync for Foo {} - unsafe impl Send for &'static Foo { } + unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl } diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr index b33dee6b4a4..3474803b00d 100644 --- a/src/test/ui/codemap_tests/empty_span.stderr +++ b/src/test/ui/codemap_tests/empty_span.stderr @@ -1,7 +1,7 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static main::Foo` --> $DIR/empty_span.rs:17:5 | -17 | unsafe impl Send for &'static Foo { } +17 | unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.rs b/src/test/ui/codemap_tests/huge_multispan_highlight.rs index 5a058d48391..cf593eab853 100644 --- a/src/test/ui/codemap_tests/huge_multispan_highlight.rs +++ b/src/test/ui/codemap_tests/huge_multispan_highlight.rs @@ -97,5 +97,5 @@ fn main() { - let y = &mut x; + let y = &mut x; //~ ERROR cannot borrow } diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr index 914db98c784..bc333bde93c 100644 --- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr +++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr @@ -4,7 +4,7 @@ error[E0596]: cannot borrow immutable local variable `x` as mutable 12 | let x = "foo"; | - consider changing this to `mut x` ... -100 | let y = &mut x; +100 | let y = &mut x; //~ ERROR cannot borrow | ^ cannot borrow mutably error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/issue-11715.rs b/src/test/ui/codemap_tests/issue-11715.rs index ba1ce6abcd3..75581d38927 100644 --- a/src/test/ui/codemap_tests/issue-11715.rs +++ b/src/test/ui/codemap_tests/issue-11715.rs @@ -97,5 +97,5 @@ fn main() { let mut x = "foo"; let y = &mut x; - let z = &mut x; + let z = &mut x; //~ ERROR cannot borrow } diff --git a/src/test/ui/codemap_tests/issue-11715.stderr b/src/test/ui/codemap_tests/issue-11715.stderr index 4947cbedd20..bd8ffba00d4 100644 --- a/src/test/ui/codemap_tests/issue-11715.stderr +++ b/src/test/ui/codemap_tests/issue-11715.stderr @@ -3,7 +3,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time | 99 | let y = &mut x; | - first mutable borrow occurs here -100 | let z = &mut x; +100 | let z = &mut x; //~ ERROR cannot borrow | ^ second mutable borrow occurs here 101 | } | - first borrow ends here diff --git a/src/test/ui/codemap_tests/issue-28308.stderr b/src/test/ui/codemap_tests/issue-28308.stderr index 7a1478104fd..bb91bbbc9e3 100644 --- a/src/test/ui/codemap_tests/issue-28308.stderr +++ b/src/test/ui/codemap_tests/issue-28308.stderr @@ -4,7 +4,7 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str` 12 | assert!("foo"); | ^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/one_line.rs b/src/test/ui/codemap_tests/one_line.rs index e50091d5606..3fb35dd26ac 100644 --- a/src/test/ui/codemap_tests/one_line.rs +++ b/src/test/ui/codemap_tests/one_line.rs @@ -10,5 +10,5 @@ fn main() { let mut v = vec![Some("foo"), Some("bar")]; - v.push(v.pop().unwrap()); + v.push(v.pop().unwrap()); //~ ERROR cannot borrow } diff --git a/src/test/ui/codemap_tests/one_line.stderr b/src/test/ui/codemap_tests/one_line.stderr index a73575a8d57..cfe3d527136 100644 --- a/src/test/ui/codemap_tests/one_line.stderr +++ b/src/test/ui/codemap_tests/one_line.stderr @@ -1,7 +1,7 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time --> $DIR/one_line.rs:13:12 | -13 | v.push(v.pop().unwrap()); +13 | v.push(v.pop().unwrap()); //~ ERROR cannot borrow | - ^ - first borrow ends here | | | | | second mutable borrow occurs here diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.rs b/src/test/ui/codemap_tests/overlapping_inherent_impls.rs index a626b63b31b..18e77ddfd2c 100644 --- a/src/test/ui/codemap_tests/overlapping_inherent_impls.rs +++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.rs @@ -16,7 +16,7 @@ struct Foo; impl Foo { - fn id() {} + fn id() {} //~ ERROR duplicate definitions } impl Foo { @@ -26,7 +26,7 @@ impl Foo { struct Bar<T>(T); impl<T> Bar<T> { - fn bar(&self) {} + fn bar(&self) {} //~ ERROR duplicate definitions } impl Bar<u32> { @@ -36,7 +36,7 @@ impl Bar<u32> { struct Baz<T>(T); impl<T: Copy> Baz<T> { - fn baz(&self) {} + fn baz(&self) {} //~ ERROR duplicate definitions } impl<T> Baz<Vec<T>> { diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr index eaf42cde22f..0ccdd207651 100644 --- a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr +++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr @@ -1,7 +1,7 @@ error[E0592]: duplicate definitions with name `id` --> $DIR/overlapping_inherent_impls.rs:19:5 | -19 | fn id() {} +19 | fn id() {} //~ ERROR duplicate definitions | ^^^^^^^^^^ duplicate definitions for `id` ... 23 | fn id() {} @@ -10,7 +10,7 @@ error[E0592]: duplicate definitions with name `id` error[E0592]: duplicate definitions with name `bar` --> $DIR/overlapping_inherent_impls.rs:29:5 | -29 | fn bar(&self) {} +29 | fn bar(&self) {} //~ ERROR duplicate definitions | ^^^^^^^^^^^^^^^^ duplicate definitions for `bar` ... 33 | fn bar(&self) {} @@ -19,7 +19,7 @@ error[E0592]: duplicate definitions with name `bar` error[E0592]: duplicate definitions with name `baz` --> $DIR/overlapping_inherent_impls.rs:39:5 | -39 | fn baz(&self) {} +39 | fn baz(&self) {} //~ ERROR duplicate definitions | ^^^^^^^^^^^^^^^^ duplicate definitions for `baz` ... 43 | fn baz(&self) {} diff --git a/src/test/ui/codemap_tests/overlapping_spans.rs b/src/test/ui/codemap_tests/overlapping_spans.rs index 7c1f0db16dd..467e90bd5a5 100644 --- a/src/test/ui/codemap_tests/overlapping_spans.rs +++ b/src/test/ui/codemap_tests/overlapping_spans.rs @@ -18,6 +18,6 @@ impl Drop for S { fn main() { match (S {f:"foo".to_string()}) { - S {f:_s} => {} + S {f:_s} => {} //~ ERROR cannot move out } } diff --git a/src/test/ui/codemap_tests/overlapping_spans.stderr b/src/test/ui/codemap_tests/overlapping_spans.stderr index d32b18d6703..dc801b20dfb 100644 --- a/src/test/ui/codemap_tests/overlapping_spans.stderr +++ b/src/test/ui/codemap_tests/overlapping_spans.stderr @@ -1,7 +1,7 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait --> $DIR/overlapping_spans.rs:21:9 | -21 | S {f:_s} => {} +21 | S {f:_s} => {} //~ ERROR cannot move out | ^^^^^--^ | | | | | hint: to prevent move, use `ref _s` or `ref mut _s` diff --git a/src/test/ui/codemap_tests/tab.rs b/src/test/ui/codemap_tests/tab.rs index 146ad2283c2..b8dedb0daf5 100644 --- a/src/test/ui/codemap_tests/tab.rs +++ b/src/test/ui/codemap_tests/tab.rs @@ -11,9 +11,9 @@ // ignore-tidy-tab fn main() { - bar; + bar; //~ ERROR cannot find value `bar` } fn foo() { - "bar boo" + "bar boo" //~ ERROR mismatched types } diff --git a/src/test/ui/codemap_tests/tab.stderr b/src/test/ui/codemap_tests/tab.stderr index b3fa9b128c5..41ab60f017f 100644 --- a/src/test/ui/codemap_tests/tab.stderr +++ b/src/test/ui/codemap_tests/tab.stderr @@ -1,7 +1,7 @@ error[E0425]: cannot find value `bar` in this scope --> $DIR/tab.rs:14:2 | -14 | bar; +14 | bar; //~ ERROR cannot find value `bar` | ^^^ not found in this scope error[E0308]: mismatched types @@ -9,7 +9,7 @@ error[E0308]: mismatched types | 17 | fn foo() { | - help: try adding a return type: `-> &'static str ` -18 | "bar boo" +18 | "bar boo" //~ ERROR mismatched types | ^^^^^^^^^^^ expected (), found reference | = note: expected type `()` diff --git a/src/test/ui/codemap_tests/tab_2.rs b/src/test/ui/codemap_tests/tab_2.rs index d26d7974d85..b759a4abcae 100644 --- a/src/test/ui/codemap_tests/tab_2.rs +++ b/src/test/ui/codemap_tests/tab_2.rs @@ -11,5 +11,5 @@ // ignore-tidy-tab fn main() { - """; + """; //~ ERROR unterminated double quote } diff --git a/src/test/ui/codemap_tests/tab_2.stderr b/src/test/ui/codemap_tests/tab_2.stderr index a2b3ca7e4d4..7f6b55e7eb8 100644 --- a/src/test/ui/codemap_tests/tab_2.stderr +++ b/src/test/ui/codemap_tests/tab_2.stderr @@ -1,7 +1,7 @@ error: unterminated double quote string --> $DIR/tab_2.rs:14:7 | -14 | """; +14 | """; //~ ERROR unterminated double quote | _______^ 15 | | } | |__^ diff --git a/src/test/ui/codemap_tests/tab_3.rs b/src/test/ui/codemap_tests/tab_3.rs index 9b3513d5116..ea235ed71a9 100644 --- a/src/test/ui/codemap_tests/tab_3.rs +++ b/src/test/ui/codemap_tests/tab_3.rs @@ -14,6 +14,6 @@ fn main() { let some_vec = vec!["hi"]; some_vec.into_iter(); { - println!("{:?}", some_vec); + println!("{:?}", some_vec); //~ ERROR use of moved } } diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr index f19f5f20d23..278e590a36d 100644 --- a/src/test/ui/codemap_tests/tab_3.stderr +++ b/src/test/ui/codemap_tests/tab_3.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `some_vec` 15 | some_vec.into_iter(); | -------- value moved here 16 | { -17 | println!("{:?}", some_vec); +17 | println!("{:?}", some_vec); //~ ERROR use of moved | ^^^^^^^^ value used here after move | = note: move occurs because `some_vec` has type `std::vec::Vec<&str>`, which does not implement the `Copy` trait diff --git a/src/test/ui/codemap_tests/two_files.rs b/src/test/ui/codemap_tests/two_files.rs index fe5eba93b23..4c99ee67598 100644 --- a/src/test/ui/codemap_tests/two_files.rs +++ b/src/test/ui/codemap_tests/two_files.rs @@ -12,6 +12,6 @@ include!("two_files_data.rs"); struct Baz { } -impl Bar for Baz { } +impl Bar for Baz { } //~ ERROR expected trait, found type alias fn main() { } diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 9db43dde1ac..c0cfeef194d 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -1,7 +1,7 @@ error[E0404]: expected trait, found type alias `Bar` --> $DIR/two_files.rs:15:6 | -15 | impl Bar for Baz { } +15 | impl Bar for Baz { } //~ ERROR expected trait, found type alias | ^^^ type aliases cannot be used for traits error: cannot continue compilation due to previous error diff --git a/src/test/ui/codemap_tests/unicode.rs b/src/test/ui/codemap_tests/unicode.rs index b206722d4f3..ac22906a623 100644 --- a/src/test/ui/codemap_tests/unicode.rs +++ b/src/test/ui/codemap_tests/unicode.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern "路濫狼á́́" fn foo() {} +extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI fn main() { } diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 02a9d7ee0ef..4f3c79410df 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -1,7 +1,7 @@ error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` --> $DIR/unicode.rs:11:8 | -11 | extern "路濫狼á́́" fn foo() {} +11 | extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/unicode_2.rs b/src/test/ui/codemap_tests/unicode_2.rs index cc3eae90f90..c01b0b286af 100644 --- a/src/test/ui/codemap_tests/unicode_2.rs +++ b/src/test/ui/codemap_tests/unicode_2.rs @@ -11,7 +11,7 @@ #![feature(non_ascii_idents)] fn main() { - let _ = ("a̐éö̲", 0u7); - let _ = ("아あ", 1i42); - let _ = a̐é; + let _ = ("a̐éö̲", 0u7); //~ ERROR invalid width + let _ = ("아あ", 1i42); //~ ERROR invalid width + let _ = a̐é; //~ ERROR cannot find } diff --git a/src/test/ui/codemap_tests/unicode_2.stderr b/src/test/ui/codemap_tests/unicode_2.stderr index 6cfa66730a2..9ffd08ca06f 100644 --- a/src/test/ui/codemap_tests/unicode_2.stderr +++ b/src/test/ui/codemap_tests/unicode_2.stderr @@ -1,7 +1,7 @@ error: invalid width `7` for integer literal --> $DIR/unicode_2.rs:14:25 | -14 | let _ = ("a̐éö̲", 0u7); +14 | let _ = ("a̐éö̲", 0u7); //~ ERROR invalid width | ^^^ | = help: valid widths are 8, 16, 32, 64 and 128 @@ -9,7 +9,7 @@ error: invalid width `7` for integer literal error: invalid width `42` for integer literal --> $DIR/unicode_2.rs:15:20 | -15 | let _ = ("아あ", 1i42); +15 | let _ = ("아あ", 1i42); //~ ERROR invalid width | ^^^^ | = help: valid widths are 8, 16, 32, 64 and 128 @@ -17,7 +17,7 @@ error: invalid width `42` for integer literal error[E0425]: cannot find value `a̐é` in this scope --> $DIR/unicode_2.rs:16:13 | -16 | let _ = a̐é; +16 | let _ = a̐é; //~ ERROR cannot find | ^^ not found in this scope error: aborting due to 3 previous errors diff --git a/src/test/ui/coercion-missing-tail-expected-type.rs b/src/test/ui/coercion-missing-tail-expected-type.rs index 15ce79a054f..b235a0f2136 100644 --- a/src/test/ui/coercion-missing-tail-expected-type.rs +++ b/src/test/ui/coercion-missing-tail-expected-type.rs @@ -10,11 +10,11 @@ // #41425 -- error message "mismatched types" has wrong types -fn plus_one(x: i32) -> i32 { +fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types x + 1; } -fn foo() -> Result<u8, u64> { +fn foo() -> Result<u8, u64> { //~ ERROR mismatched types Ok(1); } diff --git a/src/test/ui/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion-missing-tail-expected-type.stderr index 0de0a25e68e..93f57216ca0 100644 --- a/src/test/ui/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion-missing-tail-expected-type.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:13:28 | -13 | fn plus_one(x: i32) -> i32 { +13 | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types | ____________________________^ 14 | | x + 1; | | - help: consider removing this semicolon @@ -14,7 +14,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:17:29 | -17 | fn foo() -> Result<u8, u64> { +17 | fn foo() -> Result<u8, u64> { //~ ERROR mismatched types | _____________________________^ 18 | | Ok(1); | | - help: consider removing this semicolon diff --git a/src/test/ui/command-line-diagnostics.rs b/src/test/ui/command-line-diagnostics.rs new file mode 100644 index 00000000000..ac631c2e45e --- /dev/null +++ b/src/test/ui/command-line-diagnostics.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test checks the output format without the intermediate json representation +// compile-flags: --error-format=human + +pub fn main() { + let x = 42; + x = 43; +} diff --git a/src/test/ui/command-line-diagnostics.stderr b/src/test/ui/command-line-diagnostics.stderr new file mode 100644 index 00000000000..48ca45914c6 --- /dev/null +++ b/src/test/ui/command-line-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0384]: cannot assign twice to immutable variable `x` + --> $DIR/command-line-diagnostics.rs:16:5 + | +15 | let x = 42; + | - first assignment to `x` +16 | x = 43; + | ^^^^^^ cannot assign twice to immutable variable + +error: aborting due to previous error + diff --git a/src/test/ui/compare-method/region-extra.rs b/src/test/ui/compare-method/region-extra.rs index e359f080968..9befa1ba60e 100644 --- a/src/test/ui/compare-method/region-extra.rs +++ b/src/test/ui/compare-method/region-extra.rs @@ -16,7 +16,7 @@ trait Master<'a, 'b> { } impl<'a, 'b> Master<'a, 'b> for () { - fn foo() where 'a: 'b { } + fn foo() where 'a: 'b { } //~ ERROR impl has stricter } fn main() { diff --git a/src/test/ui/compare-method/region-extra.stderr b/src/test/ui/compare-method/region-extra.stderr index bc42b505818..d46376b4a42 100644 --- a/src/test/ui/compare-method/region-extra.stderr +++ b/src/test/ui/compare-method/region-extra.stderr @@ -4,7 +4,7 @@ error[E0276]: impl has stricter requirements than trait 15 | fn foo(); | --------- definition of `foo` from trait ... -19 | fn foo() where 'a: 'b { } +19 | fn foo() where 'a: 'b { } //~ ERROR impl has stricter | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b` error: aborting due to previous error diff --git a/src/test/ui/compare-method/region-unrelated.rs b/src/test/ui/compare-method/region-unrelated.rs index 719e15fdb61..31ab6cb7fc4 100644 --- a/src/test/ui/compare-method/region-unrelated.rs +++ b/src/test/ui/compare-method/region-unrelated.rs @@ -17,7 +17,7 @@ trait Master<'a, T: ?Sized, U> { // `U: 'a` does not imply `V: 'a` impl<'a, U, V> Master<'a, U, V> for () { fn foo() where V: 'a { } - //~^ ERROR parameter type `V` may not live long enough + //~^ ERROR impl has stricter requirements than trait } fn main() { diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs index 1d4ded6e712..85ab2a00521 100644 --- a/src/test/ui/const-eval/issue-43197.rs +++ b/src/test/ui/const-eval/issue-43197.rs @@ -15,7 +15,9 @@ const fn foo(x: u32) -> u32 { } fn main() { - const X: u32 = 0-1; - const Y: u32 = foo(0-1); + const X: u32 = 0-1; //~ ERROR constant evaluation error + //~^ WARN constant evaluation error + const Y: u32 = foo(0-1); //~ ERROR constant evaluation error + //~^ WARN constant evaluation error println!("{} {}", X, Y); } diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index 58dedcfd9b1..82baab620ff 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -1,27 +1,27 @@ warning: constant evaluation error: attempt to subtract with overflow --> $DIR/issue-43197.rs:18:20 | -18 | const X: u32 = 0-1; +18 | const X: u32 = 0-1; //~ ERROR constant evaluation error | ^^^ | = note: #[warn(const_err)] on by default warning: constant evaluation error: attempt to subtract with overflow - --> $DIR/issue-43197.rs:19:20 + --> $DIR/issue-43197.rs:20:20 | -19 | const Y: u32 = foo(0-1); +20 | const Y: u32 = foo(0-1); //~ ERROR constant evaluation error | ^^^^^^^^ error[E0080]: constant evaluation error --> $DIR/issue-43197.rs:18:20 | -18 | const X: u32 = 0-1; +18 | const X: u32 = 0-1; //~ ERROR constant evaluation error | ^^^ attempt to subtract with overflow error[E0080]: constant evaluation error - --> $DIR/issue-43197.rs:19:24 + --> $DIR/issue-43197.rs:20:24 | -19 | const Y: u32 = foo(0-1); +20 | const Y: u32 = foo(0-1); //~ ERROR constant evaluation error | ^^^ attempt to subtract with overflow error: aborting due to 2 previous errors diff --git a/src/test/ui/const-expr-addr-operator.rs b/src/test/ui/const-expr-addr-operator.rs index 282b0d4e45b..24d4457f01d 100644 --- a/src/test/ui/const-expr-addr-operator.rs +++ b/src/test/ui/const-expr-addr-operator.rs @@ -12,9 +12,9 @@ pub fn main() { // Constant of generic type (int) - const X: &'static u32 = &22; + const X: &'static u32 = &22; //~ ERROR constant evaluation error assert_eq!(0, match &22 { X => 0, _ => 1, }); -} \ No newline at end of file +} diff --git a/src/test/ui/const-expr-addr-operator.stderr b/src/test/ui/const-expr-addr-operator.stderr index 5bda81451d0..f6587c703bd 100644 --- a/src/test/ui/const-expr-addr-operator.stderr +++ b/src/test/ui/const-expr-addr-operator.stderr @@ -1,7 +1,7 @@ error[E0080]: constant evaluation error --> $DIR/const-expr-addr-operator.rs:15:29 | -15 | const X: &'static u32 = &22; +15 | const X: &'static u32 = &22; //~ ERROR constant evaluation error | ^^^ unimplemented constant expression: address operator | note: for pattern here diff --git a/src/test/ui/cross-crate-macro-backtrace/main.rs b/src/test/ui/cross-crate-macro-backtrace/main.rs index f8bb84abcd4..85640087a9d 100644 --- a/src/test/ui/cross-crate-macro-backtrace/main.rs +++ b/src/test/ui/cross-crate-macro-backtrace/main.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern: in format string + // aux-build:extern_macro_crate.rs #[macro_use(myprintln, myprint)] extern crate extern_macro_crate; fn main() { - myprintln!("{}"); //~ ERROR in this macro + myprintln!("{}"); } diff --git a/src/test/ui/cross-crate-macro-backtrace/main.stderr b/src/test/ui/cross-crate-macro-backtrace/main.stderr index 4dad6d60b40..3644c0468d6 100644 --- a/src/test/ui/cross-crate-macro-backtrace/main.stderr +++ b/src/test/ui/cross-crate-macro-backtrace/main.stderr @@ -1,10 +1,10 @@ error: 1 positional argument in format string, but no arguments were given - --> $DIR/main.rs:16:5 + --> $DIR/main.rs:18:5 | -16 | myprintln!("{}"); //~ ERROR in this macro +18 | myprintln!("{}"); | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/deref-suggestion.rs b/src/test/ui/deref-suggestion.rs index 16d8226bfec..04ba4ab905e 100644 --- a/src/test/ui/deref-suggestion.rs +++ b/src/test/ui/deref-suggestion.rs @@ -9,26 +9,26 @@ // except according to those terms. macro_rules! borrow { - ($x:expr) => { &$x } + ($x:expr) => { &$x } //~ ERROR mismatched types } fn foo(_: String) {} fn foo2(s: &String) { - foo(s); + foo(s); //~ ERROR mismatched types } fn foo3(_: u32) {} fn foo4(u: &u32) { - foo3(u); + foo3(u); //~ ERROR mismatched types } fn main() { let s = String::new(); let r_s = &s; foo2(r_s); - foo(&"aaa".to_owned()); - foo(&mut "aaa".to_owned()); + foo(&"aaa".to_owned()); //~ ERROR mismatched types + foo(&mut "aaa".to_owned()); //~ ERROR mismatched types foo3(borrow!(0)); foo4(&0); } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 3ed3297e05e..6c418cf4bfb 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:18:9 | -18 | foo(s); +18 | foo(s); //~ ERROR mismatched types | ^ expected struct `std::string::String`, found reference | = note: expected type `std::string::String` @@ -16,7 +16,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:23:10 | -23 | foo3(u); +23 | foo3(u); //~ ERROR mismatched types | ^ expected u32, found &u32 | = note: expected type `u32` @@ -26,7 +26,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:30:9 | -30 | foo(&"aaa".to_owned()); +30 | foo(&"aaa".to_owned()); //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found reference | = note: expected type `std::string::String` @@ -36,7 +36,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:31:9 | -31 | foo(&mut "aaa".to_owned()); +31 | foo(&mut "aaa".to_owned()); //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found mutable reference | = note: expected type `std::string::String` @@ -46,7 +46,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:12:20 | -12 | ($x:expr) => { &$x } +12 | ($x:expr) => { &$x } //~ ERROR mismatched types | ^^^ expected u32, found &{integer} ... 32 | foo3(borrow!(0)); diff --git a/src/test/ui/did_you_mean/E0178.rs b/src/test/ui/did_you_mean/E0178.rs index 8fb6c9815ce..21cdb38fdb1 100644 --- a/src/test/ui/did_you_mean/E0178.rs +++ b/src/test/ui/did_you_mean/E0178.rs @@ -11,10 +11,10 @@ trait Foo {} struct Bar<'a> { - w: &'a Foo + Copy, - x: &'a Foo + 'a, - y: &'a mut Foo + 'a, - z: fn() -> Foo + 'a, + w: &'a Foo + Copy, //~ ERROR expected a path + x: &'a Foo + 'a, //~ ERROR expected a path + y: &'a mut Foo + 'a, //~ ERROR expected a path + z: fn() -> Foo + 'a, //~ ERROR expected a path } fn main() { diff --git a/src/test/ui/did_you_mean/E0178.stderr b/src/test/ui/did_you_mean/E0178.stderr index 15e7131cfd3..4fe8849feef 100644 --- a/src/test/ui/did_you_mean/E0178.stderr +++ b/src/test/ui/did_you_mean/E0178.stderr @@ -1,25 +1,25 @@ error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` --> $DIR/E0178.rs:14:8 | -14 | w: &'a Foo + Copy, +14 | w: &'a Foo + Copy, //~ ERROR expected a path | ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Copy)` error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` --> $DIR/E0178.rs:15:8 | -15 | x: &'a Foo + 'a, +15 | x: &'a Foo + 'a, //~ ERROR expected a path | ^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + 'a)` error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo` --> $DIR/E0178.rs:16:8 | -16 | y: &'a mut Foo + 'a, +16 | y: &'a mut Foo + 'a, //~ ERROR expected a path | ^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'a mut (Foo + 'a)` error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo` --> $DIR/E0178.rs:17:8 | -17 | z: fn() -> Foo + 'a, +17 | z: fn() -> Foo + 'a, //~ ERROR expected a path | ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses? error: aborting due to 4 previous errors diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs index 99035209e14..076b61b1790 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs @@ -33,7 +33,4 @@ fn main() { f1.foo(1usize); //~^ error: the trait bound `Bar: Foo<usize>` is not satisfied - //~| help: the following implementations were found: - //~| help: <Bar as Foo<i32>> - //~| help: <Bar as Foo<u8>> } diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs index 2009c32c854..6beff6ba2a1 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs @@ -37,10 +37,4 @@ fn main() { f1.foo(1usize); //~^ error: the trait bound `Bar: Foo<usize>` is not satisfied - //~| help: the following implementations were found: - //~| help: <Bar as Foo<i8>> - //~| help: <Bar as Foo<i16>> - //~| help: <Bar as Foo<i32>> - //~| help: <Bar as Foo<u8>> - //~| help: and 2 others } diff --git a/src/test/ui/did_you_mean/issue-31424.rs b/src/test/ui/did_you_mean/issue-31424.rs index 374d06bb71d..1b31e064337 100644 --- a/src/test/ui/did_you_mean/issue-31424.rs +++ b/src/test/ui/did_you_mean/issue-31424.rs @@ -14,13 +14,13 @@ struct Struct; impl Struct { fn foo(&mut self) { - (&mut self).bar(); + (&mut self).bar(); //~ ERROR cannot borrow } // In this case we could keep the suggestion, but to distinguish the // two cases is pretty hard. It's an obscure case anyway. fn bar(self: &mut Self) { - (&mut self).bar(); + (&mut self).bar(); //~ ERROR cannot borrow } } diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr index 47dc7c97572..cd96d28ac98 100644 --- a/src/test/ui/did_you_mean/issue-31424.stderr +++ b/src/test/ui/did_you_mean/issue-31424.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow immutable argument `self` as mutable --> $DIR/issue-31424.rs:17:15 | -17 | (&mut self).bar(); +17 | (&mut self).bar(); //~ ERROR cannot borrow | ^^^^ | | | cannot reborrow mutably @@ -12,7 +12,7 @@ error[E0596]: cannot borrow immutable argument `self` as mutable | 22 | fn bar(self: &mut Self) { | --------------- consider changing this to `mut self: &mut Self` -23 | (&mut self).bar(); +23 | (&mut self).bar(); //~ ERROR cannot borrow | ^^^^ cannot borrow mutably error: aborting due to 2 previous errors diff --git a/src/test/ui/did_you_mean/issue-34126.rs b/src/test/ui/did_you_mean/issue-34126.rs index 9523e6bbf38..9dfb38abd04 100644 --- a/src/test/ui/did_you_mean/issue-34126.rs +++ b/src/test/ui/did_you_mean/issue-34126.rs @@ -13,7 +13,7 @@ struct Z { } impl Z { fn run(&self, z: &mut Z) { } fn start(&mut self) { - self.run(&mut self); + self.run(&mut self); //~ ERROR cannot borrow } } diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr index d9ef0c45410..a4921046c78 100644 --- a/src/test/ui/did_you_mean/issue-34126.stderr +++ b/src/test/ui/did_you_mean/issue-34126.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow immutable argument `self` as mutable --> $DIR/issue-34126.rs:16:23 | -16 | self.run(&mut self); +16 | self.run(&mut self); //~ ERROR cannot borrow | ^^^^ | | | cannot reborrow mutably diff --git a/src/test/ui/did_you_mean/issue-34337.rs b/src/test/ui/did_you_mean/issue-34337.rs index 42853a5d83d..a426c0f48cc 100644 --- a/src/test/ui/did_you_mean/issue-34337.rs +++ b/src/test/ui/did_you_mean/issue-34337.rs @@ -13,5 +13,5 @@ fn get(key: &mut String) { } fn main() { let mut v: Vec<String> = Vec::new(); let ref mut key = v[0]; - get(&mut key); + get(&mut key); //~ ERROR cannot borrow } diff --git a/src/test/ui/did_you_mean/issue-34337.stderr b/src/test/ui/did_you_mean/issue-34337.stderr index 20478165c7e..a53d3d7277a 100644 --- a/src/test/ui/did_you_mean/issue-34337.stderr +++ b/src/test/ui/did_you_mean/issue-34337.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow immutable local variable `key` as mutable --> $DIR/issue-34337.rs:16:14 | -16 | get(&mut key); +16 | get(&mut key); //~ ERROR cannot borrow | ^^^ | | | cannot reborrow mutably diff --git a/src/test/ui/did_you_mean/issue-35937.rs b/src/test/ui/did_you_mean/issue-35937.rs index 9ec8728fd32..867b47cf99e 100644 --- a/src/test/ui/did_you_mean/issue-35937.rs +++ b/src/test/ui/did_you_mean/issue-35937.rs @@ -14,7 +14,7 @@ struct Foo { fn main() { let f = Foo { v: Vec::new() }; - f.v.push("cat".to_string()); + f.v.push("cat".to_string()); //~ ERROR cannot borrow } @@ -23,9 +23,9 @@ struct S { } fn foo() { let s = S { x: 42 }; - s.x += 1; + s.x += 1; //~ ERROR cannot assign } fn bar(s: S) { - s.x += 1; + s.x += 1; //~ ERROR cannot assign } diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr index 1cd1fb76aa3..ec44755cb7c 100644 --- a/src/test/ui/did_you_mean/issue-35937.stderr +++ b/src/test/ui/did_you_mean/issue-35937.stderr @@ -3,7 +3,7 @@ error[E0596]: cannot borrow immutable field `f.v` as mutable | 16 | let f = Foo { v: Vec::new() }; | - consider changing this to `mut f` -17 | f.v.push("cat".to_string()); +17 | f.v.push("cat".to_string()); //~ ERROR cannot borrow | ^^^ cannot mutably borrow immutable field error[E0594]: cannot assign to immutable field `s.x` @@ -11,7 +11,7 @@ error[E0594]: cannot assign to immutable field `s.x` | 25 | let s = S { x: 42 }; | - consider changing this to `mut s` -26 | s.x += 1; +26 | s.x += 1; //~ ERROR cannot assign | ^^^^^^^^ cannot mutably borrow immutable field error[E0594]: cannot assign to immutable field `s.x` @@ -19,7 +19,7 @@ error[E0594]: cannot assign to immutable field `s.x` | 29 | fn bar(s: S) { | - consider changing this to `mut s` -30 | s.x += 1; +30 | s.x += 1; //~ ERROR cannot assign | ^^^^^^^^ cannot mutably borrow immutable field error: aborting due to 3 previous errors diff --git a/src/test/ui/did_you_mean/issue-36798.rs b/src/test/ui/did_you_mean/issue-36798.rs index cd0d0951abf..6e641ff025c 100644 --- a/src/test/ui/did_you_mean/issue-36798.rs +++ b/src/test/ui/did_you_mean/issue-36798.rs @@ -14,5 +14,5 @@ struct Foo { fn main() { let f = Foo { bar: 22 }; - f.baz; + f.baz; //~ ERROR no field } diff --git a/src/test/ui/did_you_mean/issue-36798.stderr b/src/test/ui/did_you_mean/issue-36798.stderr index 72fd09c0357..73319d567bd 100644 --- a/src/test/ui/did_you_mean/issue-36798.stderr +++ b/src/test/ui/did_you_mean/issue-36798.stderr @@ -1,7 +1,7 @@ error[E0609]: no field `baz` on type `Foo` --> $DIR/issue-36798.rs:17:7 | -17 | f.baz; +17 | f.baz; //~ ERROR no field | ^^^ did you mean `bar`? error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.rs b/src/test/ui/did_you_mean/issue-36798_unknown_field.rs index 2970a325a6a..ec54a8d2b43 100644 --- a/src/test/ui/did_you_mean/issue-36798_unknown_field.rs +++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.rs @@ -14,5 +14,5 @@ struct Foo { fn main() { let f = Foo { bar: 22 }; - f.zz; + f.zz; //~ ERROR no field } diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr index 20bb7d4c91d..f17672b234f 100644 --- a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr +++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr @@ -1,7 +1,7 @@ error[E0609]: no field `zz` on type `Foo` --> $DIR/issue-36798_unknown_field.rs:17:7 | -17 | f.zz; +17 | f.zz; //~ ERROR no field | ^^ unknown field | = note: available fields are: `bar` diff --git a/src/test/ui/did_you_mean/issue-37139.rs b/src/test/ui/did_you_mean/issue-37139.rs index 65181768053..8a1a7ce0c32 100644 --- a/src/test/ui/did_you_mean/issue-37139.rs +++ b/src/test/ui/did_you_mean/issue-37139.rs @@ -19,7 +19,7 @@ fn main() { let mut x = TestEnum::Item(10); match x { TestEnum::Item(ref mut x) => { - test(&mut x); + test(&mut x); //~ ERROR cannot borrow immutable } } } diff --git a/src/test/ui/did_you_mean/issue-37139.stderr b/src/test/ui/did_you_mean/issue-37139.stderr index 9fc364f8612..65de724616d 100644 --- a/src/test/ui/did_you_mean/issue-37139.stderr +++ b/src/test/ui/did_you_mean/issue-37139.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow immutable local variable `x` as mutable --> $DIR/issue-37139.rs:22:23 | -22 | test(&mut x); +22 | test(&mut x); //~ ERROR cannot borrow immutable | ^ | | | cannot reborrow mutably diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs index 1938d33e530..c9c1c5d141d 100644 --- a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs +++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use Foo; +use Foo; //~ ERROR unresolved -use Foo1; +use Foo1; //~ ERROR unresolved fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr index 325f55e686c..c58958c7f5e 100644 --- a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr +++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr @@ -1,13 +1,13 @@ error[E0432]: unresolved import `Foo` --> $DIR/issue-38054-do-not-show-unresolved-names.rs:11:5 | -11 | use Foo; +11 | use Foo; //~ ERROR unresolved | ^^^ no `Foo` in the root error[E0432]: unresolved import `Foo1` --> $DIR/issue-38054-do-not-show-unresolved-names.rs:13:5 | -13 | use Foo1; +13 | use Foo1; //~ ERROR unresolved | ^^^^ no `Foo1` in the root error: aborting due to 2 previous errors diff --git a/src/test/ui/did_you_mean/issue-38147-1.rs b/src/test/ui/did_you_mean/issue-38147-1.rs index 136921dd0a5..a7ce7406566 100644 --- a/src/test/ui/did_you_mean/issue-38147-1.rs +++ b/src/test/ui/did_you_mean/issue-38147-1.rs @@ -24,7 +24,7 @@ struct Foo<'a> { impl<'a> Foo<'a> { fn f(&self) { - self.s.push('x'); + self.s.push('x'); //~ ERROR cannot borrow data mutably } } diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr index e9f2b1dad80..6a262b31026 100644 --- a/src/test/ui/did_you_mean/issue-38147-1.stderr +++ b/src/test/ui/did_you_mean/issue-38147-1.stderr @@ -3,7 +3,7 @@ error[E0389]: cannot borrow data mutably in a `&` reference | 26 | fn f(&self) { | ----- use `&mut self` here to make mutable -27 | self.s.push('x'); +27 | self.s.push('x'); //~ ERROR cannot borrow data mutably | ^^^^^^ assignment into an immutable reference error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-38147-2.rs b/src/test/ui/did_you_mean/issue-38147-2.rs index a5d533edf75..cc6be98bcf8 100644 --- a/src/test/ui/did_you_mean/issue-38147-2.rs +++ b/src/test/ui/did_you_mean/issue-38147-2.rs @@ -14,7 +14,7 @@ struct Bar<'a> { impl<'a> Bar<'a> { fn f(&mut self) { - self.s.push('x'); + self.s.push('x'); //~ ERROR cannot borrow immutable borrowed } } diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr index e81bc722fa0..b09ecf9057c 100644 --- a/src/test/ui/did_you_mean/issue-38147-2.stderr +++ b/src/test/ui/did_you_mean/issue-38147-2.stderr @@ -4,7 +4,7 @@ error[E0596]: cannot borrow immutable borrowed content `*self.s` as mutable 12 | s: &'a String | ---------- use `&'a mut String` here to make mutable ... -17 | self.s.push('x'); +17 | self.s.push('x'); //~ ERROR cannot borrow immutable borrowed | ^^^^^^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-38147-3.rs b/src/test/ui/did_you_mean/issue-38147-3.rs index 5e8f2d3eaef..42b29100517 100644 --- a/src/test/ui/did_you_mean/issue-38147-3.rs +++ b/src/test/ui/did_you_mean/issue-38147-3.rs @@ -14,7 +14,7 @@ struct Qux<'a> { impl<'a> Qux<'a> { fn f(&self) { - self.s.push('x'); + self.s.push('x'); //~ ERROR cannot borrow immutable borrowed } } diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr index 749795f4d8f..ca721f133a4 100644 --- a/src/test/ui/did_you_mean/issue-38147-3.stderr +++ b/src/test/ui/did_you_mean/issue-38147-3.stderr @@ -4,7 +4,7 @@ error[E0596]: cannot borrow immutable borrowed content `*self.s` as mutable 12 | s: &'a String | ---------- use `&'a mut String` here to make mutable ... -17 | self.s.push('x'); +17 | self.s.push('x'); //~ ERROR cannot borrow immutable borrowed | ^^^^^^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-38147-4.rs b/src/test/ui/did_you_mean/issue-38147-4.rs index 4eb20ceeed4..49a8f2b6ff6 100644 --- a/src/test/ui/did_you_mean/issue-38147-4.rs +++ b/src/test/ui/did_you_mean/issue-38147-4.rs @@ -13,7 +13,7 @@ struct Foo<'a> { } fn f(x: usize, f: &Foo) { - f.s.push('x'); + f.s.push('x'); //~ ERROR cannot borrow data mutably } fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr index 9a8853f4fbb..33bf2e1160c 100644 --- a/src/test/ui/did_you_mean/issue-38147-4.stderr +++ b/src/test/ui/did_you_mean/issue-38147-4.stderr @@ -3,7 +3,7 @@ error[E0389]: cannot borrow data mutably in a `&` reference | 15 | fn f(x: usize, f: &Foo) { | ---- use `&mut Foo` here to make mutable -16 | f.s.push('x'); +16 | f.s.push('x'); //~ ERROR cannot borrow data mutably | ^^^ assignment into an immutable reference error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-39544.rs b/src/test/ui/did_you_mean/issue-39544.rs index d7c89355606..7cd7768078a 100644 --- a/src/test/ui/did_you_mean/issue-39544.rs +++ b/src/test/ui/did_you_mean/issue-39544.rs @@ -18,42 +18,42 @@ pub struct Z { fn main() { let z = Z { x: X::Y }; - let _ = &mut z.x; + let _ = &mut z.x; //~ ERROR cannot borrow } impl Z { fn foo<'z>(&'z self) { - let _ = &mut self.x; + let _ = &mut self.x; //~ ERROR cannot borrow } fn foo1(&self, other: &Z) { - let _ = &mut self.x; - let _ = &mut other.x; + let _ = &mut self.x; //~ ERROR cannot borrow + let _ = &mut other.x; //~ ERROR cannot borrow } fn foo2<'a>(&'a self, other: &Z) { - let _ = &mut self.x; - let _ = &mut other.x; + let _ = &mut self.x; //~ ERROR cannot borrow + let _ = &mut other.x; //~ ERROR cannot borrow } fn foo3<'a>(self: &'a Self, other: &Z) { - let _ = &mut self.x; - let _ = &mut other.x; + let _ = &mut self.x; //~ ERROR cannot borrow + let _ = &mut other.x; //~ ERROR cannot borrow } fn foo4(other: &Z) { - let _ = &mut other.x; + let _ = &mut other.x; //~ ERROR cannot borrow } } pub fn with_arg(z: Z, w: &Z) { - let _ = &mut z.x; - let _ = &mut w.x; + let _ = &mut z.x; //~ ERROR cannot borrow + let _ = &mut w.x; //~ ERROR cannot borrow } pub fn with_tuple() { let mut y = 0; let x = (&y,); - *x.0 = 1; + *x.0 = 1; //~ ERROR cannot assign to immutable borrowed content } diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr index 28aaab97bda..1fcb05374f6 100644 --- a/src/test/ui/did_you_mean/issue-39544.stderr +++ b/src/test/ui/did_you_mean/issue-39544.stderr @@ -3,7 +3,7 @@ error[E0596]: cannot borrow immutable field `z.x` as mutable | 20 | let z = Z { x: X::Y }; | - consider changing this to `mut z` -21 | let _ = &mut z.x; +21 | let _ = &mut z.x; //~ ERROR cannot borrow | ^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `self.x` as mutable @@ -11,7 +11,7 @@ error[E0596]: cannot borrow immutable field `self.x` as mutable | 25 | fn foo<'z>(&'z self) { | -------- use `&'z mut self` here to make mutable -26 | let _ = &mut self.x; +26 | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `self.x` as mutable @@ -19,7 +19,7 @@ error[E0596]: cannot borrow immutable field `self.x` as mutable | 29 | fn foo1(&self, other: &Z) { | ----- use `&mut self` here to make mutable -30 | let _ = &mut self.x; +30 | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `other.x` as mutable @@ -27,8 +27,8 @@ error[E0596]: cannot borrow immutable field `other.x` as mutable | 29 | fn foo1(&self, other: &Z) { | -- use `&mut Z` here to make mutable -30 | let _ = &mut self.x; -31 | let _ = &mut other.x; +30 | let _ = &mut self.x; //~ ERROR cannot borrow +31 | let _ = &mut other.x; //~ ERROR cannot borrow | ^^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `self.x` as mutable @@ -36,7 +36,7 @@ error[E0596]: cannot borrow immutable field `self.x` as mutable | 34 | fn foo2<'a>(&'a self, other: &Z) { | -------- use `&'a mut self` here to make mutable -35 | let _ = &mut self.x; +35 | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `other.x` as mutable @@ -44,8 +44,8 @@ error[E0596]: cannot borrow immutable field `other.x` as mutable | 34 | fn foo2<'a>(&'a self, other: &Z) { | -- use `&mut Z` here to make mutable -35 | let _ = &mut self.x; -36 | let _ = &mut other.x; +35 | let _ = &mut self.x; //~ ERROR cannot borrow +36 | let _ = &mut other.x; //~ ERROR cannot borrow | ^^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `self.x` as mutable @@ -53,7 +53,7 @@ error[E0596]: cannot borrow immutable field `self.x` as mutable | 39 | fn foo3<'a>(self: &'a Self, other: &Z) { | -------- use `&'a mut Self` here to make mutable -40 | let _ = &mut self.x; +40 | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `other.x` as mutable @@ -61,8 +61,8 @@ error[E0596]: cannot borrow immutable field `other.x` as mutable | 39 | fn foo3<'a>(self: &'a Self, other: &Z) { | -- use `&mut Z` here to make mutable -40 | let _ = &mut self.x; -41 | let _ = &mut other.x; +40 | let _ = &mut self.x; //~ ERROR cannot borrow +41 | let _ = &mut other.x; //~ ERROR cannot borrow | ^^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `other.x` as mutable @@ -70,7 +70,7 @@ error[E0596]: cannot borrow immutable field `other.x` as mutable | 44 | fn foo4(other: &Z) { | -- use `&mut Z` here to make mutable -45 | let _ = &mut other.x; +45 | let _ = &mut other.x; //~ ERROR cannot borrow | ^^^^^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `z.x` as mutable @@ -78,7 +78,7 @@ error[E0596]: cannot borrow immutable field `z.x` as mutable | 50 | pub fn with_arg(z: Z, w: &Z) { | - consider changing this to `mut z` -51 | let _ = &mut z.x; +51 | let _ = &mut z.x; //~ ERROR cannot borrow | ^^^ cannot mutably borrow immutable field error[E0596]: cannot borrow immutable field `w.x` as mutable @@ -86,14 +86,14 @@ error[E0596]: cannot borrow immutable field `w.x` as mutable | 50 | pub fn with_arg(z: Z, w: &Z) { | -- use `&mut Z` here to make mutable -51 | let _ = &mut z.x; -52 | let _ = &mut w.x; +51 | let _ = &mut z.x; //~ ERROR cannot borrow +52 | let _ = &mut w.x; //~ ERROR cannot borrow | ^^^ cannot mutably borrow immutable field error[E0594]: cannot assign to immutable borrowed content `*x.0` --> $DIR/issue-39544.rs:58:5 | -58 | *x.0 = 1; +58 | *x.0 = 1; //~ ERROR cannot assign to immutable borrowed content | ^^^^^^^^ cannot borrow as mutable error: aborting due to 12 previous errors diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs index 68b1f79c89b..660aedc3596 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.rs @@ -31,7 +31,7 @@ impl Foo<bool> for bool {} impl Foo<i8> for bool {} fn main() { - Foo::<i32>::bar(&1i8); - Foo::<i32>::bar(&1u8); - Foo::<i32>::bar(&true); + Foo::<i32>::bar(&1i8); //~ ERROR is not satisfied + Foo::<i32>::bar(&1u8); //~ ERROR is not satisfied + Foo::<i32>::bar(&true); //~ ERROR is not satisfied } diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index 4ea4adfcfe0..d5c4add34b5 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:34:5 | -34 | Foo::<i32>::bar(&1i8); +34 | Foo::<i32>::bar(&1i8); //~ ERROR is not satisfied | ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `i8` | = help: the following implementations were found: @@ -15,7 +15,7 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:35:5 | -35 | Foo::<i32>::bar(&1u8); +35 | Foo::<i32>::bar(&1u8); //~ ERROR is not satisfied | ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `u8` | = help: the following implementations were found: @@ -28,7 +28,7 @@ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:36:5 | -36 | Foo::<i32>::bar(&true); +36 | Foo::<i32>::bar(&true); //~ ERROR is not satisfied | ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool` | = help: the following implementations were found: diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs index d68c25faa8a..62316b96db0 100644 --- a/src/test/ui/did_you_mean/issue-40006.rs +++ b/src/test/ui/did_you_mean/issue-40006.rs @@ -8,22 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -impl X { +impl X { //~ ERROR cannot be made into an object +//~^ ERROR missing Y } struct S; -trait X { +trait X { //~ ERROR missing X() {} - fn xxx() { ### } - L = M; - Z = { 2 + 3 }; - ::Y (); + fn xxx() { ### } //~ ERROR missing + //~^ ERROR expected + L = M; //~ ERROR missing + Z = { 2 + 3 }; //~ ERROR expected one of + ::Y (); //~ ERROR expected one of } impl S { - pub hello_method(&self) { + pub hello_method(&self) { //~ ERROR missing println!("Hello"); } } diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index 3b7f32cf890..8fadb4ff6b6 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -1,65 +1,67 @@ error: missing `fn`, `type`, or `const` for impl-item declaration --> $DIR/issue-40006.rs:11:9 | -11 | impl X { +11 | impl X { //~ ERROR cannot be made into an object | _________^ -12 | | Y +12 | | //~^ ERROR missing +13 | | Y | |____^ missing `fn`, `type`, or `const` error: missing `fn`, `type`, or `const` for trait-item declaration - --> $DIR/issue-40006.rs:17:10 + --> $DIR/issue-40006.rs:18:10 | -17 | trait X { +18 | trait X { //~ ERROR missing | __________^ -18 | | X() {} +19 | | X() {} | |____^ missing `fn`, `type`, or `const` error: expected `[`, found `#` - --> $DIR/issue-40006.rs:19:17 + --> $DIR/issue-40006.rs:20:17 | -19 | fn xxx() { ### } +20 | fn xxx() { ### } //~ ERROR missing | ^ error: missing `fn`, `type`, or `const` for trait-item declaration - --> $DIR/issue-40006.rs:19:21 + --> $DIR/issue-40006.rs:20:21 | -19 | fn xxx() { ### } +20 | fn xxx() { ### } //~ ERROR missing | _____________________^ -20 | | L = M; +21 | | //~^ ERROR expected +22 | | L = M; //~ ERROR missing | |____^ missing `fn`, `type`, or `const` error: missing `fn`, `type`, or `const` for trait-item declaration - --> $DIR/issue-40006.rs:20:11 + --> $DIR/issue-40006.rs:22:11 | -20 | L = M; +22 | L = M; //~ ERROR missing | ___________^ -21 | | Z = { 2 + 3 }; +23 | | Z = { 2 + 3 }; //~ ERROR expected one of | |____^ missing `fn`, `type`, or `const` error: expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;` - --> $DIR/issue-40006.rs:21:18 + --> $DIR/issue-40006.rs:23:18 | -21 | Z = { 2 + 3 }; +23 | Z = { 2 + 3 }; //~ ERROR expected one of | ^ expected one of `const`, `extern`, `fn`, `type`, `unsafe`, or `}` here error: expected one of `!` or `::`, found `(` - --> $DIR/issue-40006.rs:22:9 + --> $DIR/issue-40006.rs:24:9 | -22 | ::Y (); +24 | ::Y (); //~ ERROR expected one of | -^ unexpected token | | | expected one of `!` or `::` here error: missing `fn`, `type`, or `const` for impl-item declaration - --> $DIR/issue-40006.rs:26:8 + --> $DIR/issue-40006.rs:28:8 | -26 | pub hello_method(&self) { +28 | pub hello_method(&self) { //~ ERROR missing | ^ missing `fn`, `type`, or `const` error[E0038]: the trait `X` cannot be made into an object --> $DIR/issue-40006.rs:11:6 | -11 | impl X { +11 | impl X { //~ ERROR cannot be made into an object | ^ the trait `X` cannot be made into an object | = note: method `xxx` has no receiver diff --git a/src/test/ui/did_you_mean/issue-40396.rs b/src/test/ui/did_you_mean/issue-40396.rs index 1eae180976a..eb62dc54084 100644 --- a/src/test/ui/did_you_mean/issue-40396.rs +++ b/src/test/ui/did_you_mean/issue-40396.rs @@ -9,15 +9,16 @@ // except according to those terms. fn foo() { - println!("{:?}", (0..13).collect<Vec<i32>>()); + println!("{:?}", (0..13).collect<Vec<i32>>()); //~ ERROR chained comparison } fn bar() { - println!("{:?}", Vec<i32>::new()); + println!("{:?}", Vec<i32>::new()); //~ ERROR chained comparison } fn qux() { - println!("{:?}", (0..13).collect<Vec<i32>()); + println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison + //~^ ERROR chained comparison } fn main() {} diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr index 11279f5c612..8f4118b3ff0 100644 --- a/src/test/ui/did_you_mean/issue-40396.stderr +++ b/src/test/ui/did_you_mean/issue-40396.stderr @@ -1,7 +1,7 @@ error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:12:37 | -12 | println!("{:?}", (0..13).collect<Vec<i32>>()); +12 | println!("{:?}", (0..13).collect<Vec<i32>>()); //~ ERROR chained comparison | ^^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments @@ -10,7 +10,7 @@ error: chained comparison operators require parentheses error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:16:25 | -16 | println!("{:?}", Vec<i32>::new()); +16 | println!("{:?}", Vec<i32>::new()); //~ ERROR chained comparison | ^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments @@ -19,7 +19,7 @@ error: chained comparison operators require parentheses error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:20:37 | -20 | println!("{:?}", (0..13).collect<Vec<i32>()); +20 | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison | ^^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments @@ -28,7 +28,7 @@ error: chained comparison operators require parentheses error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:20:41 | -20 | println!("{:?}", (0..13).collect<Vec<i32>()); +20 | println!("{:?}", (0..13).collect<Vec<i32>()); //~ ERROR chained comparison | ^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments diff --git a/src/test/ui/did_you_mean/issue-40823.rs b/src/test/ui/did_you_mean/issue-40823.rs index f4ae3257279..3b48cef1902 100644 --- a/src/test/ui/did_you_mean/issue-40823.rs +++ b/src/test/ui/did_you_mean/issue-40823.rs @@ -10,5 +10,5 @@ fn main() { let mut buf = &[1, 2, 3, 4]; - buf.iter_mut(); + buf.iter_mut(); //~ ERROR cannot borrow immutable borrowed content } diff --git a/src/test/ui/did_you_mean/issue-40823.stderr b/src/test/ui/did_you_mean/issue-40823.stderr index 7daab09c09e..0b71fc1d306 100644 --- a/src/test/ui/did_you_mean/issue-40823.stderr +++ b/src/test/ui/did_you_mean/issue-40823.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow immutable borrowed content `*buf` as mutable --> $DIR/issue-40823.rs:13:5 | -13 | buf.iter_mut(); +13 | buf.iter_mut(); //~ ERROR cannot borrow immutable borrowed content | ^^^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-41679.rs b/src/test/ui/did_you_mean/issue-41679.rs index 5091b9efc34..98c909e212f 100644 --- a/src/test/ui/did_you_mean/issue-41679.rs +++ b/src/test/ui/did_you_mean/issue-41679.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x = ~1; + let x = ~1; //~ ERROR can not be used as a unary operator } diff --git a/src/test/ui/did_you_mean/issue-41679.stderr b/src/test/ui/did_you_mean/issue-41679.stderr index 2abbbf65ba9..f1ccb3e6e14 100644 --- a/src/test/ui/did_you_mean/issue-41679.stderr +++ b/src/test/ui/did_you_mean/issue-41679.stderr @@ -1,7 +1,7 @@ error: `~` can not be used as a unary operator --> $DIR/issue-41679.rs:12:13 | -12 | let x = ~1; +12 | let x = ~1; //~ ERROR can not be used as a unary operator | ^ did you mean `!`? | = help: use `!` instead of `~` if you meant to perform bitwise negation diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs b/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs index 7fe99508012..ad5bedcefc2 100644 --- a/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs +++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.rs @@ -24,10 +24,12 @@ mod submodule { impl Demo { fn new_with_secret_two() -> Self { Self { secret_integer: 2, inocently_mispellable: () } + //~^ ERROR no field } fn new_with_secret_three() -> Self { Self { secret_integer: 3, egregiously_nonexistent_field: () } + //~^ ERROR no field } } @@ -38,6 +40,8 @@ fn main() { let demo = Demo::default(); let innocent_field_misaccess = demo.inocently_mispellable; + //~^ ERROR no field // note shouldn't suggest private fields let egregious_field_misaccess = demo.egregiously_nonexistent_field; + //~^ ERROR no field } diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr index e2bb7fbd9a8..d5dcef63847 100644 --- a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr +++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr @@ -5,23 +5,23 @@ error[E0560]: struct `submodule::Demo` has no field named `inocently_mispellable | ^^^^^^^^^^^^^^^^^^^^^^ field does not exist - did you mean `innocently_misspellable`? error[E0560]: struct `submodule::Demo` has no field named `egregiously_nonexistent_field` - --> $DIR/issue-42599_available_fields_note.rs:30:39 + --> $DIR/issue-42599_available_fields_note.rs:31:39 | -30 | Self { secret_integer: 3, egregiously_nonexistent_field: () } +31 | Self { secret_integer: 3, egregiously_nonexistent_field: () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `submodule::Demo` does not have this field | = note: available fields are: `favorite_integer`, `secret_integer`, `innocently_misspellable`, `another_field`, `yet_another_field` ... and 2 others error[E0609]: no field `inocently_mispellable` on type `submodule::Demo` - --> $DIR/issue-42599_available_fields_note.rs:40:41 + --> $DIR/issue-42599_available_fields_note.rs:42:41 | -40 | let innocent_field_misaccess = demo.inocently_mispellable; +42 | let innocent_field_misaccess = demo.inocently_mispellable; | ^^^^^^^^^^^^^^^^^^^^^ did you mean `innocently_misspellable`? error[E0609]: no field `egregiously_nonexistent_field` on type `submodule::Demo` - --> $DIR/issue-42599_available_fields_note.rs:42:42 + --> $DIR/issue-42599_available_fields_note.rs:45:42 | -42 | let egregious_field_misaccess = demo.egregiously_nonexistent_field; +45 | let egregious_field_misaccess = demo.egregiously_nonexistent_field; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field | = note: available fields are: `favorite_integer`, `innocently_misspellable` diff --git a/src/test/ui/did_you_mean/issue-42764.rs b/src/test/ui/did_you_mean/issue-42764.rs index ecaeb7b1161..ff4bb428d5f 100644 --- a/src/test/ui/did_you_mean/issue-42764.rs +++ b/src/test/ui/did_you_mean/issue-42764.rs @@ -19,4 +19,5 @@ fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {} fn main() { let n: usize = 42; this_function_expects_a_double_option(n); + //~^ ERROR mismatched types } diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs new file mode 100644 index 00000000000..7b877523e35 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Example { Ex(String), NotEx } + +fn result_test() { + let x = Option(1); //~ ERROR expected function, found enum + + if let Option(_) = x { //~ ERROR expected tuple struct/variant, found enum + println!("It is OK."); + } + + let y = Example::Ex(String::from("test")); + + if let Example(_) = y { //~ ERROR expected tuple struct/variant, found enum + println!("It is OK."); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr new file mode 100644 index 00000000000..5390e541fb7 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr @@ -0,0 +1,32 @@ +error[E0423]: expected function, found enum `Option` + --> $DIR/issue-43871-enum-instead-of-variant.rs:14:13 + | +14 | let x = Option(1); //~ ERROR expected function, found enum + | ^^^^^^ + | + = note: did you mean to use one of the following variants? + - `std::prelude::v1::Option::None` + - `std::prelude::v1::Option::Some` + +error[E0532]: expected tuple struct/variant, found enum `Option` + --> $DIR/issue-43871-enum-instead-of-variant.rs:16:12 + | +16 | if let Option(_) = x { //~ ERROR expected tuple struct/variant, found enum + | ^^^^^^ + | + = note: did you mean to use one of the following variants? + - `std::prelude::v1::Option::None` + - `std::prelude::v1::Option::Some` + +error[E0532]: expected tuple struct/variant, found enum `Example` + --> $DIR/issue-43871-enum-instead-of-variant.rs:22:12 + | +22 | if let Example(_) = y { //~ ERROR expected tuple struct/variant, found enum + | ^^^^^^^ + | + = note: did you mean to use one of the following variants? + - `Example::Ex` + - `Example::NotEx` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/did_you_mean/recursion_limit.rs b/src/test/ui/did_you_mean/recursion_limit.rs index becb81b1fff..2d27f167a03 100644 --- a/src/test/ui/did_you_mean/recursion_limit.rs +++ b/src/test/ui/did_you_mean/recursion_limit.rs @@ -41,5 +41,5 @@ enum N { N(usize) } fn is_send<T:Send>() { } fn main() { - is_send::<A>(); + is_send::<A>(); //~ ERROR overflow evaluating the requirement } diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index d157c5de6c7..7fac604ba49 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -1,7 +1,7 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send` --> $DIR/recursion_limit.rs:44:5 | -44 | is_send::<A>(); +44 | is_send::<A>(); //~ ERROR overflow evaluating the requirement | ^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.rs b/src/test/ui/did_you_mean/recursion_limit_deref.rs index ebc56c94adf..3e261ec636c 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.rs +++ b/src/test/ui/did_you_mean/recursion_limit_deref.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//~^^^^^^^^^^ ERROR reached the recursion limit + // Test that the recursion limit can be changed and that the compiler // suggests a fix. In this case, we have a long chain of Deref impls // which will cause an overflow during the autoderef loop. @@ -57,6 +59,7 @@ link!(K, Bottom); fn main() { let t = Top::new(); - let x: &Bottom = &t; + let x: &Bottom = &t; //~ ERROR mismatched types + //~^ error recursion limit } diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index 57b28d03736..951b0b10580 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr @@ -1,7 +1,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing I - --> $DIR/recursion_limit_deref.rs:60:22 + --> $DIR/recursion_limit_deref.rs:62:22 | -60 | let x: &Bottom = &t; +62 | let x: &Bottom = &t; //~ ERROR mismatched types | ^^ deref recursion limit reached | = help: consider adding a `#[recursion_limit="20"]` attribute to your crate @@ -11,9 +11,9 @@ error[E0055]: reached the recursion limit while auto-dereferencing I = help: consider adding a `#[recursion_limit="20"]` attribute to your crate error[E0308]: mismatched types - --> $DIR/recursion_limit_deref.rs:60:22 + --> $DIR/recursion_limit_deref.rs:62:22 | -60 | let x: &Bottom = &t; +62 | let x: &Bottom = &t; //~ ERROR mismatched types | ^^ expected struct `Bottom`, found struct `Top` | = note: expected type `&Bottom` diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.rs b/src/test/ui/did_you_mean/recursion_limit_macro.rs index 9fb82b730c9..16d07f36990 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.rs +++ b/src/test/ui/did_you_mean/recursion_limit_macro.rs @@ -17,7 +17,7 @@ macro_rules! recurse { () => { }; - ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; + ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; //~ ERROR recursion limit } fn main() { diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index 19aac1f77e7..24e223c797b 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -1,7 +1,7 @@ error: recursion limit reached while expanding the macro `recurse` --> $DIR/recursion_limit_macro.rs:20:31 | -20 | ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; +20 | ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; //~ ERROR recursion limit | ^^^^^^^^^^^^^^^^^^^ ... 24 | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs index 11757abae9c..76bc971e115 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs @@ -9,6 +9,7 @@ // except according to those terms. fn main() { - let _: &Copy + 'static; - let _: &'static Copy + 'static; + let _: &Copy + 'static; //~ ERROR expected a path + //~^ ERROR cannot be made into an object + let _: &'static Copy + 'static; //~ ERROR expected a path } diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 498255cb9ea..325a19eee14 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -1,19 +1,19 @@ error[E0178]: expected a path on the left-hand side of `+`, not `&Copy` --> $DIR/trait-object-reference-without-parens-suggestion.rs:12:12 | -12 | let _: &Copy + 'static; +12 | let _: &Copy + 'static; //~ ERROR expected a path | ^^^^^^^^^^^^^^^ help: try adding parentheses: `&(Copy + 'static)` error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy` - --> $DIR/trait-object-reference-without-parens-suggestion.rs:13:12 + --> $DIR/trait-object-reference-without-parens-suggestion.rs:14:12 | -13 | let _: &'static Copy + 'static; +14 | let _: &'static Copy + 'static; //~ ERROR expected a path | ^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'static (Copy + 'static)` error[E0038]: the trait `std::marker::Copy` cannot be made into an object --> $DIR/trait-object-reference-without-parens-suggestion.rs:12:12 | -12 | let _: &Copy + 'static; +12 | let _: &Copy + 'static; //~ ERROR expected a path | ^^^^^ the trait `std::marker::Copy` cannot be made into an object | = note: the trait cannot require that `Self : Sized` diff --git a/src/test/ui/dropck/dropck-eyepatch-extern-crate.rs b/src/test/ui/dropck/dropck-eyepatch-extern-crate.rs index 5e200dbdbfa..f76c2251f8c 100644 --- a/src/test/ui/dropck/dropck-eyepatch-extern-crate.rs +++ b/src/test/ui/dropck/dropck-eyepatch-extern-crate.rs @@ -36,20 +36,23 @@ fn main() { dt = Dt("dt", &c_long); dr = Dr("dr", &c_long); // Error: destructor order imprecisely modelled - dt = Dt("dt", &c); //~ ERROR `c` does not live long enough - dr = Dr("dr", &c); //~ ERROR `c` does not live long enough + dt = Dt("dt", &c); + dr = Dr("dr", &c); // No error: Drop impl asserts .1 (A and &'a _) are not accessed pt = Pt("pt", &c, &c_long); pr = Pr("pr", &c, &c_long); // Error: Drop impl's assertion does not apply to `B` nor `&'b _` - pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough - pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough + pt = Pt("pt", &c_long, &c); + pr = Pr("pr", &c_long, &c); // No error: St and Sr have no destructor. st = St("st", &c); sr = Sr("sr", &c); println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); -} +}//~ ERROR `c` does not live long enough +//~^ ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough diff --git a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr index 62ce3209c91..43d5294c93a 100644 --- a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr @@ -1,10 +1,10 @@ error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-extern-crate.rs:55:1 | -39 | dt = Dt("dt", &c); //~ ERROR `c` does not live long enough +39 | dt = Dt("dt", &c); | - borrow occurs here ... -55 | } +55 | }//~ ERROR `c` does not live long enough | ^ `c` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created @@ -12,10 +12,10 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-extern-crate.rs:55:1 | -40 | dr = Dr("dr", &c); //~ ERROR `c` does not live long enough +40 | dr = Dr("dr", &c); | - borrow occurs here ... -55 | } +55 | }//~ ERROR `c` does not live long enough | ^ `c` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created @@ -23,10 +23,10 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-extern-crate.rs:55:1 | -47 | pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough +47 | pt = Pt("pt", &c_long, &c); | - borrow occurs here ... -55 | } +55 | }//~ ERROR `c` does not live long enough | ^ `c` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created @@ -34,10 +34,10 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-extern-crate.rs:55:1 | -48 | pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough +48 | pr = Pr("pr", &c_long, &c); | - borrow occurs here ... -55 | } +55 | }//~ ERROR `c` does not live long enough | ^ `c` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.rs b/src/test/ui/dropck/dropck-eyepatch-reorder.rs index 68b0ff3b5f0..95ee45a6117 100644 --- a/src/test/ui/dropck/dropck-eyepatch-reorder.rs +++ b/src/test/ui/dropck/dropck-eyepatch-reorder.rs @@ -54,16 +54,16 @@ fn main() { dt = Dt("dt", &c_long); dr = Dr("dr", &c_long); // Error: destructor order imprecisely modelled - dt = Dt("dt", &c); //~ ERROR `c` does not live long enough - dr = Dr("dr", &c); //~ ERROR `c` does not live long enough + dt = Dt("dt", &c); + dr = Dr("dr", &c); // No error: Drop impl asserts .1 (A and &'a _) are not accessed pt = Pt("pt", &c, &c_long); pr = Pr("pr", &c, &c_long); // Error: Drop impl's assertion does not apply to `B` nor `&'b _` - pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough - pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough + pt = Pt("pt", &c_long, &c); + pr = Pr("pr", &c_long, &c); // No error: St and Sr have no destructor. st = St("st", &c); @@ -71,3 +71,7 @@ fn main() { println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); } +//~^ ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr index d94808bbcb6..1ca456c7ba3 100644 --- a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr @@ -1,7 +1,7 @@ error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-reorder.rs:73:1 | -57 | dt = Dt("dt", &c); //~ ERROR `c` does not live long enough +57 | dt = Dt("dt", &c); | - borrow occurs here ... 73 | } @@ -12,7 +12,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-reorder.rs:73:1 | -58 | dr = Dr("dr", &c); //~ ERROR `c` does not live long enough +58 | dr = Dr("dr", &c); | - borrow occurs here ... 73 | } @@ -23,7 +23,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-reorder.rs:73:1 | -65 | pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough +65 | pt = Pt("pt", &c_long, &c); | - borrow occurs here ... 73 | } @@ -34,7 +34,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch-reorder.rs:73:1 | -66 | pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough +66 | pr = Pr("pr", &c_long, &c); | - borrow occurs here ... 73 | } diff --git a/src/test/ui/dropck/dropck-eyepatch.rs b/src/test/ui/dropck/dropck-eyepatch.rs index e442fade197..de94954e921 100644 --- a/src/test/ui/dropck/dropck-eyepatch.rs +++ b/src/test/ui/dropck/dropck-eyepatch.rs @@ -77,16 +77,16 @@ fn main() { dt = Dt("dt", &c_long); dr = Dr("dr", &c_long); // Error: destructor order imprecisely modelled - dt = Dt("dt", &c); //~ ERROR `c` does not live long enough - dr = Dr("dr", &c); //~ ERROR `c` does not live long enough + dt = Dt("dt", &c); + dr = Dr("dr", &c); // No error: Drop impl asserts .1 (A and &'a _) are not accessed pt = Pt("pt", &c, &c_long); pr = Pr("pr", &c, &c_long); // Error: Drop impl's assertion does not apply to `B` nor `&'b _` - pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough - pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough + pt = Pt("pt", &c_long, &c); + pr = Pr("pr", &c_long, &c); // No error: St and Sr have no destructor. st = St("st", &c); @@ -94,3 +94,7 @@ fn main() { println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); } +//~^ ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough +//~| ERROR `c` does not live long enough diff --git a/src/test/ui/dropck/dropck-eyepatch.stderr b/src/test/ui/dropck/dropck-eyepatch.stderr index 811eee0e85f..d41ff374119 100644 --- a/src/test/ui/dropck/dropck-eyepatch.stderr +++ b/src/test/ui/dropck/dropck-eyepatch.stderr @@ -1,7 +1,7 @@ error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch.rs:96:1 | -80 | dt = Dt("dt", &c); //~ ERROR `c` does not live long enough +80 | dt = Dt("dt", &c); | - borrow occurs here ... 96 | } @@ -12,7 +12,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch.rs:96:1 | -81 | dr = Dr("dr", &c); //~ ERROR `c` does not live long enough +81 | dr = Dr("dr", &c); | - borrow occurs here ... 96 | } @@ -23,7 +23,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch.rs:96:1 | -88 | pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough +88 | pt = Pt("pt", &c_long, &c); | - borrow occurs here ... 96 | } @@ -34,7 +34,7 @@ error[E0597]: `c` does not live long enough error[E0597]: `c` does not live long enough --> $DIR/dropck-eyepatch.rs:96:1 | -89 | pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough +89 | pr = Pr("pr", &c_long, &c); | - borrow occurs here ... 96 | } diff --git a/src/test/ui/e0119/complex-impl.rs b/src/test/ui/e0119/complex-impl.rs index f0d2630b9d0..b8b30a28414 100644 --- a/src/test/ui/e0119/complex-impl.rs +++ b/src/test/ui/e0119/complex-impl.rs @@ -16,6 +16,7 @@ use complex_impl_support::{External, M}; struct Q; -impl<R> External for (Q, R) {} +impl<R> External for (Q, R) {} //~ ERROR must be used +//~^ ERROR conflicting implementations of trait -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr index ff7c8a160a4..e4f8020145c 100644 --- a/src/test/ui/e0119/complex-impl.stderr +++ b/src/test/ui/e0119/complex-impl.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `complex_impl_support::External` for type `(Q, complex_impl_support::M<'_, '_, '_, std::boxed::Box<_>, _, _>)`: --> $DIR/complex-impl.rs:19:1 | -19 | impl<R> External for (Q, R) {} +19 | impl<R> External for (Q, R) {} //~ ERROR must be used | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `complex_impl_support`: @@ -11,7 +11,7 @@ error[E0119]: conflicting implementations of trait `complex_impl_support::Extern error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter --> $DIR/complex-impl.rs:19:1 | -19 | impl<R> External for (Q, R) {} +19 | impl<R> External for (Q, R) {} //~ ERROR must be used | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs index ead62256a59..ed9033ad53d 100644 --- a/src/test/ui/e0119/conflict-with-std.rs +++ b/src/test/ui/e0119/conflict-with-std.rs @@ -14,25 +14,25 @@ use std::marker::PhantomData; use std::convert::{TryFrom, AsRef}; struct Q; -impl AsRef<Q> for Box<Q> { +impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations fn as_ref(&self) -> &Q { &**self } } struct S; -impl From<S> for S { +impl From<S> for S { //~ ERROR conflicting implementations fn from(s: S) -> S { s } } struct X; -impl TryFrom<X> for X { +impl TryFrom<X> for X { //~ ERROR conflicting implementations type Error = (); fn try_from(u: X) -> Result<X, ()> { Ok(u) } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index f3e33291ef5..21f2dd05b4d 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`: --> $DIR/conflict-with-std.rs:17:1 | -17 | / impl AsRef<Q> for Box<Q> { +17 | / impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations 18 | | fn as_ref(&self) -> &Q { 19 | | &**self 20 | | } @@ -15,7 +15,7 @@ error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`: --> $DIR/conflict-with-std.rs:24:1 | -24 | / impl From<S> for S { +24 | / impl From<S> for S { //~ ERROR conflicting implementations 25 | | fn from(s: S) -> S { 26 | | s 27 | | } @@ -28,7 +28,7 @@ error[E0119]: conflicting implementations of trait `std::convert::From<S>` for t error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`: --> $DIR/conflict-with-std.rs:31:1 | -31 | / impl TryFrom<X> for X { +31 | / impl TryFrom<X> for X { //~ ERROR conflicting implementations 32 | | type Error = (); 33 | | fn try_from(u: X) -> Result<X, ()> { 34 | | Ok(u) diff --git a/src/test/ui/e0119/issue-23563.rs b/src/test/ui/e0119/issue-23563.rs index 67710af9369..c6d03a4cfc0 100644 --- a/src/test/ui/e0119/issue-23563.rs +++ b/src/test/ui/e0119/issue-23563.rs @@ -20,7 +20,7 @@ use a::LolTo; struct LocalType<T>(Option<T>); -impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { +impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { //~ ERROR conflicting implementations of trait fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) } } @@ -36,4 +36,4 @@ impl LolTo<LocalType<u8>> for [u8] { } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/issue-23563.stderr b/src/test/ui/e0119/issue-23563.stderr index dcb76d71b3d..9dddf193063 100644 --- a/src/test/ui/e0119/issue-23563.stderr +++ b/src/test/ui/e0119/issue-23563.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`: --> $DIR/issue-23563.rs:23:1 | -23 | / impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { +23 | / impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { //~ ERROR conflicting implementations of trait 24 | | fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) } 25 | | } | |_^ diff --git a/src/test/ui/e0119/issue-27403.rs b/src/test/ui/e0119/issue-27403.rs index c880921b65b..98953153faf 100644 --- a/src/test/ui/e0119/issue-27403.rs +++ b/src/test/ui/e0119/issue-27403.rs @@ -12,10 +12,10 @@ pub struct GenX<S> { inner: S, } -impl<S> Into<S> for GenX<S> { +impl<S> Into<S> for GenX<S> { //~ ERROR conflicting implementations fn into(self) -> S { self.inner } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/issue-27403.stderr b/src/test/ui/e0119/issue-27403.stderr index d03171fc10a..68d7235f6aa 100644 --- a/src/test/ui/e0119/issue-27403.stderr +++ b/src/test/ui/e0119/issue-27403.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`: --> $DIR/issue-27403.rs:15:1 | -15 | / impl<S> Into<S> for GenX<S> { +15 | / impl<S> Into<S> for GenX<S> { //~ ERROR conflicting implementations 16 | | fn into(self) -> S { 17 | | self.inner 18 | | } diff --git a/src/test/ui/e0119/issue-28981.rs b/src/test/ui/e0119/issue-28981.rs index 06018286b31..8a52464ff50 100644 --- a/src/test/ui/e0119/issue-28981.rs +++ b/src/test/ui/e0119/issue-28981.rs @@ -12,6 +12,7 @@ use std::ops::Deref; struct Foo; -impl<Foo> Deref for Foo { } +impl<Foo> Deref for Foo { } //~ ERROR must be used +//~^ ERROR conflicting implementations -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr index c6c7c117a42..aac9f7ae964 100644 --- a/src/test/ui/e0119/issue-28981.stderr +++ b/src/test/ui/e0119/issue-28981.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `std::ops::Deref` for type `&_`: --> $DIR/issue-28981.rs:15:1 | -15 | impl<Foo> Deref for Foo { } +15 | impl<Foo> Deref for Foo { } //~ ERROR must be used | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `core`: @@ -11,7 +11,7 @@ error[E0119]: conflicting implementations of trait `std::ops::Deref` for type `& error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter --> $DIR/issue-28981.rs:15:1 | -15 | impl<Foo> Deref for Foo { } +15 | impl<Foo> Deref for Foo { } //~ ERROR must be used | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/e0119/so-37347311.rs b/src/test/ui/e0119/so-37347311.rs index 0d21120eac3..933cdb3cd53 100644 --- a/src/test/ui/e0119/so-37347311.rs +++ b/src/test/ui/e0119/so-37347311.rs @@ -18,10 +18,10 @@ enum MyError<S: Storage> { StorageProblem(S::Error), } -impl<S: Storage> From<S::Error> for MyError<S> { +impl<S: Storage> From<S::Error> for MyError<S> { //~ ERROR conflicting implementations fn from(error: S::Error) -> MyError<S> { MyError::StorageProblem(error) } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/e0119/so-37347311.stderr b/src/test/ui/e0119/so-37347311.stderr index 8a26597a1c2..351c0e1bbb6 100644 --- a/src/test/ui/e0119/so-37347311.stderr +++ b/src/test/ui/e0119/so-37347311.stderr @@ -1,7 +1,7 @@ error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`: --> $DIR/so-37347311.rs:21:1 | -21 | / impl<S: Storage> From<S::Error> for MyError<S> { +21 | / impl<S: Storage> From<S::Error> for MyError<S> { //~ ERROR conflicting implementations 22 | | fn from(error: S::Error) -> MyError<S> { 23 | | MyError::StorageProblem(error) 24 | | } diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr index 58b392f0b8d..1da8833e0f8 100644 --- a/src/test/ui/fmt/format-string-error.stderr +++ b/src/test/ui/fmt/format-string-error.stderr @@ -5,7 +5,7 @@ error: invalid format string: expected `'}'` but string was terminated | ^^^^^^^^^^^^^^ | = note: if you intended to print `{`, you can escape it using `{{` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: invalid format string: unmatched `}` found --> $DIR/format-string-error.rs:14:5 @@ -14,7 +14,7 @@ error: invalid format string: unmatched `}` found | ^^^^^^^^^^^^^^ | = note: if you intended to print `}`, you can escape it using `}}` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs new file mode 100644 index 00000000000..3f13fd2e491 --- /dev/null +++ b/src/test/ui/fmt/send-sync.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn send<T: Send>(_: T) {} +fn sync<T: Sync>(_: T) {} + +fn main() { + // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, + // `std::fmt::Arguments` used to forget this... + let c = std::cell::Cell::new(42); + send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied + sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied +} diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr new file mode 100644 index 00000000000..9e0e563c35f --- /dev/null +++ b/src/test/ui/fmt/send-sync.stderr @@ -0,0 +1,34 @@ +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `[std::fmt::ArgumentV1<'_>]` + --> $DIR/send-sync.rs:18:5 + | +18 | send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>` + = note: required because it appears within the type `core::fmt::Void` + = note: required because it appears within the type `&core::fmt::Void` + = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` + = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` + = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `std::fmt::Arguments<'_>` + = note: required by `send` + +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` + --> $DIR/send-sync.rs:19:5 + | +19 | sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>` + = note: required because it appears within the type `core::fmt::Void` + = note: required because it appears within the type `&core::fmt::Void` + = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` + = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `std::fmt::Arguments<'_>` + = note: required by `sync` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.rs b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs index 87edbb22baa..299106bd552 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.rs +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs @@ -21,8 +21,8 @@ fn foo(x: &i32) { let mut b = move || { yield(); let b = 5; - a = &b; //~ ERROR - }; + a = &b; + }; //~ ERROR } fn main() { } diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr index e30d28c2db8..7310e54925f 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr @@ -1,9 +1,9 @@ error[E0597]: `b` does not live long enough --> $DIR/ref-escapes-but-not-over-yield.rs:25:5 | -24 | a = &b; //~ ERROR +24 | a = &b; | - borrow occurs here -25 | }; +25 | }; //~ ERROR | ^ `b` dropped here while still borrowed 26 | } | - borrowed value needs to live until here diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs index d21c86e8868..504f3e8739f 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.rs +++ b/src/test/ui/generator/yield-while-local-borrowed.rs @@ -19,7 +19,7 @@ fn borrow_local_inline() { // (This error occurs because the region shows up in the type of // `b` and gets extended by region inference.) let mut b = move || { - let a = &3; //~ ERROR + let a = &3; yield(); println!("{}", a); }; diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 96db53ad2e4..36df4f0eb4d 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR no implementation for `u32 + impl Foo` + //~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied } } diff --git a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.rs b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.rs index 0bb944edb9d..9120cdab598 100644 --- a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.rs +++ b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.rs @@ -30,5 +30,4 @@ fn main() { f1.foo(1usize); //~^ error: method named `foo` found for type `Bar` in the current scope //~| help: items from traits can only be used if the trait is implemented and in scope - //~| help: candidate #1: `Foo` } diff --git a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr index 3bc281726ef..29769456849 100644 --- a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `foo` found for type `Bar` in the current scope --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8 | +23 | struct Bar; + | ----------- method `foo` not found for this +... 30 | f1.foo(1usize); | ^^^ | diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.rs b/src/test/ui/impl-trait/method-suggestion-no-duplication.rs index 390b8f07b2f..15ddadf4c51 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.rs +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.rs @@ -18,8 +18,5 @@ fn foo<F>(f: F) where F: FnMut(Foo) {} fn main() { foo(|s| s.is_empty()); //~^ ERROR no method named `is_empty` found - //~^^ HELP #1: `std::iter::ExactSizeIterator` - //~^^^ HELP #2: `core::slice::SliceExt` - //~^^^^ HELP #3: `core::str::StrExt` - //~^^^^^ HELP items from traits can only be used if the trait is implemented and in scope; the following traits define an item `is_empty`, perhaps you need to implement one of them: + //~| HELP items from traits can only be used if the trait is implemented and in scope } diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr index d3dbb77490b..52d3931011a 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `is_empty` found for type `Foo` in the current scope --> $DIR/method-suggestion-no-duplication.rs:19:15 | +14 | struct Foo; + | ----------- method `is_empty` not found for this +... 19 | foo(|s| s.is_empty()); | ^^^^^^^^ | diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.rs b/src/test/ui/impl-trait/no-method-suggested-traits.rs index 15891b00028..d9866772bdd 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.rs +++ b/src/test/ui/impl-trait/no-method-suggested-traits.rs @@ -11,7 +11,12 @@ // aux-build:no_method_suggested_traits.rs extern crate no_method_suggested_traits; -struct Foo; +struct Foo; //~ HELP perhaps add a `use` for it +//~^ HELP perhaps add a `use` for it +//~| HELP perhaps add a `use` for it +//~| HELP perhaps add a `use` for it +//~| HELP perhaps add a `use` for one of them +//~| HELP perhaps add a `use` for one of them enum Bar { X } mod foo { @@ -31,95 +36,65 @@ fn main() { 1u32.method(); - //~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them - //~| ERROR no method named - //~| HELP `use foo::Bar;` - //~| HELP `use no_method_suggested_traits::foo::PubPub;` + //~^ ERROR no method named + //~|items from traits can only be used if the trait is in scope std::rc::Rc::new(&mut Box::new(&1u32)).method(); - //~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them - //~| ERROR no method named - //~| HELP `use foo::Bar;` - //~| HELP `use no_method_suggested_traits::foo::PubPub;` + //~^items from traits can only be used if the trait is in scope + //~| ERROR no method named `method` found for type 'a'.method(); //~^ ERROR no method named - //~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~| HELP `use foo::Bar;` + //~| HELP items from traits can only be used if the trait is in scope std::rc::Rc::new(&mut Box::new(&'a')).method(); //~^ ERROR no method named - //~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~| HELP `use foo::Bar;` + //~| HELP items from traits can only be used if the trait is in scope 1i32.method(); //~^ ERROR no method named - //~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~| HELP `use no_method_suggested_traits::foo::PubPub;` + //~| HELP items from traits can only be used if the trait is in scope std::rc::Rc::new(&mut Box::new(&1i32)).method(); //~^ ERROR no method named - //~| HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~| HELP `use no_method_suggested_traits::foo::PubPub;` + //~| HELP items from traits can only be used if the trait is in scope Foo.method(); //~^ ERROR no method named - //~| HELP following traits define an item `method`, perhaps you need to implement one of them - //~| HELP `foo::Bar` - //~| HELP `no_method_suggested_traits::foo::PubPub` - //~| HELP `no_method_suggested_traits::Reexported` - //~| HELP `no_method_suggested_traits::bar::PubPriv` - //~| HELP `no_method_suggested_traits::qux::PrivPub` - //~| HELP `no_method_suggested_traits::quz::PrivPriv` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&Foo)).method(); //~^ ERROR no method named - //~| HELP following traits define an item `method`, perhaps you need to implement one of them - //~| HELP `foo::Bar` - //~| HELP `no_method_suggested_traits::foo::PubPub` - //~| HELP `no_method_suggested_traits::Reexported` - //~| HELP `no_method_suggested_traits::bar::PubPriv` - //~| HELP `no_method_suggested_traits::qux::PrivPub` - //~| HELP `no_method_suggested_traits::quz::PrivPriv` + //~| HELP items from traits can only be used if the trait is implemented and in scope 1u64.method2(); //~^ ERROR no method named - //~| HELP the following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&1u64)).method2(); //~^ ERROR no method named - //~| HELP the following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope no_method_suggested_traits::Foo.method2(); //~^ ERROR no method named - //~| HELP following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); //~^ ERROR no method named - //~| HELP following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope no_method_suggested_traits::Bar::X.method2(); //~^ ERROR no method named - //~| HELP following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); //~^ ERROR no method named - //~| HELP following trait defines an item `method2`, perhaps you need to implement it - //~| HELP `foo::Bar` + //~| HELP items from traits can only be used if the trait is implemented and in scope Foo.method3(); //~^ ERROR no method named - //~| HELP following trait defines an item `method3`, perhaps you need to implement it - //~| HELP `no_method_suggested_traits::foo::PubPub` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&Foo)).method3(); //~^ ERROR no method named - //~| HELP following trait defines an item `method3`, perhaps you need to implement it - //~| HELP `no_method_suggested_traits::foo::PubPub` + //~| HELP items from traits can only be used if the trait is implemented and in scope Bar::X.method3(); //~^ ERROR no method named - //~| HELP following trait defines an item `method3`, perhaps you need to implement it - //~| HELP `no_method_suggested_traits::foo::PubPub` + //~| HELP items from traits can only be used if the trait is implemented and in scope std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); //~^ ERROR no method named - //~| HELP following trait defines an item `method3`, perhaps you need to implement it - //~| HELP `no_method_suggested_traits::foo::PubPub` + //~| HELP items from traits can only be used if the trait is implemented and in scope // should have no help: 1_usize.method3(); //~ ERROR no method named diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 23f115858cd..2d519c11b94 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -1,38 +1,50 @@ error[E0599]: no method named `method` found for type `u32` in the current scope - --> $DIR/no-method-suggested-traits.rs:33:10 + --> $DIR/no-method-suggested-traits.rs:38:10 | -33 | 1u32.method(); +38 | 1u32.method(); | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following traits are implemented but not in scope, perhaps add a `use` for one of them: - candidate #1: `use foo::Bar;` - candidate #2: `use no_method_suggested_traits::foo::PubPub;` - candidate #3: `use no_method_suggested_traits::qux::PrivPub;` - candidate #4: `use no_method_suggested_traits::Reexported;` +help: the following traits are implemented but not in scope, perhaps add a `use` for one of them: + | +14 | use foo::Bar; + | +14 | use no_method_suggested_traits::foo::PubPub; + | +14 | use no_method_suggested_traits::qux::PrivPub; + | +14 | use no_method_suggested_traits::Reexported; + | error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&u32>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:38:44 + --> $DIR/no-method-suggested-traits.rs:41:44 | -38 | std::rc::Rc::new(&mut Box::new(&1u32)).method(); +41 | std::rc::Rc::new(&mut Box::new(&1u32)).method(); | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following traits are implemented but not in scope, perhaps add a `use` for one of them: - candidate #1: `use foo::Bar;` - candidate #2: `use no_method_suggested_traits::foo::PubPub;` - candidate #3: `use no_method_suggested_traits::qux::PrivPub;` - candidate #4: `use no_method_suggested_traits::Reexported;` +help: the following traits are implemented but not in scope, perhaps add a `use` for one of them: + | +14 | use foo::Bar; + | +14 | use no_method_suggested_traits::foo::PubPub; + | +14 | use no_method_suggested_traits::qux::PrivPub; + | +14 | use no_method_suggested_traits::Reexported; + | error[E0599]: no method named `method` found for type `char` in the current scope - --> $DIR/no-method-suggested-traits.rs:44:9 + --> $DIR/no-method-suggested-traits.rs:45:9 | -44 | 'a'.method(); +45 | 'a'.method(); | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following trait is implemented but not in scope, perhaps add a `use` for it: - candidate #1: `use foo::Bar;` +help: the following trait is implemented but not in scope, perhaps add a `use` for it: + | +14 | use foo::Bar; + | error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope --> $DIR/no-method-suggested-traits.rs:48:43 @@ -41,33 +53,42 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following trait is implemented but not in scope, perhaps add a `use` for it: - candidate #1: `use foo::Bar;` +help: the following trait is implemented but not in scope, perhaps add a `use` for it: + | +14 | use foo::Bar; + | error[E0599]: no method named `method` found for type `i32` in the current scope - --> $DIR/no-method-suggested-traits.rs:53:10 + --> $DIR/no-method-suggested-traits.rs:52:10 | -53 | 1i32.method(); +52 | 1i32.method(); | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following trait is implemented but not in scope, perhaps add a `use` for it: - candidate #1: `use no_method_suggested_traits::foo::PubPub;` +help: the following trait is implemented but not in scope, perhaps add a `use` for it: + | +14 | use no_method_suggested_traits::foo::PubPub; + | error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&i32>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:57:44 + --> $DIR/no-method-suggested-traits.rs:55:44 | -57 | std::rc::Rc::new(&mut Box::new(&1i32)).method(); +55 | std::rc::Rc::new(&mut Box::new(&1i32)).method(); | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following trait is implemented but not in scope, perhaps add a `use` for it: - candidate #1: `use no_method_suggested_traits::foo::PubPub;` +help: the following trait is implemented but not in scope, perhaps add a `use` for it: + | +14 | use no_method_suggested_traits::foo::PubPub; + | error[E0599]: no method named `method` found for type `Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:62:9 + --> $DIR/no-method-suggested-traits.rs:59:9 | -62 | Foo.method(); +14 | struct Foo; //~ HELP perhaps add a `use` for it + | ----------- method `method` not found for this +... +59 | Foo.method(); | ^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -80,9 +101,9 @@ error[E0599]: no method named `method` found for type `Foo` in the current scope candidate #6: `no_method_suggested_traits::Reexported` error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:71:43 + --> $DIR/no-method-suggested-traits.rs:62:43 | -71 | std::rc::Rc::new(&mut Box::new(&Foo)).method(); +62 | std::rc::Rc::new(&mut Box::new(&Foo)).method(); | ^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -95,9 +116,9 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box candidate #6: `no_method_suggested_traits::Reexported` error[E0599]: no method named `method2` found for type `u64` in the current scope - --> $DIR/no-method-suggested-traits.rs:81:10 + --> $DIR/no-method-suggested-traits.rs:66:10 | -81 | 1u64.method2(); +66 | 1u64.method2(); | ^^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -105,9 +126,9 @@ error[E0599]: no method named `method2` found for type `u64` in the current scop candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:85:44 + --> $DIR/no-method-suggested-traits.rs:69:44 | -85 | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); +69 | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); | ^^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -115,9 +136,9 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for type `no_method_suggested_traits::Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:90:37 + --> $DIR/no-method-suggested-traits.rs:73:37 | -90 | no_method_suggested_traits::Foo.method2(); +73 | no_method_suggested_traits::Foo.method2(); | ^^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -125,9 +146,9 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:94:71 + --> $DIR/no-method-suggested-traits.rs:76:71 | -94 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); +76 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); | ^^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -135,9 +156,9 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for type `no_method_suggested_traits::Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:98:40 + --> $DIR/no-method-suggested-traits.rs:79:40 | -98 | no_method_suggested_traits::Bar::X.method2(); +79 | no_method_suggested_traits::Bar::X.method2(); | ^^^^^^^ | = help: items from traits can only be used if the trait is implemented and in scope @@ -145,89 +166,95 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:102:74 - | -102 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); - | ^^^^^^^ - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` + --> $DIR/no-method-suggested-traits.rs:82:74 + | +82 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); + | ^^^^^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method2`, perhaps you need to implement it: + candidate #1: `foo::Bar` error[E0599]: no method named `method3` found for type `Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:107:9 - | -107 | Foo.method3(); - | ^^^^^^^ - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method3`, perhaps you need to implement it: - candidate #1: `no_method_suggested_traits::foo::PubPub` + --> $DIR/no-method-suggested-traits.rs:86:9 + | +14 | struct Foo; //~ HELP perhaps add a `use` for it + | ----------- method `method3` not found for this +... +86 | Foo.method3(); + | ^^^^^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: + candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:111:43 - | -111 | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); - | ^^^^^^^ - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method3`, perhaps you need to implement it: - candidate #1: `no_method_suggested_traits::foo::PubPub` + --> $DIR/no-method-suggested-traits.rs:89:43 + | +89 | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); + | ^^^^^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: + candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:115:12 - | -115 | Bar::X.method3(); - | ^^^^^^^ - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method3`, perhaps you need to implement it: - candidate #1: `no_method_suggested_traits::foo::PubPub` + --> $DIR/no-method-suggested-traits.rs:92:12 + | +20 | enum Bar { X } + | -------- method `method3` not found for this +... +92 | Bar::X.method3(); + | ^^^^^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: + candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:119:46 - | -119 | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); - | ^^^^^^^ - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method3`, perhaps you need to implement it: - candidate #1: `no_method_suggested_traits::foo::PubPub` + --> $DIR/no-method-suggested-traits.rs:95:46 + | +95 | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); + | ^^^^^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: + candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `usize` in the current scope - --> $DIR/no-method-suggested-traits.rs:125:13 + --> $DIR/no-method-suggested-traits.rs:100:13 | -125 | 1_usize.method3(); //~ ERROR no method named +100 | 1_usize.method3(); //~ ERROR no method named | ^^^^^^^ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&usize>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:126:47 + --> $DIR/no-method-suggested-traits.rs:101:47 | -126 | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); //~ ERROR no method named +101 | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); //~ ERROR no method named | ^^^^^^^ error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:127:37 + --> $DIR/no-method-suggested-traits.rs:102:37 | -127 | no_method_suggested_traits::Foo.method3(); //~ ERROR no method named +102 | no_method_suggested_traits::Foo.method3(); //~ ERROR no method named | ^^^^^^^ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:128:71 + --> $DIR/no-method-suggested-traits.rs:103:71 | -128 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); +103 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); | ^^^^^^^ error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:130:40 + --> $DIR/no-method-suggested-traits.rs:105:40 | -130 | no_method_suggested_traits::Bar::X.method3(); //~ ERROR no method named +105 | no_method_suggested_traits::Bar::X.method3(); //~ ERROR no method named | ^^^^^^^ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:131:74 + --> $DIR/no-method-suggested-traits.rs:106:74 | -131 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); +106 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); | ^^^^^^^ error: aborting due to 24 previous errors diff --git a/src/test/ui/impl-trait/trait_type.rs b/src/test/ui/impl-trait/trait_type.rs index 3507dcfbe17..7eefa5c6006 100644 --- a/src/test/ui/impl-trait/trait_type.rs +++ b/src/test/ui/impl-trait/trait_type.rs @@ -15,16 +15,20 @@ struct MyType4; impl std::fmt::Display for MyType { fn fmt(&self, x: &str) -> () { } + //~^ ERROR method `fmt` has an incompatible type } impl std::fmt::Display for MyType2 { fn fmt(&self) -> () { } + //~^ ERROR method `fmt` has 1 parameter } impl std::fmt::Display for MyType3 { fn fmt() -> () { } + //~^ ERROR method `fmt` has a `&self` declaration in the trait } impl std::fmt::Display for MyType4 {} +//~^ ERROR not all trait items fn main() {} diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr index 9216c6e2907..42e1dcdb1c4 100644 --- a/src/test/ui/impl-trait/trait_type.stderr +++ b/src/test/ui/impl-trait/trait_type.stderr @@ -8,25 +8,25 @@ error[E0053]: method `fmt` has an incompatible type for trait found type `fn(&MyType, &str)` error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2 - --> $DIR/trait_type.rs:21:11 + --> $DIR/trait_type.rs:22:11 | -21 | fn fmt(&self) -> () { } +22 | fn fmt(&self) -> () { } | ^^^^^ expected 2 parameters, found 1 | = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in the impl - --> $DIR/trait_type.rs:25:4 + --> $DIR/trait_type.rs:27:4 | -25 | fn fmt() -> () { } +27 | fn fmt() -> () { } | ^^^^^^^^^^^^^^^^^^ expected `&self` in impl | = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` error[E0046]: not all trait items implemented, missing: `fmt` - --> $DIR/trait_type.rs:28:1 + --> $DIR/trait_type.rs:31:1 | -28 | impl std::fmt::Display for MyType4 {} +31 | impl std::fmt::Display for MyType4 {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation | = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` diff --git a/src/test/ui/impl-trait/universal-mismatched-type.rs b/src/test/ui/impl-trait/universal-mismatched-type.rs index af7adc4c657..00fc22ff0d8 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.rs +++ b/src/test/ui/impl-trait/universal-mismatched-type.rs @@ -13,7 +13,7 @@ use std::fmt::Debug; fn foo(x: impl Debug) -> String { - x + x //~ ERROR mismatched types } fn main() { } diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr index 2be24584497..b4dd6c8446c 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.stderr +++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | 15 | fn foo(x: impl Debug) -> String { | ------ expected `std::string::String` because of return type -16 | x +16 | x //~ ERROR mismatched types | ^ expected struct `std::string::String`, found type parameter | = note: expected type `std::string::String` diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.rs b/src/test/ui/impl-trait/universal-two-impl-traits.rs index f8855a79755..9a4847b5606 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.rs +++ b/src/test/ui/impl-trait/universal-two-impl-traits.rs @@ -14,7 +14,7 @@ use std::fmt::Debug; fn foo(x: impl Debug, y: impl Debug) -> String { let mut a = x; - a = y; + a = y; //~ ERROR mismatched format!("{:?}", a) } diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr index c663d38ca8a..9903e26bbbd 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr +++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/universal-two-impl-traits.rs:17:9 | -17 | a = y; +17 | a = y; //~ ERROR mismatched | ^ expected type parameter, found a different type parameter | = note: expected type `impl Debug` (type parameter) diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.rs b/src/test/ui/impl-trait/universal_wrong_bounds.rs index fd35d04b258..36d9f615c5f 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.rs +++ b/src/test/ui/impl-trait/universal_wrong_bounds.rs @@ -15,11 +15,11 @@ use std::fmt::Display; fn foo(f: impl Display + Clone) -> String { wants_debug(f); wants_display(f); - wants_clone(f); + wants_clone(f); //~ ERROR cannot find } -fn wants_debug(g: impl Debug) { } -fn wants_display(g: impl Debug) { } +fn wants_debug(g: impl Debug) { } //~ ERROR cannot find +fn wants_display(g: impl Debug) { } //~ ERROR cannot find fn wants_cone(g: impl Clone) { } fn main() { diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index 600064c71dc..b457e025c29 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -1,13 +1,13 @@ error[E0425]: cannot find function `wants_clone` in this scope --> $DIR/universal_wrong_bounds.rs:18:5 | -18 | wants_clone(f); +18 | wants_clone(f); //~ ERROR cannot find | ^^^^^^^^^^^ did you mean `wants_cone`? error[E0405]: cannot find trait `Debug` in this scope --> $DIR/universal_wrong_bounds.rs:21:24 | -21 | fn wants_debug(g: impl Debug) { } +21 | fn wants_debug(g: impl Debug) { } //~ ERROR cannot find | ^^^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | @@ -17,7 +17,7 @@ help: possible candidate is found in another module, you can import it into scop error[E0405]: cannot find trait `Debug` in this scope --> $DIR/universal_wrong_bounds.rs:22:26 | -22 | fn wants_display(g: impl Debug) { } +22 | fn wants_display(g: impl Debug) { } //~ ERROR cannot find | ^^^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/in-band-lifetimes/E0687.rs b/src/test/ui/in-band-lifetimes/E0687.rs new file mode 100644 index 00000000000..4eddebb15e1 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0687.rs @@ -0,0 +1,26 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: fn(&'a u32)) {} //~ ERROR must be explicitly + +fn bar(x: &Fn(&'a u32)) {} //~ ERROR must be explicitly + +fn baz(x: fn(&'a u32), y: &'a u32) {} //~ ERROR must be explicitly + +struct Foo<'a> { x: &'a u32 } + +impl Foo<'a> { + fn bar(&self, x: fn(&'a u32)) {} //~ ERROR must be explicitly +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/E0687.stderr b/src/test/ui/in-band-lifetimes/E0687.stderr new file mode 100644 index 00000000000..42714f21685 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0687.stderr @@ -0,0 +1,26 @@ +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687.rs:14:15 + | +14 | fn foo(x: fn(&'a u32)) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687.rs:16:16 + | +16 | fn bar(x: &Fn(&'a u32)) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687.rs:18:15 + | +18 | fn baz(x: fn(&'a u32), y: &'a u32) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687.rs:23:26 + | +23 | fn bar(&self, x: fn(&'a u32)) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/in-band-lifetimes/E0687_where.rs b/src/test/ui/in-band-lifetimes/E0687_where.rs new file mode 100644 index 00000000000..ac675587720 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0687_where.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes, universal_impl_trait)] + +fn bar<F>(x: &F) where F: Fn(&'a u32) {} //~ ERROR must be explicitly + +fn baz(x: &impl Fn(&'a u32)) {} //~ ERROR must be explicitly + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/E0687_where.stderr b/src/test/ui/in-band-lifetimes/E0687_where.stderr new file mode 100644 index 00000000000..a9913f6b644 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0687_where.stderr @@ -0,0 +1,14 @@ +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687_where.rs:14:31 + | +14 | fn bar<F>(x: &F) where F: Fn(&'a u32) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error[E0687]: lifetimes used in `fn` or `Fn` syntax must be explicitly declared using `<...>` binders + --> $DIR/E0687_where.rs:16:21 + | +16 | fn baz(x: &impl Fn(&'a u32)) {} //~ ERROR must be explicitly + | ^^ in-band lifetime definition + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/in-band-lifetimes/E0688.rs b/src/test/ui/in-band-lifetimes/E0688.rs new file mode 100644 index 00000000000..29b954e9a83 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0688.rs @@ -0,0 +1,26 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo<'a>(x: &'a u32, y: &'b u32) {} //~ ERROR cannot mix + +struct Foo<'a> { x: &'a u32 } + +impl Foo<'a> { + fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {} //~ ERROR cannot mix +} + +impl<'b> Foo<'a> { //~ ERROR cannot mix + fn baz() {} +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/E0688.stderr b/src/test/ui/in-band-lifetimes/E0688.stderr new file mode 100644 index 00000000000..c33b088f0fa --- /dev/null +++ b/src/test/ui/in-band-lifetimes/E0688.stderr @@ -0,0 +1,26 @@ +error[E0688]: cannot mix in-band and explicit lifetime definitions + --> $DIR/E0688.rs:14:28 + | +14 | fn foo<'a>(x: &'a u32, y: &'b u32) {} //~ ERROR cannot mix + | -- ^^ in-band lifetime definition here + | | + | explicit lifetime definition here + +error[E0688]: cannot mix in-band and explicit lifetime definitions + --> $DIR/E0688.rs:19:44 + | +19 | fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {} //~ ERROR cannot mix + | -- ^^ in-band lifetime definition here + | | + | explicit lifetime definition here + +error[E0688]: cannot mix in-band and explicit lifetime definitions + --> $DIR/E0688.rs:22:14 + | +22 | impl<'b> Foo<'a> { //~ ERROR cannot mix + | -- ^^ in-band lifetime definition here + | | + | explicit lifetime definition here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/in-band-lifetimes/mismatched.rs b/src/test/ui/in-band-lifetimes/mismatched.rs new file mode 100644 index 00000000000..80bc56c0f44 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'a u32, y: &u32) -> &'a u32 { y } //~ ERROR explicit lifetime required + +fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } //~ ERROR lifetime mismatch + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched.stderr b/src/test/ui/in-band-lifetimes/mismatched.stderr new file mode 100644 index 00000000000..0c1231e01de --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched.stderr @@ -0,0 +1,18 @@ +error[E0621]: explicit lifetime required in the type of `y` + --> $DIR/mismatched.rs:14:42 + | +14 | fn foo(x: &'a u32, y: &u32) -> &'a u32 { y } //~ ERROR explicit lifetime required + | - ^ lifetime `'a` required + | | + | consider changing the type of `y` to `&'a u32` + +error[E0623]: lifetime mismatch + --> $DIR/mismatched.rs:16:46 + | +16 | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } //~ ERROR lifetime mismatch + | ------- ------- ^ ...but data from `y` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait.rs b/src/test/ui/in-band-lifetimes/mismatched_trait.rs new file mode 100644 index 00000000000..bc175803ebd --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +trait Get { + fn baz(&self, x: &'a u32, y: &u32) -> &'a u32 { + y //~ ERROR explicit lifetime required + } +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait.stderr new file mode 100644 index 00000000000..58ff1694fb7 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait.stderr @@ -0,0 +1,10 @@ +error[E0621]: explicit lifetime required in the type of `y` + --> $DIR/mismatched_trait.rs:16:9 + | +15 | fn baz(&self, x: &'a u32, y: &u32) -> &'a u32 { + | - consider changing the type of `y` to `&'a u32` +16 | y //~ ERROR explicit lifetime required + | ^ lifetime `'a` required + +error: aborting due to previous error + diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs new file mode 100644 index 00000000000..52641059b1f --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.rs @@ -0,0 +1,24 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +trait Get { + fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; +} + +impl Get for i32 { + fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer + x + } +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr new file mode 100644 index 00000000000..e96f7181a6d --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -0,0 +1,39 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements + --> $DIR/mismatched_trait_impl.rs:19:5 + | +19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer +20 | | x +21 | | } + | |_____^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 19:5... + --> $DIR/mismatched_trait_impl.rs:19:5 + | +19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer +20 | | x +21 | | } + | |_____^ +note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32) + --> $DIR/mismatched_trait_impl.rs:19:5 + | +19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer +20 | | x +21 | | } + | |_____^ +note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5... + --> $DIR/mismatched_trait_impl.rs:19:5 + | +19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer +20 | | x +21 | | } + | |_____^ +note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32) + --> $DIR/mismatched_trait_impl.rs:19:5 + | +19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer +20 | | x +21 | | } + | |_____^ + +error: aborting due to previous error + diff --git a/src/test/ui/in-band-lifetimes/mut_while_borrow.rs b/src/test/ui/in-band-lifetimes/mut_while_borrow.rs new file mode 100644 index 00000000000..08ce13d0bcc --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mut_while_borrow.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'a u32) -> &'a u32 { x } + +fn main() { + let mut p = 3; + let r = foo(&p); + p += 1; //~ ERROR cannot assign to `p` because it is borrowed + println!("{}", r); +} diff --git a/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr b/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr new file mode 100644 index 00000000000..14f9098c6c2 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr @@ -0,0 +1,10 @@ +error[E0506]: cannot assign to `p` because it is borrowed + --> $DIR/mut_while_borrow.rs:19:5 + | +18 | let r = foo(&p); + | - borrow of `p` occurs here +19 | p += 1; //~ ERROR cannot assign to `p` because it is borrowed + | ^^^^^^ assignment to borrowed `p` occurs here + +error: aborting due to previous error + diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.rs b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.rs new file mode 100644 index 00000000000..0d3e6ba644e --- /dev/null +++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.rs @@ -0,0 +1,22 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +struct Foo { + x: &'test u32, //~ ERROR undeclared lifetime +} + +enum Bar { + Baz(&'test u32), //~ ERROR undeclared lifetime +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr new file mode 100644 index 00000000000..a8df6dbca0a --- /dev/null +++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr @@ -0,0 +1,14 @@ +error[E0261]: use of undeclared lifetime name `'test` + --> $DIR/no_in_band_in_struct.rs:15:9 + | +15 | x: &'test u32, //~ ERROR undeclared lifetime + | ^^^^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'test` + --> $DIR/no_in_band_in_struct.rs:19:10 + | +19 | Baz(&'test u32), //~ ERROR undeclared lifetime + | ^^^^^ undeclared lifetime + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs new file mode 100644 index 00000000000..eaa082a35da --- /dev/null +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &u32) { + let y: &'test u32 = x; //~ ERROR use of undeclared lifetime +} + +fn foo2(x: &u32) {} +fn bar() { + let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr new file mode 100644 index 00000000000..e2340dbba23 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -0,0 +1,14 @@ +error[E0261]: use of undeclared lifetime name `'test` + --> $DIR/no_introducing_in_band_in_locals.rs:15:13 + | +15 | let y: &'test u32 = x; //~ ERROR use of undeclared lifetime + | ^^^^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'test` + --> $DIR/no_introducing_in_band_in_locals.rs:20:16 + | +20 | let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime + | ^^^^^ undeclared lifetime + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/in-band-lifetimes/shadow.rs b/src/test/ui/in-band-lifetimes/shadow.rs new file mode 100644 index 00000000000..b6438f01af5 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/shadow.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +struct Foo<T>(T); + +impl Foo<&'s u8> { + fn bar<'s>(&self, x: &'s u8) {} //~ ERROR shadows a lifetime name + fn baz(x: for<'s> fn(&'s u32)) {} //~ ERROR shadows a lifetime name +} + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/shadow.stderr b/src/test/ui/in-band-lifetimes/shadow.stderr new file mode 100644 index 00000000000..49b82fa495a --- /dev/null +++ b/src/test/ui/in-band-lifetimes/shadow.stderr @@ -0,0 +1,19 @@ +error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope + --> $DIR/shadow.rs:17:12 + | +16 | impl Foo<&'s u8> { + | -- first declared here +17 | fn bar<'s>(&self, x: &'s u8) {} //~ ERROR shadows a lifetime name + | ^^ lifetime 's already in scope + +error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope + --> $DIR/shadow.rs:18:19 + | +16 | impl Foo<&'s u8> { + | -- first declared here +17 | fn bar<'s>(&self, x: &'s u8) {} //~ ERROR shadows a lifetime name +18 | fn baz(x: for<'s> fn(&'s u32)) {} //~ ERROR shadows a lifetime name + | ^^ lifetime 's already in scope + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs index 60d85d1b3b7..a772d1f90cc 100644 --- a/src/test/ui/interior-mutability/interior-mutability.rs +++ b/src/test/ui/interior-mutability/interior-mutability.rs @@ -12,5 +12,5 @@ use std::cell::Cell; use std::panic::catch_unwind; fn main() { let mut x = Cell::new(22); - catch_unwind(|| { x.set(23); }); + catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound } diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index 76362f1f494..f4beb44b82d 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::Cell<i32>` --> $DIR/interior-mutability.rs:15:5 | -15 | catch_unwind(|| { x.set(23); }); +15 | catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound | ^^^^^^^^^^^^ the type std::cell::UnsafeCell<i32> may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>` diff --git a/src/test/ui/issue-13483.rs b/src/test/ui/issue-13483.rs index 86378043912..c44465b221c 100644 --- a/src/test/ui/issue-13483.rs +++ b/src/test/ui/issue-13483.rs @@ -10,14 +10,14 @@ fn main() { if true { - } else if { + } else if { //~ ERROR missing condition } else { } } fn foo() { if true { - } else if { + } else if { //~ ERROR missing condition } bar(); } diff --git a/src/test/ui/issue-13483.stderr b/src/test/ui/issue-13483.stderr index 3446969dfd2..344e1796953 100644 --- a/src/test/ui/issue-13483.stderr +++ b/src/test/ui/issue-13483.stderr @@ -1,13 +1,13 @@ error: missing condition for `if` statemement --> $DIR/issue-13483.rs:13:14 | -13 | } else if { +13 | } else if { //~ ERROR missing condition | ^ expected if condition here error: missing condition for `if` statemement --> $DIR/issue-13483.rs:20:14 | -20 | } else if { +20 | } else if { //~ ERROR missing condition | ^ expected if condition here error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-22644.rs b/src/test/ui/issue-22644.rs index c8e0cd1763f..f787e43dbdf 100644 --- a/src/test/ui/issue-22644.rs +++ b/src/test/ui/issue-22644.rs @@ -13,17 +13,19 @@ fn main() { let long_name : usize = 0; println!("{}", a as usize > long_name); - println!("{}", a as usize < long_name); + println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic println!("{}{}", a as usize < long_name, long_name); - println!("{}", a as usize < 4); + //~^ ERROR `<` is interpreted as a start of generic + println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic println!("{}", a: usize > long_name); println!("{}{}", a: usize < long_name, long_name); - println!("{}", a: usize < 4); + //~^ ERROR `<` is interpreted as a start of generic + println!("{}", a: usize < 4); //~ ERROR `<` is interpreted as a start of generic println!("{}", a as usize - < + < //~ ERROR `<` is interpreted as a start of generic 4); println!("{}", a @@ -32,10 +34,10 @@ fn main() { usize - < + < //~ ERROR `<` is interpreted as a start of generic 5); - println!("{}", a as usize << long_name); + println!("{}", a as usize << long_name); //~ ERROR `<` is interpreted as a start of generic - println!("{}", a: &mut 4); + println!("{}", a: &mut 4); //~ ERROR expected type, found `4` } diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 5777c24ae88..91107fbe356 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -1,7 +1,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:16:31 | -16 | println!("{}", a as usize < long_name); +16 | println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic | ---------- ^ --------- interpreted as generic arguments | | | | | not interpreted as comparison @@ -17,75 +17,75 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | help: try comparing the casted value: `(a as usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:18:31 + --> $DIR/issue-22644.rs:19:31 | -18 | println!("{}", a as usize < 4); +19 | println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic | ---------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison | help: try comparing the casted value: `(a as usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:20:31 + --> $DIR/issue-22644.rs:21:31 | -20 | println!("{}{}", a: usize < long_name, long_name); +21 | println!("{}{}", a: usize < long_name, long_name); | -------- ^ -------------------- interpreted as generic arguments | | | | | not interpreted as comparison | help: try comparing the casted value: `(a: usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:21:29 + --> $DIR/issue-22644.rs:23:29 | -21 | println!("{}", a: usize < 4); +23 | println!("{}", a: usize < 4); //~ ERROR `<` is interpreted as a start of generic | -------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison | help: try comparing the casted value: `(a: usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:26:20 + --> $DIR/issue-22644.rs:28:20 | -26 | < +28 | < //~ ERROR `<` is interpreted as a start of generic | ^ not interpreted as comparison -27 | 4); +29 | 4); | - interpreted as generic arguments help: try comparing the casted value | -23 | println!("{}", (a -24 | as -25 | usize) +25 | println!("{}", (a +26 | as +27 | usize) | error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:35:20 + --> $DIR/issue-22644.rs:37:20 | -35 | < +37 | < //~ ERROR `<` is interpreted as a start of generic | ^ not interpreted as comparison -36 | 5); +38 | 5); | - interpreted as generic arguments help: try comparing the casted value | -28 | println!("{}", (a -29 | -30 | -31 | as +30 | println!("{}", (a +31 | 32 | -33 | +33 | as +34 | +35 | ... error: `<` is interpreted as a start of generic arguments for `usize`, not a shift - --> $DIR/issue-22644.rs:38:31 + --> $DIR/issue-22644.rs:40:31 | -38 | println!("{}", a as usize << long_name); +40 | println!("{}", a as usize << long_name); //~ ERROR `<` is interpreted as a start of generic | ---------- ^^ --------- interpreted as generic arguments | | | | | not interpreted as shift | help: try shifting the casted value: `(a as usize)` error: expected type, found `4` - --> $DIR/issue-22644.rs:40:28 + --> $DIR/issue-22644.rs:42:28 | -40 | println!("{}", a: &mut 4); +42 | println!("{}", a: &mut 4); //~ ERROR expected type, found `4` | ^ expecting a type here because of type ascription diff --git a/src/test/ui/issue-33525.rs b/src/test/ui/issue-33525.rs index 0e777fe8a94..0589618a82f 100644 --- a/src/test/ui/issue-33525.rs +++ b/src/test/ui/issue-33525.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - a; - "".lorem; - "".ipsum; + a; //~ ERROR cannot find value `a` + "".lorem; //~ ERROR no field + "".ipsum; //~ ERROR no field } diff --git a/src/test/ui/issue-33525.stderr b/src/test/ui/issue-33525.stderr index 5de2d98f86a..4909340fa4c 100644 --- a/src/test/ui/issue-33525.stderr +++ b/src/test/ui/issue-33525.stderr @@ -1,19 +1,19 @@ error[E0425]: cannot find value `a` in this scope --> $DIR/issue-33525.rs:12:5 | -12 | a; +12 | a; //~ ERROR cannot find value `a` | ^ not found in this scope error[E0609]: no field `lorem` on type `&'static str` --> $DIR/issue-33525.rs:13:8 | -13 | "".lorem; +13 | "".lorem; //~ ERROR no field | ^^^^^ error[E0609]: no field `ipsum` on type `&'static str` --> $DIR/issue-33525.rs:14:8 | -14 | "".ipsum; +14 | "".ipsum; //~ ERROR no field | ^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/issue-33941.rs b/src/test/ui/issue-33941.rs index eb111d33b99..21c169c6638 100644 --- a/src/test/ui/issue-33941.rs +++ b/src/test/ui/issue-33941.rs @@ -11,5 +11,6 @@ use std::collections::HashMap; fn main() { - for _ in HashMap::new().iter().cloned() {} + for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch + //~^ ERROR type mismatch } diff --git a/src/test/ui/issue-33941.stderr b/src/test/ui/issue-33941.stderr index 5a8d1fab3f6..953e6fe77d7 100644 --- a/src/test/ui/issue-33941.stderr +++ b/src/test/ui/issue-33941.stderr @@ -1,7 +1,7 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_` --> $DIR/issue-33941.rs:14:36 | -14 | for _ in HashMap::new().iter().cloned() {} +14 | for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch | ^^^^^^ expected tuple, found reference | = note: expected type `(&_, &_)` @@ -10,7 +10,7 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_` --> $DIR/issue-33941.rs:14:5 | -14 | for _ in HashMap::new().iter().cloned() {} +14 | for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference | = note: expected type `(&_, &_)` diff --git a/src/test/ui/issue-35241.rs b/src/test/ui/issue-35241.rs index 7ec3974854b..4616f25bdfb 100644 --- a/src/test/ui/issue-35241.rs +++ b/src/test/ui/issue-35241.rs @@ -10,6 +10,6 @@ struct Foo(u32); -fn test() -> Foo { Foo } +fn test() -> Foo { Foo } //~ ERROR mismatched types fn main() {} diff --git a/src/test/ui/issue-35241.stderr b/src/test/ui/issue-35241.stderr index bb1bba152bb..25cef738897 100644 --- a/src/test/ui/issue-35241.stderr +++ b/src/test/ui/issue-35241.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-35241.rs:13:20 | -13 | fn test() -> Foo { Foo } +13 | fn test() -> Foo { Foo } //~ ERROR mismatched types | --- ^^^ | | | | | expected struct `Foo`, found fn item diff --git a/src/test/ui/issue-35675.rs b/src/test/ui/issue-35675.rs index 001c1f2eddc..ee9d1324cdb 100644 --- a/src/test/ui/issue-35675.rs +++ b/src/test/ui/issue-35675.rs @@ -12,14 +12,13 @@ enum Fruit { //~ HELP possible candidate is found in another module, you can import it into scope //~^ HELP possible candidate is found in another module, you can import it into scope Apple(i64), - //~^ HELP there is an enum variant `Fruit::Apple`, did you mean to use `Fruit`? - //~| HELP there is an enum variant `Fruit::Apple`, did you mean to use `Fruit`? Orange(i64), } fn should_return_fruit() -> Apple { //~^ ERROR cannot find type `Apple` in this scope //~| NOTE not found in this scope + //~| HELP you can try using the variant's enum Apple(5) //~^ ERROR cannot find function `Apple` in this scope //~| NOTE not found in this scope @@ -28,6 +27,7 @@ fn should_return_fruit() -> Apple { fn should_return_fruit_too() -> Fruit::Apple { //~^ ERROR expected type, found variant `Fruit::Apple` //~| NOTE not a type + //~| HELP you can try using the variant's enum Apple(5) //~^ ERROR cannot find function `Apple` in this scope //~| NOTE not found in this scope @@ -44,6 +44,7 @@ fn foo() -> Ok { fn bar() -> Variant3 { //~^ ERROR cannot find type `Variant3` in this scope //~| NOTE not found in this scope + //~| HELP you can try using the variant's enum } fn qux() -> Some { @@ -61,7 +62,6 @@ mod x { Variant1, Variant2(), Variant3(usize), - //~^ HELP there is an enum variant `x::Enum::Variant3`, did you mean to use `x::Enum`? Variant4 {}, } } diff --git a/src/test/ui/issue-35675.stderr b/src/test/ui/issue-35675.stderr index e125d74e28f..550e094dc51 100644 --- a/src/test/ui/issue-35675.stderr +++ b/src/test/ui/issue-35675.stderr @@ -1,16 +1,16 @@ error[E0412]: cannot find type `Apple` in this scope - --> $DIR/issue-35675.rs:20:29 + --> $DIR/issue-35675.rs:18:29 | -20 | fn should_return_fruit() -> Apple { +18 | fn should_return_fruit() -> Apple { | ^^^^^ | | | not found in this scope | help: you can try using the variant's enum: `Fruit` error[E0425]: cannot find function `Apple` in this scope - --> $DIR/issue-35675.rs:23:5 + --> $DIR/issue-35675.rs:22:5 | -23 | Apple(5) +22 | Apple(5) | ^^^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | @@ -18,9 +18,9 @@ help: possible candidate is found in another module, you can import it into scop | error[E0573]: expected type, found variant `Fruit::Apple` - --> $DIR/issue-35675.rs:28:33 + --> $DIR/issue-35675.rs:27:33 | -28 | fn should_return_fruit_too() -> Fruit::Apple { +27 | fn should_return_fruit_too() -> Fruit::Apple { | ^^^^^^^^^^^^ | | | not a type @@ -55,9 +55,9 @@ error[E0412]: cannot find type `Variant3` in this scope | help: you can try using the variant's enum: `x::Enum` error[E0573]: expected type, found variant `Some` - --> $DIR/issue-35675.rs:49:13 + --> $DIR/issue-35675.rs:50:13 | -49 | fn qux() -> Some { +50 | fn qux() -> Some { | ^^^^ not a type | = help: there is an enum variant `std::prelude::v1::Option::Some`, try using `std::prelude::v1::Option`? diff --git a/src/test/ui/issue-35976.rs b/src/test/ui/issue-35976.rs index 169d7b55916..d45b0c5a041 100644 --- a/src/test/ui/issue-35976.rs +++ b/src/test/ui/issue-35976.rs @@ -23,7 +23,6 @@ mod private { fn bar(arg: Box<private::Future>) { arg.wait(); //~^ ERROR the `wait` method cannot be invoked on a trait object - //~| another candidate was found in the following trait, perhaps add a `use` for it: } fn main() { diff --git a/src/test/ui/issue-35976.stderr b/src/test/ui/issue-35976.stderr index 9fb67449734..146d0ff72d8 100644 --- a/src/test/ui/issue-35976.stderr +++ b/src/test/ui/issue-35976.stderr @@ -3,9 +3,10 @@ error: the `wait` method cannot be invoked on a trait object | 24 | arg.wait(); | ^^^^ +help: another candidate was found in the following trait, perhaps add a `use` for it: + | +11 | use private::Future; | - = note: another candidate was found in the following trait, perhaps add a `use` for it: - candidate #1: `use private::Future;` error: aborting due to previous error diff --git a/src/test/ui/issue-36400.rs b/src/test/ui/issue-36400.rs index c0aec5b4296..fa4361e42aa 100644 --- a/src/test/ui/issue-36400.rs +++ b/src/test/ui/issue-36400.rs @@ -12,5 +12,5 @@ fn f(x: &mut u32) {} fn main() { let x = Box::new(3); - f(&mut *x); + f(&mut *x); //~ ERROR cannot borrow immutable } diff --git a/src/test/ui/issue-36400.stderr b/src/test/ui/issue-36400.stderr index 69e9c455f35..84e6855e23b 100644 --- a/src/test/ui/issue-36400.stderr +++ b/src/test/ui/issue-36400.stderr @@ -3,7 +3,7 @@ error[E0596]: cannot borrow immutable `Box` content `*x` as mutable | 14 | let x = Box::new(3); | - consider changing this to `mut x` -15 | f(&mut *x); +15 | f(&mut *x); //~ ERROR cannot borrow immutable | ^^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/issue-37311-type-length-limit/issue-37311.rs b/src/test/ui/issue-37311-type-length-limit/issue-37311.rs index add96461f1b..1e05bdb0c60 100644 --- a/src/test/ui/issue-37311-type-length-limit/issue-37311.rs +++ b/src/test/ui/issue-37311-type-length-limit/issue-37311.rs @@ -20,7 +20,7 @@ trait Foo { impl<T> Foo for T { #[allow(unconditional_recursion)] - fn recurse(&self) { + fn recurse(&self) { //~ ERROR reached the type-length limit (self, self).recurse(); } } diff --git a/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr index b51b683a1ac..fe173867da1 100644 --- a/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr +++ b/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr @@ -1,7 +1,7 @@ error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&()...` --> $DIR/issue-37311.rs:23:5 | -23 | / fn recurse(&self) { +23 | / fn recurse(&self) { //~ ERROR reached the type-length limit 24 | | (self, self).recurse(); 25 | | } | |_____^ diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs b/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs index 7efa3bd9d5b..f2de2030bd1 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs @@ -16,5 +16,5 @@ struct Foo { fn main() { let mut f = Foo { v: Vec::new() }; f.v.push("hello".to_string()); - let e = f.v[0]; + let e = f.v[0]; //~ ERROR cannot move out of indexed content } diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr index 56d0a5351ce..173a60b0f08 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr @@ -1,7 +1,7 @@ error[E0507]: cannot move out of indexed content --> $DIR/issue-40402-1.rs:19:13 | -19 | let e = f.v[0]; +19 | let e = f.v[0]; //~ ERROR cannot move out of indexed content | ^^^^^^ | | | cannot move out of indexed content diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs b/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs index 76e038b696e..894923605c0 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs @@ -12,5 +12,5 @@ // are nested within a pattern fn main() { let x = vec![(String::new(), String::new())]; - let (a, b) = x[0]; + let (a, b) = x[0]; //~ ERROR cannot move out of indexed content } diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr index 0060b683bba..7b992e376dc 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr @@ -1,7 +1,7 @@ error[E0507]: cannot move out of indexed content --> $DIR/issue-40402-2.rs:15:18 | -15 | let (a, b) = x[0]; +15 | let (a, b) = x[0]; //~ ERROR cannot move out of indexed content | - - ^^^^ cannot move out of indexed content | | | | | ...and here (use `ref b` or `ref mut b`) diff --git a/src/test/ui/issue-40782.rs b/src/test/ui/issue-40782.rs index 56ee225105f..10dc177c7e9 100644 --- a/src/test/ui/issue-40782.rs +++ b/src/test/ui/issue-40782.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - for i 0..2 { + for i 0..2 { //~ ERROR missing `in` } } diff --git a/src/test/ui/issue-40782.stderr b/src/test/ui/issue-40782.stderr index 0d49eebbdbf..543233e0cc6 100644 --- a/src/test/ui/issue-40782.stderr +++ b/src/test/ui/issue-40782.stderr @@ -1,7 +1,7 @@ error: missing `in` in `for` loop --> $DIR/issue-40782.rs:12:10 | -12 | for i 0..2 { +12 | for i 0..2 { //~ ERROR missing `in` | ^ help: try adding `in` here error: aborting due to previous error diff --git a/src/test/ui/issue-42106.rs b/src/test/ui/issue-42106.rs index f13f1dd1145..f35eee186a2 100644 --- a/src/test/ui/issue-42106.rs +++ b/src/test/ui/issue-42106.rs @@ -10,7 +10,7 @@ fn do_something<T>(collection: &mut Vec<T>) { let _a = &collection; - collection.swap(1, 2); + collection.swap(1, 2); //~ ERROR also borrowed as immutable } fn main() {} diff --git a/src/test/ui/issue-42106.stderr b/src/test/ui/issue-42106.stderr index 481cdb5f5b2..0f96377c062 100644 --- a/src/test/ui/issue-42106.stderr +++ b/src/test/ui/issue-42106.stderr @@ -3,7 +3,7 @@ error[E0502]: cannot borrow `*collection` as mutable because `collection` is als | 12 | let _a = &collection; | ---------- immutable borrow occurs here -13 | collection.swap(1, 2); +13 | collection.swap(1, 2); //~ ERROR also borrowed as immutable | ^^^^^^^^^^ mutable borrow occurs here 14 | } | - immutable borrow ends here diff --git a/src/test/ui/issue-42954.rs b/src/test/ui/issue-42954.rs index bdfdf44c0e2..6fa2c69bf66 100644 --- a/src/test/ui/issue-42954.rs +++ b/src/test/ui/issue-42954.rs @@ -10,7 +10,7 @@ macro_rules! is_plainly_printable { ($i: ident) => { - $i as u32 < 0 + $i as u32 < 0 //~ `<` is interpreted as a start of generic arguments }; } diff --git a/src/test/ui/issue-42954.stderr b/src/test/ui/issue-42954.stderr index 7287c8f37eb..d0fc410c474 100644 --- a/src/test/ui/issue-42954.stderr +++ b/src/test/ui/issue-42954.stderr @@ -1,7 +1,7 @@ error: `<` is interpreted as a start of generic arguments for `u32`, not a comparison --> $DIR/issue-42954.rs:13:19 | -13 | $i as u32 < 0 +13 | $i as u32 < 0 //~ `<` is interpreted as a start of generic arguments | --------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison diff --git a/src/test/ui/issue-44023.rs b/src/test/ui/issue-44023.rs index 295d4808289..97b82dc58dc 100644 --- a/src/test/ui/issue-44023.rs +++ b/src/test/ui/issue-44023.rs @@ -12,5 +12,5 @@ pub fn main () {} -fn საჭმელად_გემრიელი_სადილი ( ) -> isize { +fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types } diff --git a/src/test/ui/issue-44023.stderr b/src/test/ui/issue-44023.stderr index a17512ba4ab..fc6363dc921 100644 --- a/src/test/ui/issue-44023.stderr +++ b/src/test/ui/issue-44023.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-44023.rs:15:42 | -15 | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { +15 | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types | __________________________________________^ 16 | | } | |_^ expected isize, found () diff --git a/src/test/ui/issue-44078.rs b/src/test/ui/issue-44078.rs index ef47214f2b3..356a7be0b41 100644 --- a/src/test/ui/issue-44078.rs +++ b/src/test/ui/issue-44078.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - "😊""; + "😊""; //~ ERROR unterminated double quote } diff --git a/src/test/ui/issue-44078.stderr b/src/test/ui/issue-44078.stderr index 2ed4578d538..49e461bd18d 100644 --- a/src/test/ui/issue-44078.stderr +++ b/src/test/ui/issue-44078.stderr @@ -1,7 +1,7 @@ error: unterminated double quote string --> $DIR/issue-44078.rs:12:8 | -12 | "😊""; +12 | "😊""; //~ ERROR unterminated double quote | _________^ 13 | | } | |__^ diff --git a/src/test/ui/issue-44406.rs b/src/test/ui/issue-44406.rs index abf572118fc..8e99caff4ef 100644 --- a/src/test/ui/issue-44406.rs +++ b/src/test/ui/issue-44406.rs @@ -15,5 +15,6 @@ macro_rules! foo { } fn main() { - foo!(true); + foo!(true); //~ ERROR expected type, found keyword + //~^ ERROR expected identifier, found keyword } diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr index e7afbb574ef..2e71b001d7a 100644 --- a/src/test/ui/issue-44406.stderr +++ b/src/test/ui/issue-44406.stderr @@ -1,7 +1,7 @@ error: expected identifier, found keyword `true` --> $DIR/issue-44406.rs:18:10 | -18 | foo!(true); +18 | foo!(true); //~ ERROR expected type, found keyword | ^^^^ error: expected type, found keyword `true` @@ -10,7 +10,7 @@ error: expected type, found keyword `true` 13 | bar(baz: $rest) | - help: did you mean to use `;` here? ... -18 | foo!(true); +18 | foo!(true); //~ ERROR expected type, found keyword | ^^^^ expecting a type here because of type ascription error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.rs b/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.rs index 833fc2802a3..2fce8d723d3 100644 --- a/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.rs +++ b/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.rs @@ -14,13 +14,13 @@ fn main() { unsafe { let f = |v: &mut Vec<_>| { - unsafe { + unsafe { //~ ERROR unnecessary `unsafe` v.set_len(24); - |w: &mut Vec<u32>| { unsafe { + |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` w.set_len(32); } }; } - |x: &mut Vec<u32>| { unsafe { + |x: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` x.set_len(40); } }; }; diff --git a/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.stderr b/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.stderr index be6b1e30a59..abd875c4808 100644 --- a/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.stderr +++ b/src/test/ui/issue-45107-unnecessary-unsafe-in-closure.stderr @@ -1,9 +1,9 @@ error: unnecessary `unsafe` block --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:17:13 | -17 | / unsafe { +17 | / unsafe { //~ ERROR unnecessary `unsafe` 18 | | v.set_len(24); -19 | | |w: &mut Vec<u32>| { unsafe { +19 | | |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` 20 | | w.set_len(32); 21 | | } }; 22 | | } @@ -19,7 +19,7 @@ note: because it's nested under this `unsafe` block | 15 | / unsafe { 16 | | let f = |v: &mut Vec<_>| { -17 | | unsafe { +17 | | unsafe { //~ ERROR unnecessary `unsafe` 18 | | v.set_len(24); ... | 29 | | f(&mut v); @@ -29,7 +29,7 @@ note: because it's nested under this `unsafe` block error: unnecessary `unsafe` block --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:19:38 | -19 | |w: &mut Vec<u32>| { unsafe { +19 | |w: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` | ______________________________________^ 20 | | w.set_len(32); 21 | | } }; @@ -40,7 +40,7 @@ note: because it's nested under this `unsafe` block | 15 | / unsafe { 16 | | let f = |v: &mut Vec<_>| { -17 | | unsafe { +17 | | unsafe { //~ ERROR unnecessary `unsafe` 18 | | v.set_len(24); ... | 29 | | f(&mut v); @@ -50,7 +50,7 @@ note: because it's nested under this `unsafe` block error: unnecessary `unsafe` block --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:23:34 | -23 | |x: &mut Vec<u32>| { unsafe { +23 | |x: &mut Vec<u32>| { unsafe { //~ ERROR unnecessary `unsafe` | __________________________________^ 24 | | x.set_len(40); 25 | | } }; @@ -61,7 +61,7 @@ note: because it's nested under this `unsafe` block | 15 | / unsafe { 16 | | let f = |v: &mut Vec<_>| { -17 | | unsafe { +17 | | unsafe { //~ ERROR unnecessary `unsafe` 18 | | v.set_len(24); ... | 29 | | f(&mut v); diff --git a/src/test/ui/issue-45296.rs b/src/test/ui/issue-45296.rs index 7a2b4e56d69..965747cfa05 100644 --- a/src/test/ui/issue-45296.rs +++ b/src/test/ui/issue-45296.rs @@ -11,5 +11,5 @@ fn main() { let unused = (); - #![allow(unused_variables)] + #![allow(unused_variables)] //~ ERROR not permitted in this context } diff --git a/src/test/ui/issue-45296.stderr b/src/test/ui/issue-45296.stderr index 1a660e4c678..45a80750de7 100644 --- a/src/test/ui/issue-45296.stderr +++ b/src/test/ui/issue-45296.stderr @@ -1,7 +1,7 @@ error: an inner attribute is not permitted in this context --> $DIR/issue-45296.rs:14:7 | -14 | #![allow(unused_variables)] +14 | #![allow(unused_variables)] //~ ERROR not permitted in this context | ^ | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/issue-45730.rs b/src/test/ui/issue-45730.rs index f725d69ca65..d733c8e6de2 100644 --- a/src/test/ui/issue-45730.rs +++ b/src/test/ui/issue-45730.rs @@ -10,10 +10,10 @@ use std::fmt; fn main() { - let x: *const _ = 0 as _; + let x: *const _ = 0 as _; //~ ERROR cannot cast - let x: *const _ = 0 as *const _; + let x: *const _ = 0 as *const _; //~ ERROR cannot cast let y: Option<*const fmt::Debug> = Some(x) as _; - let x = 0 as *const i32 as *const _ as *mut _; + let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast } diff --git a/src/test/ui/issue-45730.stderr b/src/test/ui/issue-45730.stderr index c4f2e856b7b..94d39239117 100644 --- a/src/test/ui/issue-45730.stderr +++ b/src/test/ui/issue-45730.stderr @@ -1,7 +1,7 @@ error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:13:23 | -13 | let x: *const _ = 0 as _; +13 | let x: *const _ = 0 as _; //~ ERROR cannot cast | ^^^^^- | | | help: consider giving more type information @@ -11,7 +11,7 @@ error[E0641]: cannot cast to a pointer of an unknown kind error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:15:23 | -15 | let x: *const _ = 0 as *const _; +15 | let x: *const _ = 0 as *const _; //~ ERROR cannot cast | ^^^^^-------- | | | help: consider giving more type information @@ -21,7 +21,7 @@ error[E0641]: cannot cast to a pointer of an unknown kind error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:18:13 | -18 | let x = 0 as *const i32 as *const _ as *mut _; +18 | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------ | | | help: consider giving more type information diff --git a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.rs b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.rs index 04112c303bd..5ded42e7c97 100644 --- a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.rs +++ b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.rs @@ -17,7 +17,7 @@ fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 { let p: &i32 = &a.field; &*p } else { - &*x + &*x //~ ERROR explicit lifetime } } diff --git a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr index 613c903853a..9bfa72c2f36 100644 --- a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr +++ b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr @@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `x` 15 | fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 { | - consider changing the type of `x` to `&'a i32` ... -20 | &*x +20 | &*x //~ ERROR explicit lifetime | ^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs index 55752f753ef..1705767834f 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs @@ -18,7 +18,7 @@ impl<'a> Foo<'a> { match *self { Foo::Bar(s) => { if s == "test" { - other + other //~ ERROR explicit lifetime } else { self.clone() } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr index d1660a620b6..4c5e37b8f10 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr @@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `other` 17 | fn bar(&self, other: Foo) -> Foo<'a> { | ----- consider changing the type of `other` to `Foo<'a>` ... -21 | other +21 | other //~ ERROR explicit lifetime | ^^^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs index a1716c4e797..964f2f1c003 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { - if x > y { x } else { y } + if x > y { x } else { y } //~ ERROR explicit lifetime } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr index 83716b7791d..457e347faaa 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in the type of `x` | 11 | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { | - consider changing the type of `x` to `&'a i32` -12 | if x > y { x } else { y } +12 | if x > y { x } else { y } //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs index 7bd32d87617..96d5c5bb161 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 { - if x > y { x } else { y } + if x > y { x } else { y } //~ ERROR explicit lifetime } fn main () { } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr index 6d5e94a5e78..8c3592379ef 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in parameter type | 11 | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 { | ------ consider changing type to `(&'a i32, &'a i32)` -12 | if x > y { x } else { y } +12 | if x > y { x } else { y } //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs index 8849f7084b3..5cf52fe79f0 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs @@ -11,7 +11,7 @@ trait Foo { fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { - if x > y { x } else { y } + if x > y { x } else { y } //~ ERROR explicit lifetime } } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr index 4288fdf89a4..d5d1d16a424 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in the type of `x` | 13 | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { | - consider changing the type of `x` to `&'a i32` -14 | if x > y { x } else { y } +14 | if x > y { x } else { y } //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs index 362290ff3fa..3727ddf9129 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs @@ -15,7 +15,7 @@ struct Foo { impl Foo { fn foo<'a>(&'a self, x: &i32) -> &i32 { - if true { &self.field } else { x } + if true { &self.field } else { x } //~ ERROR explicit lifetime } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 95076bfbdc7..23b9c0cf250 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `x` 16 | fn foo<'a>(&'a self, x: &i32) -> &i32 { | - consider changing the type of `x` to `&'a i32` 17 | -18 | if true { &self.field } else { x } +18 | if true { &self.field } else { x } //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs index 36d956a3996..cec73d79ec2 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs @@ -18,7 +18,7 @@ impl Foo for () { fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { - if x > y { x } else { y } + if x > y { x } else { y } //~ ERROR lifetime mismatch } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index cb9a1edf1dd..f418e1c01f2 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -6,7 +6,7 @@ error[E0623]: lifetime mismatch | | | this parameter and the return type are declared with different lifetimes... 20 | -21 | if x > y { x } else { y } +21 | if x > y { x } else { y } //~ ERROR lifetime mismatch | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs index 30239f4c094..5ee2663317e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { - if x > y { x } else { y } + if x > y { x } else { y } //~ ERROR explicit lifetime } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr index 5d1336c7c3a..b28f102cd5a 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in the type of `y` | 11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { | - consider changing the type of `y` to `&'a i32` -12 | if x > y { x } else { y } +12 | if x > y { x } else { y } //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs index 96b733be9b4..4d57c61ba9e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs @@ -15,7 +15,7 @@ struct Foo { impl Foo { fn foo<'a>(&self, x: &'a i32) -> &i32 { - x + x //~ ERROR lifetime mismatch } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index 8af6acc62c4..d26cb6be709 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -6,7 +6,7 @@ error[E0623]: lifetime mismatch | | | this parameter and the return type are declared with different lifetimes... 17 | -18 | x +18 | x //~ ERROR lifetime mismatch | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs index a8ce60c47b6..a6ccf4a53d1 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs @@ -15,7 +15,7 @@ struct Foo { impl Foo { fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { - if true { x } else { self } + if true { x } else { self } //~ ERROR lifetime mismatch } } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index c09de0c33af..0430e4c2715 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -6,7 +6,7 @@ error[E0623]: lifetime mismatch | | | this parameter and the return type are declared with different lifetimes... 17 | -18 | if true { x } else { self } +18 | if true { x } else { self } //~ ERROR lifetime mismatch | ^^^^ ...but data from `self` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs index 098950e13b3..7f5b23728fd 100644 --- a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs +++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(x: &i32, y: &i32) -> &i32 { +fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime if x > y { x } else { y } } diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr index fccc44caac8..7cd5ca65981 100644 --- a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -1,7 +1,7 @@ error[E0106]: missing lifetime specifier --> $DIR/ex1b-return-no-names-if-else.rs:11:29 | -11 | fn foo(x: &i32, y: &i32) -> &i32 { +11 | fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime | ^ expected lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.rs b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.rs index dd34e1aa6d9..f35a7555d70 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.rs +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.rs @@ -13,7 +13,7 @@ struct Ref<'a, T: 'a> { } fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) { - y.push(x); + y.push(x); //~ ERROR explicit lifetime } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr index 8dba0c33f20..7abc093512b 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in the type of `x` | 15 | fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) { | - consider changing the type of `x` to `Ref<'a, i32>` -16 | y.push(x); +16 | y.push(x); //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs index 5d182008209..18a720f345d 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs @@ -14,7 +14,7 @@ fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T) where i32: Foo<'a>, u32: Foo<'b> { - x.push(y); + x.push(y); //~ ERROR explicit lifetime required } fn main() { let x = baz; diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr index 980f14a51d9..ca522596fbf 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr @@ -4,7 +4,7 @@ error[E0621]: explicit lifetime required in the type of `y` 13 | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T) | - consider changing the type of `y` to `&'a T` ... -17 | x.push(y); +17 | x.push(y); //~ ERROR explicit lifetime required | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs index 71a1c865e09..1834395bd3b 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs @@ -13,7 +13,7 @@ struct Ref<'a, T: 'a> { } fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) { - x.push(y); + x.push(y); //~ ERROR explicit lifetime } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr index e529d6ffe46..5d8f2c1decb 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr @@ -3,7 +3,7 @@ error[E0621]: explicit lifetime required in the type of `y` | 15 | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) { | - consider changing the type of `y` to `Ref<'a, i32>` -16 | x.push(y); +16 | x.push(y); //~ ERROR explicit lifetime | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs index 09038d8ce90..6cf626adf82 100644 --- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs @@ -13,7 +13,7 @@ struct Ref<'a, T: 'a> { } fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr index 1ee00997997..69ff29db357 100644 --- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 15 | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) { | -------- -------- these two types are declared with different lifetimes... -16 | x.push(y); +16 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs index cb083f778de..36bd1c32286 100644 --- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs @@ -14,7 +14,7 @@ struct Ref<'a, T: 'a> { fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { let z = Ref { data: y.data }; - x.push(z); + x.push(z); //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr index 495af8ae208..dacb0708b05 100644 --- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr @@ -4,7 +4,7 @@ error[E0623]: lifetime mismatch 15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... 16 | let z = Ref { data: y.data }; -17 | x.push(z); +17 | x.push(z); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs index bcb7583beef..96316819e93 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs @@ -13,7 +13,7 @@ struct Ref<'a, T: 'a> { } fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { - let a: &mut Vec<Ref<i32>> = x; + let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch let b = Ref { data: y.data }; a.push(b); } diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr index 1f250a88847..e30355891ee 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... -16 | let a: &mut Vec<Ref<i32>> = x; +16 | let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs index 2d05adb7ecd..9352ebc77f5 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs @@ -13,7 +13,7 @@ struct Ref<'a, T: 'a> { } fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { - let a: &mut Vec<Ref<i32>> = x; + let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch let b = Ref { data: y.data }; Vec::push(a, b); } diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr index 343c35b871e..841555c1fcb 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... -16 | let a: &mut Vec<Ref<i32>> = x; +16 | let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.rs index 905eae18d18..5d490824d02 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo((v, w): (&u8, &u8), x: &u8) { - v = x; + v = x; //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr index 74a40c87c2f..5e1a4593ae4 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 11 | fn foo((v, w): (&u8, &u8), x: &u8) { | --- --- these two types are declared with different lifetimes... -12 | v = x; +12 | v = x; //~ ERROR lifetime mismatch | ^ ...but data from `x` flows here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.rs index 51271243bdf..fe6b40c05a6 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.rs @@ -9,7 +9,8 @@ // except according to those terms. fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - z.push((x,y)); + z.push((x,y)); //~ ERROR lifetime mismatch + //~^ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr index 898866c75f2..b5b90c077d0 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | --- --- these two types are declared with different lifetimes... -12 | z.push((x,y)); +12 | z.push((x,y)); //~ ERROR lifetime mismatch | ^ ...but data flows into `z` here error[E0623]: lifetime mismatch @@ -11,7 +11,7 @@ error[E0623]: lifetime mismatch | 11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | --- --- these two types are declared with different lifetimes... -12 | z.push((x,y)); +12 | z.push((x,y)); //~ ERROR lifetime mismatch | ^ ...but data flows into `z` here error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs index 2fbf31aead5..f16120ddc22 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs @@ -13,7 +13,7 @@ struct Ref<'a, 'b> { } fn foo(mut x: Ref, y: Ref) { - x.b = y.b; + x.b = y.b; //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr index 26f31defc9e..e7317e63ab4 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 15 | fn foo(mut x: Ref, y: Ref) { | --- --- these two types are declared with different lifetimes... -16 | x.b = y.b; +16 | x.b = y.b; //~ ERROR lifetime mismatch | ^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs index 120a7ca74ae..78e6dc2d3e7 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs @@ -13,7 +13,7 @@ struct Ref<'a, 'b> { } fn foo(mut x: Ref) { - x.a = x.b; + x.a = x.b; //~ ERROR lifetime mismatch } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr index 73460277de4..71eef13a67d 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr @@ -5,7 +5,7 @@ error[E0623]: lifetime mismatch | --- | | | this type is declared with multiple lifetimes... -16 | x.a = x.b; +16 | x.a = x.b; //~ ERROR lifetime mismatch | ^^^ ...but data with one lifetime flows into the other here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.rs index 606e611865f..78e6dc2d3e7 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.rs @@ -13,7 +13,7 @@ struct Ref<'a, 'b> { } fn foo(mut x: Ref) { - x.a = x.b; + x.a = x.b; //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr index fb524ae62c5..61b59b8f121 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr @@ -5,7 +5,7 @@ error[E0623]: lifetime mismatch | --- | | | this type is declared with multiple lifetimes... -16 | x.a = x.b; +16 | x.a = x.b; //~ ERROR lifetime mismatch | ^^^ ...but data with one lifetime flows into the other here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs index 0fef709ae53..ffec0e8d5bb 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs @@ -15,7 +15,7 @@ fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) where &'a (): Sized, &'b u32: Sized { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr index 59bf5d17222..0b1b01d86b8 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr @@ -4,7 +4,7 @@ error[E0623]: lifetime mismatch 14 | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) | ------- ------- these two types are declared with different lifetimes... ... -18 | x.push(y); +18 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs index a91d0b55dc7..16d18f30951 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs @@ -12,7 +12,7 @@ struct Ref<'a> { } fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr index 87835121068..36885b7e076 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 14 | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) { | ------- ------- these two types are declared with different lifetimes... -15 | x.push(y); +15 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs index 67ba8ee532a..3b90b3474a1 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs @@ -12,7 +12,7 @@ struct Ref<'a> { } fn foo(mut x: Vec<Ref>, y: Ref) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr index 6ad795400b3..961b8e310fe 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 14 | fn foo(mut x: Vec<Ref>, y: Ref) { | --- --- these two types are declared with different lifetimes... -15 | x.push(y); +15 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs index 5abfc983f88..966b4f0b6c3 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } -fn main() { } \ No newline at end of file +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr index be628f226d3..b70d26a99d7 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 11 | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) { | ------ ------ these two types are declared with different lifetimes... -12 | x.push(y); +12 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs index a8b1f53fc98..055c3f80468 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs @@ -11,7 +11,7 @@ struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } fn foo(mut x: Ref, y: &u32) { - y = x.b; + y = x.b; //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr index 31c7ebf6504..7a503713063 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr @@ -5,7 +5,7 @@ error[E0623]: lifetime mismatch | --- ---- | | | these two types are declared with different lifetimes... -14 | y = x.b; +14 | y = x.b; //~ ERROR lifetime mismatch | ^^^ ...but data from `x` flows into `y` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs index 4933dbb7e7a..474da4a7d16 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs @@ -11,7 +11,7 @@ struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } fn foo(mut y: Ref, x: &u32) { - y.b = x; + y.b = x; //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr index d54b526aef9..66155bec0bb 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 13 | fn foo(mut y: Ref, x: &u32) { | --- ---- these two types are declared with different lifetimes... -14 | y.b = x; +14 | y.b = x; //~ ERROR lifetime mismatch | ^ ...but data from `x` flows into `y` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs index 4933dbb7e7a..474da4a7d16 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs @@ -11,7 +11,7 @@ struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } fn foo(mut y: Ref, x: &u32) { - y.b = x; + y.b = x; //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr index 40f026bcb1b..d47cffbc622 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 13 | fn foo(mut y: Ref, x: &u32) { | --- ---- these two types are declared with different lifetimes... -14 | y.b = x; +14 | y.b = x; //~ ERROR lifetime mismatch | ^ ...but data from `x` flows into `y` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs index e1594b1a277..1ffaec7ba00 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs @@ -14,7 +14,7 @@ struct Ref<'a, 'b> { } fn foo(mut x: Ref, y: &u32) { - x.b = y; + x.b = y; //~ ERROR lifetime mismatch } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr index bb7b9ea6843..43c85e43e77 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 16 | fn foo(mut x: Ref, y: &u32) { | --- ---- these two types are declared with different lifetimes... -17 | x.b = y; +17 | x.b = y; //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs index 0dc257ac092..97af3598010 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs @@ -14,7 +14,7 @@ struct Foo { impl Foo { fn foo<'a>(&self, x: &i32) -> &i32 { - x + x //~ ERROR lifetime mismatch } } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index 1409b216133..73927f0c1d3 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -5,7 +5,7 @@ error[E0623]: lifetime mismatch | ---- ---- | | | this parameter and the return type are declared with different lifetimes... -17 | x +17 | x //~ ERROR lifetime mismatch | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs index 0940ce15d1e..e6f4f0966ca 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs @@ -14,7 +14,7 @@ struct Foo { impl Foo { fn foo<'a>(&self, x: &Foo) -> &Foo { - if true { x } else { self } + if true { x } else { self } //~ ERROR lifetime mismatch } } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index cae45023e26..edb7ce2d6e9 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -5,7 +5,7 @@ error[E0623]: lifetime mismatch | ---- ---- | | | this parameter and the return type are declared with different lifetimes... -17 | if true { x } else { self } +17 | if true { x } else { self } //~ ERROR lifetime mismatch | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs index 9220c34489f..db53acf5afc 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { - y.push(z); + y.push(z); //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr index adfc4dc0c27..065b669e692 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 10 | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { | --- --- these two types are declared with different lifetimes... -11 | y.push(z); +11 | y.push(z); //~ ERROR lifetime mismatch | ^ ...but data from `z` flows into `y` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs index 3a7ba415c0d..b3ef06f1898 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs @@ -12,7 +12,7 @@ trait Foo { } impl Foo for () { fn foo(x: &mut Vec<&u8>, y: &u8) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } } fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr index 9591df8e8aa..20badfccd8e 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 14 | fn foo(x: &mut Vec<&u8>, y: &u8) { | --- --- these two types are declared with different lifetimes... -15 | x.push(y); +15 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs index 78a6ad54eae..ebde6a3b53f 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) { - y.push(z); + y.push(z); //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr index ce766b2e406..b8a4d9ed24e 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 10 | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) { | --- --- these two types are declared with different lifetimes... -11 | y.push(z); +11 | y.push(z); //~ ERROR lifetime mismatch | ^ ...but data from `z` flows into `y` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions.rs index be48d07b94e..f88eca494eb 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions.rs +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo(x: &mut Vec<&u8>, y: &u8) { - x.push(y); + x.push(y); //~ ERROR lifetime mismatch } fn main() { } diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr index d3291063859..2a30172c43a 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr @@ -3,7 +3,7 @@ error[E0623]: lifetime mismatch | 11 | fn foo(x: &mut Vec<&u8>, y: &u8) { | --- --- these two types are declared with different lifetimes... -12 | x.push(y); +12 | x.push(y); //~ ERROR lifetime mismatch | ^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs index 1c904648f9e..7bf0ed34cbf 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.rs +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs @@ -9,7 +9,7 @@ // except according to those terms. fn f() { - let x = vec![1].iter(); + let x = vec![1].iter(); //~ ERROR does not live long enough } fn main() { diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index 6316c066660..f61595e869d 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -1,7 +1,7 @@ error[E0597]: borrowed value does not live long enough --> $DIR/borrowck-let-suggestion.rs:12:27 | -12 | let x = vec![1].iter(); +12 | let x = vec![1].iter(); //~ ERROR does not live long enough | ------- ^ temporary value dropped here while still borrowed | | | temporary value created here @@ -9,7 +9,7 @@ error[E0597]: borrowed value does not live long enough | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs index 242520cdb32..58c33af0ddd 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs @@ -16,6 +16,7 @@ trait Collection { fn len(&self) -> usize; } struct List<'a, T: ListItem<'a>> { slice: &'a [T] + //~^ ERROR may not live long enough } impl<'a, T: ListItem<'a>> Collection for List<'a, T> { @@ -26,19 +27,24 @@ impl<'a, T: ListItem<'a>> Collection for List<'a, T> { struct Foo<T> { foo: &'static T + //~^ ERROR may not live long enough } trait X<K>: Sized { fn foo<'a, L: X<&'a Nested<K>>>(); + //~^ ERROR may not live long enough // check that we give a sane error for `Self` fn bar<'a, L: X<&'a Nested<Self>>>(); + //~^ ERROR may not live long enough } struct Nested<K>(K); impl<K> Nested<K> { fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { + //~^ ERROR may not live long enough } fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { + //~^ ERROR may not live long enough } } diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index 42e4f28260e..342c6ab8f16 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -13,77 +13,81 @@ note: ...so that the reference type `&'a [T]` does not outlive the data it point | ^^^^^^^^^^^^^^ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:29:5 | -27 | struct Foo<T> { +28 | struct Foo<T> { | - help: consider adding an explicit lifetime bound `T: 'static`... -28 | foo: &'static T +29 | foo: &'static T | ^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'static T` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:28:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:29:5 | -28 | foo: &'static T +29 | foo: &'static T | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:34:5 | -31 | trait X<K>: Sized { +33 | trait X<K>: Sized { | - help: consider adding an explicit lifetime bound `K: 'a`... -32 | fn foo<'a, L: X<&'a Nested<K>>>(); +34 | fn foo<'a, L: X<&'a Nested<K>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:32:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:34:5 | -32 | fn foo<'a, L: X<&'a Nested<K>>>(); +34 | fn foo<'a, L: X<&'a Nested<K>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:34:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:37:5 | -34 | fn bar<'a, L: X<&'a Nested<Self>>>(); +37 | fn bar<'a, L: X<&'a Nested<Self>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:34:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:37:5 | -34 | fn bar<'a, L: X<&'a Nested<Self>>>(); +37 | fn bar<'a, L: X<&'a Nested<Self>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0309]: the parameter type `K` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:39:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:43:5 | -38 | impl<K> Nested<K> { +42 | impl<K> Nested<K> { | - help: consider adding an explicit lifetime bound `K: 'a`... -39 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { -40 | | } +43 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { +44 | | //~^ ERROR may not live long enough +45 | | } | |_____^ | note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:39:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:43:5 | -39 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { -40 | | } +43 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { +44 | | //~^ ERROR may not live long enough +45 | | } | |_____^ error[E0309]: the parameter type `M` may not live long enough - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:46:5 | -41 | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { +46 | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { | ^ -- help: consider adding an explicit lifetime bound `M: 'a`... | _____| | | -42 | | } +47 | | //~^ ERROR may not live long enough +48 | | } | |_____^ | note: ...so that the reference type `&'a Nested<M>` does not outlive the data it points at - --> $DIR/lifetime-doesnt-live-long-enough.rs:41:5 + --> $DIR/lifetime-doesnt-live-long-enough.rs:46:5 | -41 | / fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { -42 | | } +46 | / fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { +47 | | //~^ ERROR may not live long enough +48 | | } | |_____^ error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/command-line-lint-group-deny.rs b/src/test/ui/lint/command-line-lint-group-deny.rs index 1248601c1e4..6ffc9b5aa17 100644 --- a/src/test/ui/lint/command-line-lint-group-deny.rs +++ b/src/test/ui/lint/command-line-lint-group-deny.rs @@ -11,5 +11,5 @@ // compile-flags: -D bad-style fn main() { - let _InappropriateCamelCasing = true; + let _InappropriateCamelCasing = true; //~ ERROR should have a snake } diff --git a/src/test/ui/lint/command-line-lint-group-deny.stderr b/src/test/ui/lint/command-line-lint-group-deny.stderr index 23fac66cc6c..a6182de0a75 100644 --- a/src/test/ui/lint/command-line-lint-group-deny.stderr +++ b/src/test/ui/lint/command-line-lint-group-deny.stderr @@ -1,7 +1,7 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing` --> $DIR/command-line-lint-group-deny.rs:14:9 | -14 | let _InappropriateCamelCasing = true; +14 | let _InappropriateCamelCasing = true; //~ ERROR should have a snake | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D non-snake-case` implied by `-D bad-style` diff --git a/src/test/ui/lint/command-line-lint-group-forbid.rs b/src/test/ui/lint/command-line-lint-group-forbid.rs index ae16db44864..eb4645a4fc8 100644 --- a/src/test/ui/lint/command-line-lint-group-forbid.rs +++ b/src/test/ui/lint/command-line-lint-group-forbid.rs @@ -11,5 +11,5 @@ // compile-flags: -F bad-style fn main() { - let _InappropriateCamelCasing = true; + let _InappropriateCamelCasing = true; //~ ERROR should have a snake } diff --git a/src/test/ui/lint/command-line-lint-group-forbid.stderr b/src/test/ui/lint/command-line-lint-group-forbid.stderr index 0babd7f6fe4..7ae6734c8a3 100644 --- a/src/test/ui/lint/command-line-lint-group-forbid.stderr +++ b/src/test/ui/lint/command-line-lint-group-forbid.stderr @@ -1,7 +1,7 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing` --> $DIR/command-line-lint-group-forbid.rs:14:9 | -14 | let _InappropriateCamelCasing = true; +14 | let _InappropriateCamelCasing = true; //~ ERROR should have a snake | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-F non-snake-case` implied by `-F bad-style` diff --git a/src/test/ui/lint/lint-group-style.rs b/src/test/ui/lint/lint-group-style.rs index 2bd760e417a..9f33f57f48a 100644 --- a/src/test/ui/lint/lint-group-style.rs +++ b/src/test/ui/lint/lint-group-style.rs @@ -11,7 +11,7 @@ #![deny(bad_style)] #![allow(dead_code)] -fn CamelCase() {} +fn CamelCase() {} //~ ERROR should have a snake #[allow(bad_style)] mod test { @@ -19,17 +19,17 @@ mod test { #[forbid(bad_style)] mod bad { - fn CamelCase() {} + fn CamelCase() {} //~ ERROR should have a snake - static bad: isize = 1; + static bad: isize = 1; //~ ERROR should have an upper } mod warn { #![warn(bad_style)] - fn CamelCase() {} + fn CamelCase() {} //~ WARN should have a snake - struct snake_case; + struct snake_case; //~ WARN should have a camel } } diff --git a/src/test/ui/lint/lint-group-style.stderr b/src/test/ui/lint/lint-group-style.stderr index 862e94b873a..3dfe2cee991 100644 --- a/src/test/ui/lint/lint-group-style.stderr +++ b/src/test/ui/lint/lint-group-style.stderr @@ -1,7 +1,7 @@ error: function `CamelCase` should have a snake case name such as `camel_case` --> $DIR/lint-group-style.rs:14:1 | -14 | fn CamelCase() {} +14 | fn CamelCase() {} //~ ERROR should have a snake | ^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -14,7 +14,7 @@ note: lint level defined here error: function `CamelCase` should have a snake case name such as `camel_case` --> $DIR/lint-group-style.rs:22:9 | -22 | fn CamelCase() {} +22 | fn CamelCase() {} //~ ERROR should have a snake | ^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -27,7 +27,7 @@ note: lint level defined here error: static variable `bad` should have an upper case name such as `BAD` --> $DIR/lint-group-style.rs:24:9 | -24 | static bad: isize = 1; +24 | static bad: isize = 1; //~ ERROR should have an upper | ^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -40,7 +40,7 @@ note: lint level defined here warning: function `CamelCase` should have a snake case name such as `camel_case` --> $DIR/lint-group-style.rs:30:9 | -30 | fn CamelCase() {} +30 | fn CamelCase() {} //~ WARN should have a snake | ^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -53,7 +53,7 @@ note: lint level defined here warning: type `snake_case` should have a camel case name such as `SnakeCase` --> $DIR/lint-group-style.rs:32:9 | -32 | struct snake_case; +32 | struct snake_case; //~ WARN should have a camel | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/lint/outer-forbid.rs b/src/test/ui/lint/outer-forbid.rs index a79dacbc1c9..d72f307b461 100644 --- a/src/test/ui/lint/outer-forbid.rs +++ b/src/test/ui/lint/outer-forbid.rs @@ -16,13 +16,13 @@ #![forbid(unused, non_snake_case)] -#[allow(unused_variables)] +#[allow(unused_variables)] //~ ERROR overruled fn foo() {} -#[allow(unused)] +#[allow(unused)] //~ ERROR overruled fn bar() {} -#[allow(bad_style)] +#[allow(bad_style)] //~ ERROR overruled fn main() { println!("hello forbidden world") } diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index 67a1f4f88ad..0bc4e4dcf5f 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -4,7 +4,7 @@ error[E0453]: allow(unused_variables) overruled by outer forbid(unused) 17 | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here 18 | -19 | #[allow(unused_variables)] +19 | #[allow(unused_variables)] //~ ERROR overruled | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: allow(unused) overruled by outer forbid(unused) @@ -13,7 +13,7 @@ error[E0453]: allow(unused) overruled by outer forbid(unused) 17 | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here ... -22 | #[allow(unused)] +22 | #[allow(unused)] //~ ERROR overruled | ^^^^^^ overruled by previous forbid error[E0453]: allow(bad_style) overruled by outer forbid(non_snake_case) @@ -22,7 +22,7 @@ error[E0453]: allow(bad_style) overruled by outer forbid(non_snake_case) 17 | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here ... -25 | #[allow(bad_style)] +25 | #[allow(bad_style)] //~ ERROR overruled | ^^^^^^^^^ overruled by previous forbid error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs index bf2b5769bf8..3789b6dfc8b 100644 --- a/src/test/ui/lint/suggestions.rs +++ b/src/test/ui/lint/suggestions.rs @@ -12,25 +12,34 @@ #![feature(no_debug)] #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub` +//~^ WARN static is marked #[no_mangle] #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const` +//~^ ERROR const items should never be #[no_mangle] #[no_mangle] // should suggest removal (generics can't be no-mangle) pub fn defiant<T>(_t: T) {} +//~^ WARN functions generic over types must be mangled #[no_mangle] fn rio_grande() {} // should suggest `pub` +//~^ WARN function is marked struct Equinox { warp_factor: f32, } #[no_debug] // should suggest removal of deprecated attribute +//~^ WARN deprecated fn main() { while true { // should suggest `loop` + //~^ WARN denote infinite loops let mut a = (1); // should suggest no `mut`, no parens + //~^ WARN does not need to be mutable + //~| WARN unnecessary parentheses let d = Equinox { warp_factor: 9.975 }; match d { Equinox { warp_factor: warp_factor } => {} // should suggest shorthand + //~^ WARN this pattern is redundant } println!("{}", a); } diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index a0014666836..7b84cc1f4b4 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,7 +1,7 @@ warning: unnecessary parentheses around assigned value - --> $DIR/suggestions.rs:30:21 + --> $DIR/suggestions.rs:36:21 | -30 | let mut a = (1); // should suggest no `mut`, no parens +36 | let mut a = (1); // should suggest no `mut`, no parens | ^^^ help: remove these parentheses | note: lint level defined here @@ -11,17 +11,17 @@ note: lint level defined here | ^^^^^^^^^^^^^ warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721 - --> $DIR/suggestions.rs:27:1 + --> $DIR/suggestions.rs:31:1 | -27 | #[no_debug] // should suggest removal of deprecated attribute +31 | #[no_debug] // should suggest removal of deprecated attribute | ^^^^^^^^^^^ help: remove this attribute | = note: #[warn(deprecated)] on by default warning: variable does not need to be mutable - --> $DIR/suggestions.rs:30:13 + --> $DIR/suggestions.rs:36:13 | -30 | let mut a = (1); // should suggest no `mut`, no parens +36 | let mut a = (1); // should suggest no `mut`, no parens | ---^^ | | | help: remove this `mut` @@ -43,9 +43,9 @@ warning: static is marked #[no_mangle], but not exported = note: #[warn(private_no_mangle_statics)] on by default error: const items should never be #[no_mangle] - --> $DIR/suggestions.rs:15:14 + --> $DIR/suggestions.rs:16:14 | -15 | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const` +16 | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const` | -----^^^^^^^^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static` @@ -53,19 +53,19 @@ error: const items should never be #[no_mangle] = note: #[deny(no_mangle_const_items)] on by default warning: functions generic over types must be mangled - --> $DIR/suggestions.rs:18:1 + --> $DIR/suggestions.rs:20:1 | -17 | #[no_mangle] // should suggest removal (generics can't be no-mangle) +19 | #[no_mangle] // should suggest removal (generics can't be no-mangle) | ------------ help: remove this attribute -18 | pub fn defiant<T>(_t: T) {} +20 | pub fn defiant<T>(_t: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: #[warn(no_mangle_generic_items)] on by default warning: function is marked #[no_mangle], but not exported - --> $DIR/suggestions.rs:21:1 + --> $DIR/suggestions.rs:24:1 | -21 | fn rio_grande() {} // should suggest `pub` +24 | fn rio_grande() {} // should suggest `pub` | -^^^^^^^^^^^^^^^^^ | | | help: try making it public: `pub ` @@ -73,27 +73,27 @@ warning: function is marked #[no_mangle], but not exported = note: #[warn(private_no_mangle_fns)] on by default warning: denote infinite loops with `loop { ... }` - --> $DIR/suggestions.rs:29:5 + --> $DIR/suggestions.rs:34:5 | -29 | while true { // should suggest `loop` +34 | while true { // should suggest `loop` | ^--------- | | | _____help: use `loop` | | -30 | | let mut a = (1); // should suggest no `mut`, no parens -31 | | let d = Equinox { warp_factor: 9.975 }; -32 | | match d { +35 | | //~^ WARN denote infinite loops +36 | | let mut a = (1); // should suggest no `mut`, no parens +37 | | //~^ WARN does not need to be mutable ... | -35 | | println!("{}", a); -36 | | } +44 | | println!("{}", a); +45 | | } | |_____^ | = note: #[warn(while_true)] on by default warning: the `warp_factor:` in this pattern is redundant - --> $DIR/suggestions.rs:33:23 + --> $DIR/suggestions.rs:41:23 | -33 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand +41 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand | ------------^^^^^^^^^^^^ | | | help: remove this diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index e166f7011b5..fe113eda3dd 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -87,5 +87,17 @@ "rendered": null } ], - "rendered": null + "rendered": "warning: unnecessary parentheses around assigned value + --> $DIR/unused_parens_json_suggestion.rs:24:14 + | +24 | let _a = (1 / (2 + 3)); + | ^^^^^^^^^^^^^ help: remove these parentheses + | +note: lint level defined here + --> $DIR/unused_parens_json_suggestion.rs:19:9 + | +19 | #![warn(unused_parens)] + | ^^^^^^^^^^^^^ + +" } diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index fd3b5fe1ada..846d7df445d 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -2,7 +2,72 @@ "message": "cannot find type `Iter` in this scope", "code": { "code": "E0412", - "explanation": "/nThe type name used is not in scope./n/nErroneous code examples:/n/n```compile_fail,E0412/nimpl Something {} // error: type name `Something` is not in scope/n/n// or:/n/ntrait Foo {/n fn bar(N); // error: type name `N` is not in scope/n}/n/n// or:/n/nfn foo(x: T) {} // type name `T` is not in scope/n```/n/nTo fix this error, please verify you didn't misspell the type name, you did/ndeclare it or imported it into the scope. Examples:/n/n```/nstruct Something;/n/nimpl Something {} // ok!/n/n// or:/n/ntrait Foo {/n type N;/n/n fn bar(_: Self::N); // ok!/n}/n/n// or:/n/nfn foo<T>(x: T) {} // ok!/n```/n/nAnother case that causes this error is when a type is imported into a parent/nmodule. To fix this, you can follow the suggestion and use File directly or/n`use super::File;` which will import the types from the parent namespace. An/nexample that causes this error is below:/n/n```compile_fail,E0412/nuse std::fs::File;/n/nmod foo {/n fn some_function(f: File) {}/n}/n```/n/n```/nuse std::fs::File;/n/nmod foo {/n // either/n use super::File;/n // or/n // use std::fs::File;/n fn foo(f: File) {}/n}/n# fn main() {} // don't insert it for us; that'll break imports/n```/n" + "explanation": " +The type name used is not in scope. + +Erroneous code examples: + +```compile_fail,E0412 +impl Something {} // error: type name `Something` is not in scope + +// or: + +trait Foo { + fn bar(N); // error: type name `N` is not in scope +} + +// or: + +fn foo(x: T) {} // type name `T` is not in scope +``` + +To fix this error, please verify you didn't misspell the type name, you did +declare it or imported it into the scope. Examples: + +``` +struct Something; + +impl Something {} // ok! + +// or: + +trait Foo { + type N; + + fn bar(_: Self::N); // ok! +} + +// or: + +fn foo<T>(x: T) {} // ok! +``` + +Another case that causes this error is when a type is imported into a parent +module. To fix this, you can follow the suggestion and use File directly or +`use super::File;` which will import the types from the parent namespace. An +example that causes this error is below: + +```compile_fail,E0412 +use std::fs::File; + +mod foo { + fn some_function(f: File) {} +} +``` + +``` +use std::fs::File; + +mod foo { + // either + use super::File; + // or + // use std::fs::File; + fn foo(f: File) {} +} +# fn main() {} // don't insert it for us; that'll break imports +``` +" }, "level": "error", "spans": [ @@ -50,7 +115,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::binary_heap::Iter;/n/n", + "suggested_replacement": "use std::collections::binary_heap::Iter; + +", "expansion": null }, { @@ -70,7 +137,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::btree_map::Iter;/n/n", + "suggested_replacement": "use std::collections::btree_map::Iter; + +", "expansion": null }, { @@ -90,7 +159,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::btree_set::Iter;/n/n", + "suggested_replacement": "use std::collections::btree_set::Iter; + +", "expansion": null }, { @@ -110,7 +181,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::hash_map::Iter;/n/n", + "suggested_replacement": "use std::collections::hash_map::Iter; + +", "expansion": null }, { @@ -130,7 +203,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::hash_set::Iter;/n/n", + "suggested_replacement": "use std::collections::hash_set::Iter; + +", "expansion": null }, { @@ -150,7 +225,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::linked_list::Iter;/n/n", + "suggested_replacement": "use std::collections::linked_list::Iter; + +", "expansion": null }, { @@ -170,7 +247,9 @@ } ], "label": null, - "suggested_replacement": "use std::collections::vec_deque::Iter;/n/n", + "suggested_replacement": "use std::collections::vec_deque::Iter; + +", "expansion": null }, { @@ -190,7 +269,9 @@ } ], "label": null, - "suggested_replacement": "use std::option::Iter;/n/n", + "suggested_replacement": "use std::option::Iter; + +", "expansion": null }, { @@ -210,7 +291,9 @@ } ], "label": null, - "suggested_replacement": "use std::path::Iter;/n/n", + "suggested_replacement": "use std::path::Iter; + +", "expansion": null }, { @@ -230,7 +313,9 @@ } ], "label": null, - "suggested_replacement": "use std::result::Iter;/n/n", + "suggested_replacement": "use std::result::Iter; + +", "expansion": null }, { @@ -250,7 +335,9 @@ } ], "label": null, - "suggested_replacement": "use std::slice::Iter;/n/n", + "suggested_replacement": "use std::slice::Iter; + +", "expansion": null }, { @@ -270,7 +357,9 @@ } ], "label": null, - "suggested_replacement": "use std::sync::mpsc::Iter;/n/n", + "suggested_replacement": "use std::sync::mpsc::Iter; + +", "expansion": null } ], @@ -278,7 +367,24 @@ "rendered": null } ], - "rendered": null + "rendered": "error[E0412]: cannot find type `Iter` in this scope + --> $DIR/use_suggestion_json.rs:20:12 + | +20 | let x: Iter; + | ^^^^ not found in this scope +help: possible candidates are found in other modules, you can import them into scope + | +19 | use std::collections::binary_heap::Iter; + | +19 | use std::collections::btree_map::Iter; + | +19 | use std::collections::btree_set::Iter; + | +19 | use std::collections::hash_map::Iter; + | +and 8 other candidates + +" } { "message": "aborting due to previous error", @@ -286,5 +392,7 @@ "level": "error", "spans": [], "children": [], - "rendered": null + "rendered": "error: aborting due to previous error + +" } diff --git a/src/test/ui/loop-break-value-no-repeat.rs b/src/test/ui/loop-break-value-no-repeat.rs index b52d540fd75..f24840eca54 100644 --- a/src/test/ui/loop-break-value-no-repeat.rs +++ b/src/test/ui/loop-break-value-no-repeat.rs @@ -19,6 +19,6 @@ use std::ptr; fn main() { for _ in &[1,2,3] { - break 22 + break 22 //~ ERROR `break` with value from a `for` loop } } diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr index c154ea6f8c2..296b3b191e3 100644 --- a/src/test/ui/loop-break-value-no-repeat.stderr +++ b/src/test/ui/loop-break-value-no-repeat.stderr @@ -1,7 +1,7 @@ error[E0571]: `break` with value from a `for` loop --> $DIR/loop-break-value-no-repeat.rs:22:9 | -22 | break 22 +22 | break 22 //~ ERROR `break` with value from a `for` loop | ^^^^^^^^ can only break with a value inside `loop` error: aborting due to previous error diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs index 85c90bb375f..7526b2f946c 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs @@ -15,7 +15,7 @@ fn foo( x: fn(&u8, &u8), y: for<'a> fn(&'a u8, &'a u8), ) { - let z = match 22 { + let z = match 22 { //~ ERROR incompatible types 0 => x, _ => y, }; diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr index 4a310a5e6b2..72d9787b93a 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -1,7 +1,7 @@ error[E0308]: match arms have incompatible types --> $DIR/old-lub-glb-hr.rs:18:13 | -18 | let z = match 22 { +18 | let z = match 22 { //~ ERROR incompatible types | _____________^ 19 | | 0 => x, 20 | | _ => y, diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs index 7cf89b68be1..63dcfa3fc1e 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.rs +++ b/src/test/ui/lub-glb/old-lub-glb-object.rs @@ -17,7 +17,7 @@ fn foo( x: &for<'a, 'b> Foo<&'a u8, &'b u8>, y: &for<'a> Foo<&'a u8, &'a u8>, ) { - let z = match 22 { + let z = match 22 { //~ ERROR incompatible types 0 => x, _ => y, }; diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr index a1077f40bf5..852f74b4e75 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr @@ -1,7 +1,7 @@ error[E0308]: match arms have incompatible types --> $DIR/old-lub-glb-object.rs:20:13 | -20 | let z = match 22 { +20 | let z = match 22 { //~ ERROR incompatible types | _____________^ 21 | | 0 => x, 22 | | _ => y, diff --git a/src/test/ui/macro_backtrace/auxiliary/ping.rs b/src/test/ui/macro_backtrace/auxiliary/ping.rs new file mode 100644 index 00000000000..eeed0d78158 --- /dev/null +++ b/src/test/ui/macro_backtrace/auxiliary/ping.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the macro backtrace facility works (supporting file) + +// a non-local macro +#[macro_export] +macro_rules! ping { + () => { + pong!(); + } +} + diff --git a/src/test/ui/macro_backtrace/main.rs b/src/test/ui/macro_backtrace/main.rs new file mode 100644 index 00000000000..ec9218e3ec0 --- /dev/null +++ b/src/test/ui/macro_backtrace/main.rs @@ -0,0 +1,26 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the macro backtrace facility works +// aux-build:ping.rs +// compile-flags: -Z external-macro-backtrace + +#[macro_use] extern crate ping; + +// a local macro +macro_rules! pong { + () => { syntax error }; //~ ERROR expected one of + //~^ ERROR expected one of +} + +fn main() { + pong!(); + ping!(); +} diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr new file mode 100644 index 00000000000..e8434a79f44 --- /dev/null +++ b/src/test/ui/macro_backtrace/main.stderr @@ -0,0 +1,21 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` + --> $DIR/main.rs:19:20 + | +19 | () => { syntax error }; //~ ERROR expected one of + | -^^^^^ unexpected token + | | + | expected one of 8 possible tokens here +$DIR/main.rs:24:5: 24:13 note: in this expansion of pong! (defined in $DIR/main.rs) + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` + --> $DIR/main.rs:19:20 + | +19 | () => { syntax error }; //~ ERROR expected one of + | -^^^^^ unexpected token + | | + | expected one of 8 possible tokens here +$DIR/main.rs:25:5: 25:13 note: in this expansion of ping! (defined in <ping macros>) +<ping macros>:1:11: 1:24 note: in this expansion of pong! (defined in $DIR/main.rs) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/macros/bad_hello.rs b/src/test/ui/macros/bad_hello.rs index a18771deace..174dcc9b6cd 100644 --- a/src/test/ui/macros/bad_hello.rs +++ b/src/test/ui/macros/bad_hello.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - println!(3 + 4); + println!(3 + 4); //~ ERROR expected a literal } diff --git a/src/test/ui/macros/bad_hello.stderr b/src/test/ui/macros/bad_hello.stderr index bffb33f468f..825aa64e40f 100644 --- a/src/test/ui/macros/bad_hello.stderr +++ b/src/test/ui/macros/bad_hello.stderr @@ -1,7 +1,7 @@ error: expected a literal --> $DIR/bad_hello.rs:12:14 | -12 | println!(3 + 4); +12 | println!(3 + 4); //~ ERROR expected a literal | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/macros/format-foreign.rs b/src/test/ui/macros/format-foreign.rs index cca45ca9ecd..91ca8f5ff76 100644 --- a/src/test/ui/macros/format-foreign.rs +++ b/src/test/ui/macros/format-foreign.rs @@ -10,11 +10,11 @@ fn main() { println!("%.*3$s %s!\n", "Hello,", "World", 4); - println!("%1$*2$.*3$f", 123.456); + println!("%1$*2$.*3$f", 123.456); //~ ERROR never used // This should *not* produce hints, on the basis that there's equally as // many "correct" format specifiers. It's *probably* just an actual typo. - println!("{} %f", "one", 2.0); + println!("{} %f", "one", 2.0); //~ ERROR never used - println!("Hi there, $NAME.", NAME="Tim"); + println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used } diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index 00469b5f799..95f348b8b8b 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -11,12 +11,12 @@ error: multiple unused formatting arguments = help: `%.*3$s` should be written as `{:.2$}` = help: `%s` should be written as `{}` = note: printf formatting not supported; see the documentation for `std::fmt` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: argument never used --> $DIR/format-foreign.rs:13:29 | -13 | println!("%1$*2$.*3$f", 123.456); +13 | println!("%1$*2$.*3$f", 123.456); //~ ERROR never used | ^^^^^^^ | = help: `%1$*2$.*3$f` should be written as `{0:1$.2$}` @@ -25,13 +25,13 @@ error: argument never used error: argument never used --> $DIR/format-foreign.rs:17:30 | -17 | println!("{} %f", "one", 2.0); +17 | println!("{} %f", "one", 2.0); //~ ERROR never used | ^^^ error: named argument never used --> $DIR/format-foreign.rs:19:39 | -19 | println!("Hi there, $NAME.", NAME="Tim"); +19 | println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used | ^^^^^ | = help: `$NAME` should be written as `{NAME}` diff --git a/src/test/ui/macros/format-unused-lables.rs b/src/test/ui/macros/format-unused-lables.rs index f1e349ea9f4..7a32d932ba3 100644 --- a/src/test/ui/macros/format-unused-lables.rs +++ b/src/test/ui/macros/format-unused-lables.rs @@ -17,7 +17,7 @@ fn main() { 789 ); - println!("Some stuff", UNUSED="args"); + println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used println!("Some more $STUFF", "woo!", diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index bd6d38ccb0a..01d3577a7c9 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -8,7 +8,7 @@ error: multiple unused formatting arguments | | unused | unused | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: multiple unused formatting arguments --> $DIR/format-unused-lables.rs:14:5 @@ -23,12 +23,12 @@ error: multiple unused formatting arguments 18 | | ); | |______^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: named argument never used --> $DIR/format-unused-lables.rs:20:35 | -20 | println!("Some stuff", UNUSED="args"); +20 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used | ^^^^^^ error: multiple unused formatting arguments @@ -47,7 +47,7 @@ error: multiple unused formatting arguments | = help: `$STUFF` should be written as `{STUFF}` = note: shell formatting not supported; see the documentation for `std::fmt` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.rs b/src/test/ui/macros/macro-backtrace-invalid-internals.rs index 546e06b6c79..037f0d839e2 100644 --- a/src/test/ui/macros/macro-backtrace-invalid-internals.rs +++ b/src/test/ui/macros/macro-backtrace-invalid-internals.rs @@ -12,37 +12,37 @@ macro_rules! fake_method_stmt { () => { - 1.fake() + 1.fake() //~ ERROR no method } } macro_rules! fake_field_stmt { () => { - 1.fake + 1.fake //~ ERROR doesn't have fields } } macro_rules! fake_anon_field_stmt { () => { - (1).0 + (1).0 //~ ERROR no field } } macro_rules! fake_method_expr { () => { - 1.fake() + 1.fake() //~ ERROR no method } } macro_rules! fake_field_expr { () => { - 1.fake + 1.fake //~ ERROR doesn't have fields } } macro_rules! fake_anon_field_expr { () => { - (1).0 + (1).0 //~ ERROR no field } } diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr index c80c0fce358..42144f63c37 100644 --- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr +++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr @@ -1,7 +1,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current scope --> $DIR/macro-backtrace-invalid-internals.rs:15:13 | -15 | 1.fake() +15 | 1.fake() //~ ERROR no method | ^^^^ ... 50 | fake_method_stmt!(); @@ -10,7 +10,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:21:13 | -21 | 1.fake +21 | 1.fake //~ ERROR doesn't have fields | ^^^^ ... 51 | fake_field_stmt!(); @@ -19,7 +19,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields error[E0609]: no field `0` on type `{integer}` --> $DIR/macro-backtrace-invalid-internals.rs:27:11 | -27 | (1).0 +27 | (1).0 //~ ERROR no field | ^^^^^ ... 52 | fake_anon_field_stmt!(); @@ -28,7 +28,7 @@ error[E0609]: no field `0` on type `{integer}` error[E0599]: no method named `fake` found for type `{integer}` in the current scope --> $DIR/macro-backtrace-invalid-internals.rs:33:13 | -33 | 1.fake() +33 | 1.fake() //~ ERROR no method | ^^^^ ... 54 | let _ = fake_method_expr!(); @@ -37,7 +37,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/macro-backtrace-invalid-internals.rs:39:13 | -39 | 1.fake +39 | 1.fake //~ ERROR doesn't have fields | ^^^^ ... 55 | let _ = fake_field_expr!(); @@ -46,7 +46,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields error[E0609]: no field `0` on type `{integer}` --> $DIR/macro-backtrace-invalid-internals.rs:45:11 | -45 | (1).0 +45 | (1).0 //~ ERROR no field | ^^^^^ ... 56 | let _ = fake_anon_field_expr!(); diff --git a/src/test/ui/macros/macro-backtrace-nested.rs b/src/test/ui/macros/macro-backtrace-nested.rs index d8bf6222c1c..d261633c60c 100644 --- a/src/test/ui/macros/macro-backtrace-nested.rs +++ b/src/test/ui/macros/macro-backtrace-nested.rs @@ -12,7 +12,8 @@ // we replace the span of the expanded expression with that of the call site. macro_rules! nested_expr { - () => (fake) + () => (fake) //~ ERROR cannot find + //~^ ERROR cannot find } macro_rules! call_nested_expr { diff --git a/src/test/ui/macros/macro-backtrace-nested.stderr b/src/test/ui/macros/macro-backtrace-nested.stderr index 8b69d112d4d..ee4a38312e2 100644 --- a/src/test/ui/macros/macro-backtrace-nested.stderr +++ b/src/test/ui/macros/macro-backtrace-nested.stderr @@ -1,19 +1,19 @@ error[E0425]: cannot find value `fake` in this scope --> $DIR/macro-backtrace-nested.rs:15:12 | -15 | () => (fake) +15 | () => (fake) //~ ERROR cannot find | ^^^^ not found in this scope ... -27 | 1 + call_nested_expr!(); +28 | 1 + call_nested_expr!(); | ------------------- in this macro invocation error[E0425]: cannot find value `fake` in this scope --> $DIR/macro-backtrace-nested.rs:15:12 | -15 | () => (fake) +15 | () => (fake) //~ ERROR cannot find | ^^^^ not found in this scope ... -28 | call_nested_expr_sum!(); +29 | call_nested_expr_sum!(); | ------------------------ in this macro invocation error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/macro-backtrace-println.rs b/src/test/ui/macros/macro-backtrace-println.rs index baf276919a5..6f035bc9d23 100644 --- a/src/test/ui/macros/macro-backtrace-println.rs +++ b/src/test/ui/macros/macro-backtrace-println.rs @@ -21,7 +21,7 @@ macro_rules! myprint { } macro_rules! myprintln { - ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); + ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ ERROR no arguments were given } fn main() { diff --git a/src/test/ui/macros/macro-backtrace-println.stderr b/src/test/ui/macros/macro-backtrace-println.stderr index 3e782294484..c587654d880 100644 --- a/src/test/ui/macros/macro-backtrace-println.stderr +++ b/src/test/ui/macros/macro-backtrace-println.stderr @@ -1,7 +1,7 @@ error: 1 positional argument in format string, but no arguments were given --> $DIR/macro-backtrace-println.rs:24:30 | -24 | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); +24 | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); //~ ERROR no arguments were given | ^^^^^^^^^^^^^^^^^^^ ... 28 | myprintln!("{}"); diff --git a/src/test/ui/macros/macro-name-typo.rs b/src/test/ui/macros/macro-name-typo.rs index ec8d27f9138..7fadbf2a90b 100644 --- a/src/test/ui/macros/macro-name-typo.rs +++ b/src/test/ui/macros/macro-name-typo.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - printlx!("oh noes!"); + printlx!("oh noes!"); //~ ERROR cannot find } diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index 7c83250fe8a..84851749c70 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -1,7 +1,7 @@ error: cannot find macro `printlx!` in this scope --> $DIR/macro-name-typo.rs:12:5 | -12 | printlx!("oh noes!"); +12 | printlx!("oh noes!"); //~ ERROR cannot find | ^^^^^^^ help: you could try the macro: `println!` error: aborting due to previous error diff --git a/src/test/ui/macros/macro_path_as_generic_bound.rs b/src/test/ui/macros/macro_path_as_generic_bound.rs index 781ea30ed8b..85cf597489d 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.rs +++ b/src/test/ui/macros/macro_path_as_generic_bound.rs @@ -14,6 +14,6 @@ macro_rules! foo(($t:path) => { impl<T: $t> Foo for T {} }); -foo!(m::m2::A); +foo!(m::m2::A); //~ ERROR failed to resolve fn main() {} diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr index 5c3bb66d83a..d59bcaa316e 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.stderr +++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr @@ -1,7 +1,7 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m` --> $DIR/macro_path_as_generic_bound.rs:17:6 | -17 | foo!(m::m2::A); +17 | foo!(m::m2::A); //~ ERROR failed to resolve | ^ Use of undeclared type or module `m` error: cannot continue compilation due to previous error diff --git a/src/test/ui/macros/macro_undefined.rs b/src/test/ui/macros/macro_undefined.rs index db93ba5e2c4..c0acbc979ad 100644 --- a/src/test/ui/macros/macro_undefined.rs +++ b/src/test/ui/macros/macro_undefined.rs @@ -18,6 +18,6 @@ mod m { } fn main() { - k!(); - kl!(); + k!(); //~ ERROR cannot find + kl!(); //~ ERROR cannot find } diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr index 5c33ae99734..6cfb05e7867 100644 --- a/src/test/ui/macros/macro_undefined.stderr +++ b/src/test/ui/macros/macro_undefined.stderr @@ -1,7 +1,7 @@ error: cannot find macro `kl!` in this scope --> $DIR/macro_undefined.rs:22:5 | -22 | kl!(); +22 | kl!(); //~ ERROR cannot find | ^^ | = help: have you added the `#[macro_use]` on the module/import? @@ -9,7 +9,7 @@ error: cannot find macro `kl!` in this scope error: cannot find macro `k!` in this scope --> $DIR/macro_undefined.rs:21:5 | -21 | k!(); +21 | k!(); //~ ERROR cannot find | ^ help: you could try the macro: `kl!` error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/trace_faulty_macros.rs b/src/test/ui/macros/trace_faulty_macros.rs index eb7292b0a65..ced1a7f68fb 100644 --- a/src/test/ui/macros/trace_faulty_macros.rs +++ b/src/test/ui/macros/trace_faulty_macros.rs @@ -14,7 +14,7 @@ macro_rules! my_faulty_macro { () => { - my_faulty_macro!(bcd); + my_faulty_macro!(bcd); //~ ERROR no rules }; } @@ -29,7 +29,7 @@ macro_rules! pat_macro { macro_rules! my_recursive_macro { () => { - my_recursive_macro!(); + my_recursive_macro!(); //~ ERROR recursion limit }; } diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index f4aeb8332f0..b0e4a56a3d1 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -1,7 +1,7 @@ error: no rules expected the token `bcd` --> $DIR/trace_faulty_macros.rs:17:26 | -17 | my_faulty_macro!(bcd); +17 | my_faulty_macro!(bcd); //~ ERROR no rules | ^^^ ... 43 | my_faulty_macro!(); @@ -20,7 +20,7 @@ note: trace_macro error: recursion limit reached while expanding the macro `my_recursive_macro` --> $DIR/trace_faulty_macros.rs:32:9 | -32 | my_recursive_macro!(); +32 | my_recursive_macro!(); //~ ERROR recursion limit | ^^^^^^^^^^^^^^^^^^^^^^ ... 44 | my_recursive_macro!(); diff --git a/src/test/ui/method-call-err-msg.rs b/src/test/ui/method-call-err-msg.rs index 14fa74d1f32..37806e43a9d 100644 --- a/src/test/ui/method-call-err-msg.rs +++ b/src/test/ui/method-call-err-msg.rs @@ -10,7 +10,7 @@ // Test that parameter cardinality or missing method error gets span exactly. -pub struct Foo; +pub struct Foo; //~ NOTE not found for this impl Foo { fn zero(self) -> Foo { self } //~^ NOTE defined here diff --git a/src/test/ui/method-call-err-msg.stderr b/src/test/ui/method-call-err-msg.stderr index c39c62daf9e..472879261ef 100644 --- a/src/test/ui/method-call-err-msg.stderr +++ b/src/test/ui/method-call-err-msg.stderr @@ -28,6 +28,9 @@ error[E0061]: this function takes 2 parameters but 1 parameter was supplied error[E0599]: no method named `take` found for type `Foo` in the current scope --> $DIR/method-call-err-msg.rs:34:7 | +13 | pub struct Foo; //~ NOTE not found for this + | --------------- method `take` not found for this +... 34 | .take() //~ ERROR no method named `take` found for type `Foo` in the current scope | ^^^^ | diff --git a/src/test/ui/mismatched_types/E0053.rs b/src/test/ui/mismatched_types/E0053.rs index 933462e553e..f82f3fb0fa4 100644 --- a/src/test/ui/mismatched_types/E0053.rs +++ b/src/test/ui/mismatched_types/E0053.rs @@ -19,11 +19,11 @@ impl Foo for Bar { fn foo(x: i16) { } //~^ ERROR method `foo` has an incompatible type for trait //~| NOTE expected u16 + //~| NOTE expected type `fn(u16)` fn bar(&mut self) { } //~^ ERROR method `bar` has an incompatible type for trait //~| NOTE types differ in mutability //~| NOTE expected type `fn(&Bar)` - //~| NOTE found type `fn(&mut Bar)` } fn main() { diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr index d9871b8970c..b80363e3d3e 100644 --- a/src/test/ui/mismatched_types/E0053.stderr +++ b/src/test/ui/mismatched_types/E0053.stderr @@ -11,12 +11,12 @@ error[E0053]: method `foo` has an incompatible type for trait found type `fn(i16)` error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/E0053.rs:22:12 + --> $DIR/E0053.rs:23:12 | 13 | fn bar(&self); //~ NOTE type in trait | ----- type in trait ... -22 | fn bar(&mut self) { } +23 | fn bar(&mut self) { } | ^^^^^^^^^ types differ in mutability | = note: expected type `fn(&Bar)` diff --git a/src/test/ui/mismatched_types/E0409.rs b/src/test/ui/mismatched_types/E0409.rs index e89cc9ea5cb..17bbc3f2433 100644 --- a/src/test/ui/mismatched_types/E0409.rs +++ b/src/test/ui/mismatched_types/E0409.rs @@ -18,7 +18,6 @@ fn main() { //~| ERROR E0308 //~| NOTE expected &{integer}, found integral variable //~| NOTE expected type `&{integer}` - //~| NOTE found type `{integer}` _ => () } } diff --git a/src/test/ui/mismatched_types/E0631.rs b/src/test/ui/mismatched_types/E0631.rs index e28f15ab0b6..7e5490b37c4 100644 --- a/src/test/ui/mismatched_types/E0631.rs +++ b/src/test/ui/mismatched_types/E0631.rs @@ -14,8 +14,8 @@ fn foo<F: Fn(usize)>(_: F) {} fn bar<F: Fn<usize>>(_: F) {} fn main() { fn f(_: u64) {} - foo(|_: isize| {}); - bar(|_: isize| {}); - foo(f); - bar(f); + foo(|_: isize| {}); //~ ERROR type mismatch + bar(|_: isize| {}); //~ ERROR type mismatch + foo(f); //~ ERROR type mismatch + bar(f); //~ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 235e7a10063..33a68a29ddc 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -1,7 +1,7 @@ error[E0631]: type mismatch in closure arguments --> $DIR/E0631.rs:17:5 | -17 | foo(|_: isize| {}); +17 | foo(|_: isize| {}); //~ ERROR type mismatch | ^^^ ------------- found signature of `fn(isize) -> _` | | | expected signature of `fn(usize) -> _` @@ -11,7 +11,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/E0631.rs:18:5 | -18 | bar(|_: isize| {}); +18 | bar(|_: isize| {}); //~ ERROR type mismatch | ^^^ ------------- found signature of `fn(isize) -> _` | | | expected signature of `fn(usize) -> _` @@ -21,7 +21,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:19:5 | -19 | foo(f); +19 | foo(f); //~ ERROR type mismatch | ^^^ | | | expected signature of `fn(usize) -> _` @@ -32,7 +32,7 @@ error[E0631]: type mismatch in function arguments error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:20:5 | -20 | bar(f); +20 | bar(f); //~ ERROR type mismatch | ^^^ | | | expected signature of `fn(usize) -> _` diff --git a/src/test/ui/mismatched_types/abridged.rs b/src/test/ui/mismatched_types/abridged.rs index 03f889224be..f496df58f73 100644 --- a/src/test/ui/mismatched_types/abridged.rs +++ b/src/test/ui/mismatched_types/abridged.rs @@ -23,19 +23,19 @@ struct X<T1, T2> { } fn a() -> Foo { - Some(Foo { bar: 1 }) + Some(Foo { bar: 1 }) //~ ERROR mismatched types } fn a2() -> Foo { - Ok(Foo { bar: 1}) + Ok(Foo { bar: 1}) //~ ERROR mismatched types } fn b() -> Option<Foo> { - Foo { bar: 1 } + Foo { bar: 1 } //~ ERROR mismatched types } fn c() -> Result<Foo, Bar> { - Foo { bar: 1 } + Foo { bar: 1 } //~ ERROR mismatched types } fn d() -> X<X<String, String>, String> { @@ -46,7 +46,7 @@ fn d() -> X<X<String, String>, String> { }, y: 3, }; - x + x //~ ERROR mismatched types } fn e() -> X<X<String, String>, String> { @@ -57,7 +57,7 @@ fn e() -> X<X<String, String>, String> { }, y: "".to_string(), }; - x + x //~ ERROR mismatched types } fn main() {} diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 8c63d7d6f91..2e1e5afad32 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | 25 | fn a() -> Foo { | --- expected `Foo` because of return type -26 | Some(Foo { bar: 1 }) +26 | Some(Foo { bar: 1 }) //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::option::Option` | = note: expected type `Foo` @@ -14,7 +14,7 @@ error[E0308]: mismatched types | 29 | fn a2() -> Foo { | --- expected `Foo` because of return type -30 | Ok(Foo { bar: 1}) +30 | Ok(Foo { bar: 1}) //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::result::Result` | = note: expected type `Foo` @@ -25,7 +25,7 @@ error[E0308]: mismatched types | 33 | fn b() -> Option<Foo> { | ----------- expected `std::option::Option<Foo>` because of return type -34 | Foo { bar: 1 } +34 | Foo { bar: 1 } //~ ERROR mismatched types | ^^^^^^^^^^^^^^ expected enum `std::option::Option`, found struct `Foo` | = note: expected type `std::option::Option<Foo>` @@ -36,7 +36,7 @@ error[E0308]: mismatched types | 37 | fn c() -> Result<Foo, Bar> { | ---------------- expected `std::result::Result<Foo, Bar>` because of return type -38 | Foo { bar: 1 } +38 | Foo { bar: 1 } //~ ERROR mismatched types | ^^^^^^^^^^^^^^ expected enum `std::result::Result`, found struct `Foo` | = note: expected type `std::result::Result<Foo, Bar>` @@ -48,7 +48,7 @@ error[E0308]: mismatched types 41 | fn d() -> X<X<String, String>, String> { | ---------------------------- expected `X<X<std::string::String, std::string::String>, std::string::String>` because of return type ... -49 | x +49 | x //~ ERROR mismatched types | ^ expected struct `std::string::String`, found integral variable | = note: expected type `X<X<_, std::string::String>, std::string::String>` @@ -60,7 +60,7 @@ error[E0308]: mismatched types 52 | fn e() -> X<X<String, String>, String> { | ---------------------------- expected `X<X<std::string::String, std::string::String>, std::string::String>` because of return type ... -60 | x +60 | x //~ ERROR mismatched types | ^ expected struct `std::string::String`, found integral variable | = note: expected type `X<X<_, std::string::String>, _>` diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index 98449e59664..e45616cd67a 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -9,10 +9,10 @@ // except according to those terms. fn main() { - 1 + Some(1); - 2 as usize - Some(1); - 3 * (); - 4 / ""; - 5 < String::new(); - 6 == Ok(1); + 1 + Some(1); //~ ERROR is not satisfied + 2 as usize - Some(1); //~ ERROR is not satisfied + 3 * (); //~ ERROR is not satisfied + 4 / ""; //~ ERROR is not satisfied + 5 < String::new(); //~ ERROR is not satisfied + 6 == Ok(1); //~ ERROR is not satisfied } diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 6d1a39e0d93..8541ad52e01 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{integer}>>` is not satisfied --> $DIR/binops.rs:12:7 | -12 | 1 + Some(1); +12 | 1 + Some(1); //~ ERROR is not satisfied | ^ no implementation for `{integer} + std::option::Option<{integer}>` | = help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}` @@ -9,7 +9,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{int error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer}>>` is not satisfied --> $DIR/binops.rs:13:16 | -13 | 2 as usize - Some(1); +13 | 2 as usize - Some(1); //~ ERROR is not satisfied | ^ no implementation for `usize - std::option::Option<{integer}>` | = help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize` @@ -17,7 +17,7 @@ error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied --> $DIR/binops.rs:14:7 | -14 | 3 * (); +14 | 3 * (); //~ ERROR is not satisfied | ^ no implementation for `{integer} * ()` | = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}` @@ -25,7 +25,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied --> $DIR/binops.rs:15:7 | -15 | 4 / ""; +15 | 4 / ""; //~ ERROR is not satisfied | ^ no implementation for `{integer} / &str` | = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}` @@ -33,7 +33,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied error[E0277]: the trait bound `{integer}: std::cmp::PartialOrd<std::string::String>` is not satisfied --> $DIR/binops.rs:16:7 | -16 | 5 < String::new(); +16 | 5 < String::new(); //~ ERROR is not satisfied | ^ can't compare `{integer}` with `std::string::String` | = help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}` @@ -41,7 +41,7 @@ error[E0277]: the trait bound `{integer}: std::cmp::PartialOrd<std::string::Stri error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not satisfied --> $DIR/binops.rs:17:7 | -17 | 6 == Ok(1); +17 | 6 == Ok(1); //~ ERROR is not satisfied | ^^ can't compare `{integer}` with `std::result::Result<{integer}, _>` | = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}` diff --git a/src/test/ui/mismatched_types/cast-rfc0401.rs b/src/test/ui/mismatched_types/cast-rfc0401.rs index f72be0d7054..15388b3a764 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.rs +++ b/src/test/ui/mismatched_types/cast-rfc0401.rs @@ -10,12 +10,12 @@ fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V { - u as *const V + u as *const V //~ ERROR is invalid } fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str { - u as *const str + u as *const str //~ ERROR is invalid } trait Foo { fn foo(&self) {} } @@ -36,47 +36,47 @@ fn main() let fat_sv : *const [i8] = unsafe { &*(0 as *const [i8; 1])}; let foo: &Foo = &f; - let _ = v as &u8; - let _ = v as E; - let _ = v as fn(); - let _ = v as (u32,); - let _ = Some(&v) as *const u8; + let _ = v as &u8; //~ ERROR non-primitive cast + let _ = v as E; //~ ERROR non-primitive cast + let _ = v as fn(); //~ ERROR non-primitive cast + let _ = v as (u32,); //~ ERROR non-primitive cast + let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast - let _ = v as f32; - let _ = main as f64; - let _ = &v as usize; - let _ = f as *const u8; - let _ = 3_i32 as bool; - let _ = E::A as bool; - let _ = 0x61u32 as char; + let _ = v as f32; //~ ERROR is invalid + let _ = main as f64; //~ ERROR is invalid + let _ = &v as usize; //~ ERROR is invalid + let _ = f as *const u8; //~ ERROR is invalid + let _ = 3_i32 as bool; //~ ERROR cannot cast + let _ = E::A as bool; //~ ERROR cannot cast + let _ = 0x61u32 as char; //~ ERROR can be cast as - let _ = false as f32; - let _ = E::A as f32; - let _ = 'a' as f32; + let _ = false as f32; //~ ERROR is invalid + let _ = E::A as f32; //~ ERROR is invalid + let _ = 'a' as f32; //~ ERROR is invalid - let _ = false as *const u8; - let _ = E::A as *const u8; - let _ = 'a' as *const u8; + let _ = false as *const u8; //~ ERROR is invalid + let _ = E::A as *const u8; //~ ERROR is invalid + let _ = 'a' as *const u8; //~ ERROR is invalid - let _ = 42usize as *const [u8]; - let _ = v as *const [u8]; - let _ = fat_v as *const Foo; - let _ = foo as *const str; - let _ = foo as *mut str; - let _ = main as *mut str; - let _ = &f as *mut f32; - let _ = &f as *const f64; - let _ = fat_sv as usize; + let _ = 42usize as *const [u8]; //~ ERROR is invalid + let _ = v as *const [u8]; //~ ERROR cannot cast + let _ = fat_v as *const Foo; //~ ERROR is not satisfied + let _ = foo as *const str; //~ ERROR is invalid + let _ = foo as *mut str; //~ ERROR is invalid + let _ = main as *mut str; //~ ERROR is invalid + let _ = &f as *mut f32; //~ ERROR is invalid + let _ = &f as *const f64; //~ ERROR is invalid + let _ = fat_sv as usize; //~ ERROR is invalid let a : *const str = "hello"; - let _ = a as *const Foo; + let _ = a as *const Foo; //~ ERROR is not satisfied // check no error cascade - let _ = main.f as *const u32; + let _ = main.f as *const u32; //~ ERROR no field let cf: *const Foo = &0; - let _ = cf as *const [u16]; - let _ = cf as *const Bar; + let _ = cf as *const [u16]; //~ ERROR is invalid + let _ = cf as *const Bar; //~ ERROR is invalid - vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); + vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid } diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index fb363c388b6..fa4f5903621 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -1,7 +1,7 @@ error[E0606]: casting `*const U` as `*const V` is invalid --> $DIR/cast-rfc0401.rs:13:5 | -13 | u as *const V +13 | u as *const V //~ ERROR is invalid | ^^^^^^^^^^^^^ | = note: vtable kinds may not match @@ -9,7 +9,7 @@ error[E0606]: casting `*const U` as `*const V` is invalid error[E0606]: casting `*const U` as `*const str` is invalid --> $DIR/cast-rfc0401.rs:18:5 | -18 | u as *const str +18 | u as *const str //~ ERROR is invalid | ^^^^^^^^^^^^^^^ | = note: vtable kinds may not match @@ -17,13 +17,13 @@ error[E0606]: casting `*const U` as `*const str` is invalid error[E0609]: no field `f` on type `fn() {main}` --> $DIR/cast-rfc0401.rs:75:18 | -75 | let _ = main.f as *const u32; +75 | let _ = main.f as *const u32; //~ ERROR no field | ^ error[E0605]: non-primitive cast: `*const u8` as `&u8` --> $DIR/cast-rfc0401.rs:39:13 | -39 | let _ = v as &u8; +39 | let _ = v as &u8; //~ ERROR non-primitive cast | ^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait @@ -31,7 +31,7 @@ error[E0605]: non-primitive cast: `*const u8` as `&u8` error[E0605]: non-primitive cast: `*const u8` as `E` --> $DIR/cast-rfc0401.rs:40:13 | -40 | let _ = v as E; +40 | let _ = v as E; //~ ERROR non-primitive cast | ^^^^^^ | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait @@ -39,7 +39,7 @@ error[E0605]: non-primitive cast: `*const u8` as `E` error[E0605]: non-primitive cast: `*const u8` as `fn()` --> $DIR/cast-rfc0401.rs:41:13 | -41 | let _ = v as fn(); +41 | let _ = v as fn(); //~ ERROR non-primitive cast | ^^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait @@ -47,7 +47,7 @@ error[E0605]: non-primitive cast: `*const u8` as `fn()` error[E0605]: non-primitive cast: `*const u8` as `(u32,)` --> $DIR/cast-rfc0401.rs:42:13 | -42 | let _ = v as (u32,); +42 | let _ = v as (u32,); //~ ERROR non-primitive cast | ^^^^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait @@ -55,7 +55,7 @@ error[E0605]: non-primitive cast: `*const u8` as `(u32,)` error[E0605]: non-primitive cast: `std::option::Option<&*const u8>` as `*const u8` --> $DIR/cast-rfc0401.rs:43:13 | -43 | let _ = Some(&v) as *const u8; +43 | let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast | ^^^^^^^^^^^^^^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait @@ -63,19 +63,19 @@ error[E0605]: non-primitive cast: `std::option::Option<&*const u8>` as `*const u error[E0606]: casting `*const u8` as `f32` is invalid --> $DIR/cast-rfc0401.rs:45:13 | -45 | let _ = v as f32; +45 | let _ = v as f32; //~ ERROR is invalid | ^^^^^^^^ error[E0606]: casting `fn() {main}` as `f64` is invalid --> $DIR/cast-rfc0401.rs:46:13 | -46 | let _ = main as f64; +46 | let _ = main as f64; //~ ERROR is invalid | ^^^^^^^^^^^ error[E0606]: casting `&*const u8` as `usize` is invalid --> $DIR/cast-rfc0401.rs:47:13 | -47 | let _ = &v as usize; +47 | let _ = &v as usize; //~ ERROR is invalid | ^^^^^^^^^^^ | = help: cast through a raw pointer first @@ -83,13 +83,13 @@ error[E0606]: casting `&*const u8` as `usize` is invalid error[E0606]: casting `f32` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:48:13 | -48 | let _ = f as *const u8; +48 | let _ = f as *const u8; //~ ERROR is invalid | ^^^^^^^^^^^^^^ error[E0054]: cannot cast as `bool` --> $DIR/cast-rfc0401.rs:49:13 | -49 | let _ = 3_i32 as bool; +49 | let _ = 3_i32 as bool; //~ ERROR cannot cast | ^^^^^^^^^^^^^ unsupported cast | = help: compare with zero instead @@ -97,7 +97,7 @@ error[E0054]: cannot cast as `bool` error[E0054]: cannot cast as `bool` --> $DIR/cast-rfc0401.rs:50:13 | -50 | let _ = E::A as bool; +50 | let _ = E::A as bool; //~ ERROR cannot cast | ^^^^^^^^^^^^ unsupported cast | = help: compare with zero instead @@ -105,13 +105,13 @@ error[E0054]: cannot cast as `bool` error[E0604]: only `u8` can be cast as `char`, not `u32` --> $DIR/cast-rfc0401.rs:51:13 | -51 | let _ = 0x61u32 as char; +51 | let _ = 0x61u32 as char; //~ ERROR can be cast as | ^^^^^^^^^^^^^^^ error[E0606]: casting `bool` as `f32` is invalid --> $DIR/cast-rfc0401.rs:53:13 | -53 | let _ = false as f32; +53 | let _ = false as f32; //~ ERROR is invalid | ^^^^^^^^^^^^ | = help: cast through an integer first @@ -119,7 +119,7 @@ error[E0606]: casting `bool` as `f32` is invalid error[E0606]: casting `E` as `f32` is invalid --> $DIR/cast-rfc0401.rs:54:13 | -54 | let _ = E::A as f32; +54 | let _ = E::A as f32; //~ ERROR is invalid | ^^^^^^^^^^^ | = help: cast through an integer first @@ -127,7 +127,7 @@ error[E0606]: casting `E` as `f32` is invalid error[E0606]: casting `char` as `f32` is invalid --> $DIR/cast-rfc0401.rs:55:13 | -55 | let _ = 'a' as f32; +55 | let _ = 'a' as f32; //~ ERROR is invalid | ^^^^^^^^^^ | = help: cast through an integer first @@ -135,67 +135,67 @@ error[E0606]: casting `char` as `f32` is invalid error[E0606]: casting `bool` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:57:13 | -57 | let _ = false as *const u8; +57 | let _ = false as *const u8; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^^^ error[E0606]: casting `E` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:58:13 | -58 | let _ = E::A as *const u8; +58 | let _ = E::A as *const u8; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^^ error[E0606]: casting `char` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:59:13 | -59 | let _ = 'a' as *const u8; +59 | let _ = 'a' as *const u8; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^ error[E0606]: casting `usize` as `*const [u8]` is invalid --> $DIR/cast-rfc0401.rs:61:13 | -61 | let _ = 42usize as *const [u8]; +61 | let _ = 42usize as *const [u8]; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^^^^^^^ error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]` --> $DIR/cast-rfc0401.rs:62:13 | -62 | let _ = v as *const [u8]; +62 | let _ = v as *const [u8]; //~ ERROR cannot cast | ^^^^^^^^^^^^^^^^ error[E0606]: casting `&Foo` as `*const str` is invalid --> $DIR/cast-rfc0401.rs:64:13 | -64 | let _ = foo as *const str; +64 | let _ = foo as *const str; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^^ error[E0606]: casting `&Foo` as `*mut str` is invalid --> $DIR/cast-rfc0401.rs:65:13 | -65 | let _ = foo as *mut str; +65 | let _ = foo as *mut str; //~ ERROR is invalid | ^^^^^^^^^^^^^^^ error[E0606]: casting `fn() {main}` as `*mut str` is invalid --> $DIR/cast-rfc0401.rs:66:13 | -66 | let _ = main as *mut str; +66 | let _ = main as *mut str; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^ error[E0606]: casting `&f32` as `*mut f32` is invalid --> $DIR/cast-rfc0401.rs:67:13 | -67 | let _ = &f as *mut f32; +67 | let _ = &f as *mut f32; //~ ERROR is invalid | ^^^^^^^^^^^^^^ error[E0606]: casting `&f32` as `*const f64` is invalid --> $DIR/cast-rfc0401.rs:68:13 | -68 | let _ = &f as *const f64; +68 | let _ = &f as *const f64; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^ error[E0606]: casting `*const [i8]` as `usize` is invalid --> $DIR/cast-rfc0401.rs:69:13 | -69 | let _ = fat_sv as usize; +69 | let _ = fat_sv as usize; //~ ERROR is invalid | ^^^^^^^^^^^^^^^ | = help: cast through a thin pointer first @@ -203,7 +203,7 @@ error[E0606]: casting `*const [i8]` as `usize` is invalid error[E0606]: casting `*const Foo` as `*const [u16]` is invalid --> $DIR/cast-rfc0401.rs:78:13 | -78 | let _ = cf as *const [u16]; +78 | let _ = cf as *const [u16]; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^^^ | = note: vtable kinds may not match @@ -211,7 +211,7 @@ error[E0606]: casting `*const Foo` as `*const [u16]` is invalid error[E0606]: casting `*const Foo` as `*const Bar` is invalid --> $DIR/cast-rfc0401.rs:79:13 | -79 | let _ = cf as *const Bar; +79 | let _ = cf as *const Bar; //~ ERROR is invalid | ^^^^^^^^^^^^^^^^ | = note: vtable kinds may not match @@ -219,7 +219,7 @@ error[E0606]: casting `*const Foo` as `*const Bar` is invalid error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied --> $DIR/cast-rfc0401.rs:63:13 | -63 | let _ = fat_v as *const Foo; +63 | let _ = fat_v as *const Foo; //~ ERROR is not satisfied | ^^^^^ `[u8]` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `[u8]` @@ -228,7 +228,7 @@ error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied --> $DIR/cast-rfc0401.rs:72:13 | -72 | let _ = a as *const Foo; +72 | let _ = a as *const Foo; //~ ERROR is not satisfied | ^ `str` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `str` @@ -237,13 +237,13 @@ error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied error[E0606]: casting `&{float}` as `f32` is invalid --> $DIR/cast-rfc0401.rs:81:30 | -81 | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); +81 | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid | ^^^^^^^^ cannot cast `&{float}` as `f32` | help: did you mean `*s`? --> $DIR/cast-rfc0401.rs:81:30 | -81 | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); +81 | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid | ^ error: aborting due to 34 previous errors diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 5d2d1d2b04c..dcdf3070d68 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -13,11 +13,18 @@ fn f<F: Fn<usize>>(_: F) {} fn main() { [1, 2, 3].sort_by(|| panic!()); + //~^ ERROR closure is expected to take [1, 2, 3].sort_by(|tuple| panic!()); + //~^ ERROR closure is expected to take [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); + //~^ ERROR closure is expected to take f(|| panic!()); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); + //~^ ERROR closure is expected to take } diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 9de5e8fea01..2d792373cd7 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -7,25 +7,25 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 0 arguments | expected closure that takes 2 arguments error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:16:15 + --> $DIR/closure-arg-count.rs:17:15 | -16 | [1, 2, 3].sort_by(|tuple| panic!()); +17 | [1, 2, 3].sort_by(|tuple| panic!()); | ^^^^^^^ ------- takes 1 argument | | | expected closure that takes 2 arguments error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:17:15 + --> $DIR/closure-arg-count.rs:19:15 | -17 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); +19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); | ^^^^^^^ ----------------- takes 1 argument | | | expected closure that takes 2 arguments error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:18:5 + --> $DIR/closure-arg-count.rs:21:5 | -18 | f(|| panic!()); +21 | f(|| panic!()); | ^ -- takes 0 arguments | | | expected closure that takes 1 argument @@ -33,25 +33,25 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments = note: required by `f` error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:20:53 + --> $DIR/closure-arg-count.rs:24:53 | -20 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); +24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|` | | | expected closure that takes a single tuple as argument error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:21:53 + --> $DIR/closure-arg-count.rs:26:53 | -21 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|` | | | expected closure that takes a single tuple as argument error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:22:53 + --> $DIR/closure-arg-count.rs:28:53 | -22 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments | | | expected closure that takes a single 2-tuple as argument diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs index aa9dba4c3f4..566998c374e 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -10,12 +10,13 @@ fn main() { let a = [(1u32, 2u32)]; - a.iter().map(|_: (u32, u32)| 45); - a.iter().map(|_: &(u16, u16)| 45); - a.iter().map(|_: (u16, u16)| 45); + a.iter().map(|_: (u32, u32)| 45); //~ ERROR type mismatch + a.iter().map(|_: &(u16, u16)| 45); //~ ERROR type mismatch + a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch } fn baz<F: Fn(*mut &u32)>(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { - baz(f); + baz(f); //~ ERROR type mismatch + //~^ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 866a024ab08..77d3a332767 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -1,7 +1,7 @@ error[E0631]: type mismatch in closure arguments --> $DIR/closure-arg-type-mismatch.rs:13:14 | -13 | a.iter().map(|_: (u32, u32)| 45); +13 | a.iter().map(|_: (u32, u32)| 45); //~ ERROR type mismatch | ^^^ ------------------ found signature of `fn((u32, u32)) -> _` | | | expected signature of `fn(&(u32, u32)) -> _` @@ -9,7 +9,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/closure-arg-type-mismatch.rs:14:14 | -14 | a.iter().map(|_: &(u16, u16)| 45); +14 | a.iter().map(|_: &(u16, u16)| 45); //~ ERROR type mismatch | ^^^ ------------------- found signature of `for<'r> fn(&'r (u16, u16)) -> _` | | | expected signature of `fn(&(u32, u32)) -> _` @@ -17,7 +17,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in closure arguments --> $DIR/closure-arg-type-mismatch.rs:15:14 | -15 | a.iter().map(|_: (u16, u16)| 45); +15 | a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch | ^^^ ------------------ found signature of `fn((u16, u16)) -> _` | | | expected signature of `fn(&(u32, u32)) -> _` @@ -25,7 +25,7 @@ error[E0631]: type mismatch in closure arguments error[E0631]: type mismatch in function arguments --> $DIR/closure-arg-type-mismatch.rs:20:5 | -20 | baz(f); +20 | baz(f); //~ ERROR type mismatch | ^^^ | | | expected signature of `for<'r> fn(*mut &'r u32) -> _` @@ -36,7 +36,7 @@ error[E0631]: type mismatch in function arguments error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:20:5 | -20 | baz(f); +20 | baz(f); //~ ERROR type mismatch | ^^^ expected bound lifetime parameter, found concrete lifetime | = note: required by `baz` diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs index 91298cb2bbd..5a74e8f933d 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-mismatch.rs @@ -15,5 +15,6 @@ impl<T: Fn(&())> Foo for T {} fn baz<T: Foo>(_: T) {} fn main() { - baz(|_| ()); + baz(|_| ()); //~ ERROR type mismatch + //~^ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index a54fd118cc5..99767ba1afa 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -1,7 +1,7 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.rs:18:9: 18:15] as std::ops::FnOnce<(&'r (),)>>::Output == ()` --> $DIR/closure-mismatch.rs:18:5 | -18 | baz(|_| ()); +18 | baz(|_| ()); //~ ERROR type mismatch | ^^^ expected bound lifetime parameter, found concrete lifetime | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` @@ -10,7 +10,7 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r error[E0631]: type mismatch in closure arguments --> $DIR/closure-mismatch.rs:18:5 | -18 | baz(|_| ()); +18 | baz(|_| ()); //~ ERROR type mismatch | ^^^ ------ found signature of `fn(_) -> _` | | | expected signature of `for<'r> fn(&'r ()) -> _` diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.rs b/src/test/ui/mismatched_types/const-fn-in-trait.rs index 5e44030eab7..e0d5c19f125 100644 --- a/src/test/ui/mismatched_types/const-fn-in-trait.rs +++ b/src/test/ui/mismatched_types/const-fn-in-trait.rs @@ -14,11 +14,11 @@ trait Foo { fn f() -> u32; - const fn g(); + const fn g(); //~ ERROR cannot be declared const } impl Foo for u32 { - const fn f() -> u32 { 22 } + const fn f() -> u32 { 22 } //~ ERROR cannot be declared const fn g() {} } diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.stderr b/src/test/ui/mismatched_types/const-fn-in-trait.stderr index f7b7635e41a..4911db6b2eb 100644 --- a/src/test/ui/mismatched_types/const-fn-in-trait.stderr +++ b/src/test/ui/mismatched_types/const-fn-in-trait.stderr @@ -1,13 +1,13 @@ error[E0379]: trait fns cannot be declared const --> $DIR/const-fn-in-trait.rs:17:5 | -17 | const fn g(); +17 | const fn g(); //~ ERROR cannot be declared const | ^^^^^ trait fns cannot be const error[E0379]: trait fns cannot be declared const --> $DIR/const-fn-in-trait.rs:21:5 | -21 | const fn f() -> u32 { 22 } +21 | const fn f() -> u32 { 22 } //~ ERROR cannot be declared const | ^^^^^ trait fns cannot be const error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/fn-variance-1.rs b/src/test/ui/mismatched_types/fn-variance-1.rs index 4bea8177b7c..e9e34abc092 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.rs +++ b/src/test/ui/mismatched_types/fn-variance-1.rs @@ -20,12 +20,14 @@ fn main() { apply(&3, takes_imm); apply(&3, takes_mut); //~^ ERROR type mismatch - //~| NOTE types differ in mutability //~| NOTE required by `apply` + //~| NOTE expected signature + //~| NOTE found signature apply(&mut 3, takes_mut); apply(&mut 3, takes_imm); //~^ ERROR type mismatch - //~| NOTE types differ in mutability //~| NOTE required by `apply` + //~| NOTE expected signature + //~| NOTE found signature } diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr index 09a90ef3d6b..e593298633a 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.stderr +++ b/src/test/ui/mismatched_types/fn-variance-1.stderr @@ -10,9 +10,9 @@ error[E0631]: type mismatch in function arguments = note: required by `apply` error[E0631]: type mismatch in function arguments - --> $DIR/fn-variance-1.rs:27:5 + --> $DIR/fn-variance-1.rs:28:5 | -27 | apply(&mut 3, takes_imm); +28 | apply(&mut 3, takes_imm); | ^^^^^ | | | expected signature of `fn(&mut {integer}) -> _` diff --git a/src/test/ui/mismatched_types/issue-19109.rs b/src/test/ui/mismatched_types/issue-19109.rs index 580684e2e14..59127c10cd1 100644 --- a/src/test/ui/mismatched_types/issue-19109.rs +++ b/src/test/ui/mismatched_types/issue-19109.rs @@ -14,7 +14,6 @@ fn function(t: &mut Trait) { t as *mut Trait //~^ ERROR: mismatched types //~| NOTE: expected type `()` - //~| NOTE: found type `*mut Trait` //~| NOTE: expected (), found *-ptr } diff --git a/src/test/ui/mismatched_types/issue-26480.rs b/src/test/ui/mismatched_types/issue-26480.rs index f842627e76f..33c5e74fafa 100644 --- a/src/test/ui/mismatched_types/issue-26480.rs +++ b/src/test/ui/mismatched_types/issue-26480.rs @@ -23,13 +23,13 @@ macro_rules! write { const stdout: i32 = 1; unsafe { write(stdout, $arr.as_ptr() as *const i8, - $arr.len() * size_of($arr[0])); + $arr.len() * size_of($arr[0])); //~ ERROR mismatched types } }} } macro_rules! cast { - ($x:expr) => ($x as ()) + ($x:expr) => ($x as ()) //~ ERROR non-primitive cast } fn main() { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index fae831ffb86..5d25cb2f93c 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-26480.rs:26:19 | -26 | $arr.len() * size_of($arr[0])); +26 | $arr.len() * size_of($arr[0])); //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize ... 37 | write!(hello); @@ -10,7 +10,7 @@ error[E0308]: mismatched types error[E0605]: non-primitive cast: `{integer}` as `()` --> $DIR/issue-26480.rs:32:19 | -32 | ($x:expr) => ($x as ()) +32 | ($x:expr) => ($x as ()) //~ ERROR non-primitive cast | ^^^^^^^^ ... 38 | cast!(2); diff --git a/src/test/ui/mismatched_types/issue-35030.rs b/src/test/ui/mismatched_types/issue-35030.rs index 006074ead13..503b2e08c39 100644 --- a/src/test/ui/mismatched_types/issue-35030.rs +++ b/src/test/ui/mismatched_types/issue-35030.rs @@ -16,7 +16,7 @@ trait Parser<T> { impl<bool> Parser<bool> for bool { fn parse(text: &str) -> Option<bool> { - Some(true) + Some(true) //~ ERROR mismatched types } } diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr index 46d690c5f03..3ec5d1b7b40 100644 --- a/src/test/ui/mismatched_types/issue-35030.stderr +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-35030.rs:19:14 | -19 | Some(true) +19 | Some(true) //~ ERROR mismatched types | ^^^^ expected type parameter, found bool | = note: expected type `bool` (type parameter) diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs index 7e489621e21..76885651c5b 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.rs +++ b/src/test/ui/mismatched_types/issue-36053-2.rs @@ -16,13 +16,8 @@ use std::iter::once; fn main() { once::<&str>("str").fuse().filter(|a: &str| true).count(); //~^ ERROR no method named `count` - //~| ERROR E0281 - //~| ERROR E0281 - //~| NOTE expected &str, found str - //~| NOTE expected &str, found str - //~| NOTE implements - //~| NOTE implements - //~| NOTE requires - //~| NOTE requires + //~| ERROR type mismatch in closure arguments //~| NOTE the method `count` exists but the following trait bounds + //~| NOTE expected signature + //~| NOTE found signature } diff --git a/src/test/ui/mismatched_types/issue-38371.rs b/src/test/ui/mismatched_types/issue-38371.rs index 6b49079c472..b9b6b05996b 100644 --- a/src/test/ui/mismatched_types/issue-38371.rs +++ b/src/test/ui/mismatched_types/issue-38371.rs @@ -13,7 +13,7 @@ struct Foo { } -fn foo(&foo: Foo) { +fn foo(&foo: Foo) { //~ ERROR mismatched types } fn bar(foo: Foo) { @@ -27,13 +27,13 @@ fn zar(&foo: &Foo) { // The somewhat unexpected help message in this case is courtesy of // match_default_bindings. -fn agh(&&bar: &u32) { +fn agh(&&bar: &u32) { //~ ERROR mismatched types } -fn bgh(&&bar: u32) { +fn bgh(&&bar: u32) { //~ ERROR mismatched types } -fn ugh(&[bar]: &u32) { +fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice } fn main() {} diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index c80f075021e..d34f05e054a 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-38371.rs:16:8 | -16 | fn foo(&foo: Foo) { +16 | fn foo(&foo: Foo) { //~ ERROR mismatched types | ^^^^ expected struct `Foo`, found reference | = note: expected type `Foo` @@ -11,7 +11,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/issue-38371.rs:30:9 | -30 | fn agh(&&bar: &u32) { +30 | fn agh(&&bar: &u32) { //~ ERROR mismatched types | ^^^^ expected u32, found reference | = note: expected type `u32` @@ -21,7 +21,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/issue-38371.rs:33:8 | -33 | fn bgh(&&bar: u32) { +33 | fn bgh(&&bar: u32) { //~ ERROR mismatched types | ^^^^^ expected u32, found reference | = note: expected type `u32` @@ -30,7 +30,7 @@ error[E0308]: mismatched types error[E0529]: expected an array or slice, found `u32` --> $DIR/issue-38371.rs:36:9 | -36 | fn ugh(&[bar]: &u32) { +36 | fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice | ^^^^^ pattern cannot match with input type `u32` error: aborting due to 4 previous errors diff --git a/src/test/ui/mismatched_types/main.rs b/src/test/ui/mismatched_types/main.rs index f7f1c78c3ba..7cf1de7cfee 100644 --- a/src/test/ui/mismatched_types/main.rs +++ b/src/test/ui/mismatched_types/main.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - let x: u32 = ( + let x: u32 = ( //~ ERROR mismatched types ); } diff --git a/src/test/ui/mismatched_types/main.stderr b/src/test/ui/mismatched_types/main.stderr index c8941fbf950..41e4c512398 100644 --- a/src/test/ui/mismatched_types/main.stderr +++ b/src/test/ui/mismatched_types/main.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/main.rs:12:18 | -12 | let x: u32 = ( +12 | let x: u32 = ( //~ ERROR mismatched types | __________________^ 13 | | ); | |_____^ expected u32, found () diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs index 3295e2bebd2..da1265dfeff 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs @@ -38,7 +38,6 @@ fn main() { let ans = s("what"); //~ ERROR mismatched types //~^ NOTE expected isize, found reference //~| NOTE expected type - //~| NOTE found type let ans = s(); //~^ ERROR this function takes 1 parameter but 0 parameters were supplied //~| NOTE expected 1 parameter diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr index cd05684f15d..feec86342e5 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr @@ -8,15 +8,15 @@ error[E0308]: mismatched types found type `&'static str` error[E0057]: this function takes 1 parameter but 0 parameters were supplied - --> $DIR/overloaded-calls-bad.rs:42:15 + --> $DIR/overloaded-calls-bad.rs:41:15 | -42 | let ans = s(); +41 | let ans = s(); | ^^^ expected 1 parameter error[E0057]: this function takes 1 parameter but 2 parameters were supplied - --> $DIR/overloaded-calls-bad.rs:45:17 + --> $DIR/overloaded-calls-bad.rs:44:17 | -45 | let ans = s("burma", "shave"); +44 | let ans = s("burma", "shave"); | ^^^^^^^^^^^^^^^^ expected 1 parameter error: aborting due to 3 previous errors diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.rs b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.rs index 9f832c7b6e5..115be1bf4de 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.rs +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.rs @@ -22,8 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) { fn d(x: Box<Foo>) { a(x); //~ ERROR mismatched types [E0308] - //~| NOTE expected type `Box<Foo + std::marker::Send + 'static>` - //~| NOTE found type `Box<Foo + 'static>` + //~| NOTE expected type `std::boxed::Box<Foo + std::marker::Send + 'static>` //~| NOTE expected trait `Foo + std::marker::Send`, found trait `Foo` } diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs index 099c8699e49..420b59a4df1 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs @@ -18,8 +18,8 @@ trait Foo { struct Bar; impl Foo for Bar { - fn foo(x: i16) { } - fn bar(&mut self, bar: &Bar) { } + fn foo(x: i16) { } //~ ERROR incompatible type + fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type } fn main() { diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 349432f64bb..f3cf1d56615 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -4,7 +4,7 @@ error[E0053]: method `foo` has an incompatible type for trait 14 | fn foo(x: u16); | --- type in trait ... -21 | fn foo(x: i16) { } +21 | fn foo(x: i16) { } //~ ERROR incompatible type | ^^^ expected u16, found i16 | = note: expected type `fn(u16)` @@ -16,7 +16,7 @@ error[E0053]: method `bar` has an incompatible type for trait 15 | fn bar(&mut self, bar: &mut Bar); | -------- type in trait ... -22 | fn bar(&mut self, bar: &Bar) { } +22 | fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type | ^^^^ types differ in mutability | = note: expected type `fn(&mut Bar, &mut Bar)` diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs index 693a1585320..814f2c4d187 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -20,15 +20,10 @@ fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize { pub fn main() { let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); - //~^ NOTE implements - //~| NOTE implements + //~^ NOTE found signature of `fn(usize, isize) let z = call_it(3, f); //~^ ERROR type mismatch - //~| NOTE expected isize, found usize - //~| NOTE expected isize, found usize - //~| NOTE requires - //~| NOTE requires - //~| NOTE required by `call_it` - //~| NOTE required by `call_it` + //~| NOTE expected signature of `fn(isize, isize) + //~| required by `call_it` println!("{}", z); } diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 59883649280..1d25632c5e2 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,10 +1,10 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13 + --> $DIR/unboxed-closures-vtable-mismatch.rs:24:13 | 22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | -------------------------------------------------- found signature of `fn(usize, isize) -> _` -... -25 | let z = call_it(3, f); +23 | //~^ NOTE found signature of `fn(usize, isize) +24 | let z = call_it(3, f); | ^^^^^^^ expected signature of `fn(isize, isize) -> _` | = note: required by `call_it` diff --git a/src/test/ui/missing-items/issue-40221.rs b/src/test/ui/missing-items/issue-40221.rs index 9cf1c7d6de8..526fc3a8658 100644 --- a/src/test/ui/missing-items/issue-40221.rs +++ b/src/test/ui/missing-items/issue-40221.rs @@ -18,7 +18,7 @@ enum PC { } fn test(proto: P) { - match proto { + match proto { //~ ERROR non-exhaustive patterns P::C(PC::Q) => (), } } diff --git a/src/test/ui/missing-items/issue-40221.stderr b/src/test/ui/missing-items/issue-40221.stderr index fc90c8a2b20..883c4329f4d 100644 --- a/src/test/ui/missing-items/issue-40221.stderr +++ b/src/test/ui/missing-items/issue-40221.stderr @@ -1,7 +1,7 @@ error[E0004]: non-exhaustive patterns: `C(QA)` not covered --> $DIR/issue-40221.rs:21:11 | -21 | match proto { +21 | match proto { //~ ERROR non-exhaustive patterns | ^^^^^ pattern `C(QA)` not covered error: aborting due to previous error diff --git a/src/test/ui/missing-items/m2.rs b/src/test/ui/missing-items/m2.rs index ffd7ff7f432..9f195452691 100644 --- a/src/test/ui/missing-items/m2.rs +++ b/src/test/ui/missing-items/m2.rs @@ -16,5 +16,5 @@ extern crate m1; struct X { } -impl m1::X for X { +impl m1::X for X { //~ ERROR not all trait items implemented } diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr index ce061bd167a..47164a5304a 100644 --- a/src/test/ui/missing-items/m2.stderr +++ b/src/test/ui/missing-items/m2.stderr @@ -3,7 +3,7 @@ error[E0601]: main function not found error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method` --> $DIR/m2.rs:19:1 | -19 | / impl m1::X for X { +19 | / impl m1::X for X { //~ ERROR not all trait items implemented 20 | | } | |_^ missing `CONSTANT`, `Type`, `method` in implementation | diff --git a/src/test/ui/missing-items/missing-type-parameter.rs b/src/test/ui/missing-items/missing-type-parameter.rs index 79368587062..f2d5359fb16 100644 --- a/src/test/ui/missing-items/missing-type-parameter.rs +++ b/src/test/ui/missing-items/missing-type-parameter.rs @@ -11,5 +11,5 @@ fn foo<X>() { } fn main() { - foo(); + foo(); //~ ERROR type annotations needed } diff --git a/src/test/ui/missing-items/missing-type-parameter.stderr b/src/test/ui/missing-items/missing-type-parameter.stderr index a16ae5538bf..1cb9e5f56d3 100644 --- a/src/test/ui/missing-items/missing-type-parameter.stderr +++ b/src/test/ui/missing-items/missing-type-parameter.stderr @@ -1,7 +1,7 @@ error[E0282]: type annotations needed --> $DIR/missing-type-parameter.rs:14:5 | -14 | foo(); +14 | foo(); //~ ERROR type annotations needed | ^^^ cannot infer type for `X` error: aborting due to previous error diff --git a/src/test/ui/mut-ref.rs b/src/test/ui/mut-ref.rs index f8883699688..715c4adf2e6 100644 --- a/src/test/ui/mut-ref.rs +++ b/src/test/ui/mut-ref.rs @@ -11,6 +11,6 @@ // compile-flags: -Z parse-only fn main() { - let mut ref x = 10; + let mut ref x = 10; //~ ERROR the order of `mut` and `ref` is incorrect let ref mut y = 11; } diff --git a/src/test/ui/mut-ref.stderr b/src/test/ui/mut-ref.stderr index ce6a42f1e5e..aaab243e22f 100644 --- a/src/test/ui/mut-ref.stderr +++ b/src/test/ui/mut-ref.stderr @@ -1,7 +1,7 @@ error: the order of `mut` and `ref` is incorrect --> $DIR/mut-ref.rs:14:9 | -14 | let mut ref x = 10; +14 | let mut ref x = 10; //~ ERROR the order of `mut` and `ref` is incorrect | ^^^^^^^ help: try switching the order: `ref mut` error: aborting due to previous error diff --git a/src/test/ui/nll/get_default.rs b/src/test/ui/nll/get_default.rs index 5605206221a..e65159390db 100644 --- a/src/test/ui/nll/get_default.rs +++ b/src/test/ui/nll/get_default.rs @@ -31,6 +31,7 @@ fn ok(map: &mut Map) -> &String { } None => { map.set(String::new()); // Just AST errors here + //~^ ERROR borrowed as immutable (Ast) } } } @@ -41,10 +42,13 @@ fn err(map: &mut Map) -> &String { match map.get() { Some(v) => { map.set(String::new()); // Both AST and MIR error here + //~^ ERROR borrowed as immutable (Mir) + //~| ERROR borrowed as immutable (Ast) return v; } None => { map.set(String::new()); // Just AST errors here + //~^ ERROR borrowed as immutable (Ast) } } } diff --git a/src/test/ui/nll/get_default.stderr b/src/test/ui/nll/get_default.stderr index 9586f426720..fff2684af13 100644 --- a/src/test/ui/nll/get_default.stderr +++ b/src/test/ui/nll/get_default.stderr @@ -7,40 +7,40 @@ error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as imm 33 | map.set(String::new()); // Just AST errors here | ^^^ mutable borrow occurs here ... -37 | } +38 | } | - immutable borrow ends here error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/get_default.rs:43:17 + --> $DIR/get_default.rs:44:17 | -41 | match map.get() { +42 | match map.get() { | --- immutable borrow occurs here -42 | Some(v) => { -43 | map.set(String::new()); // Both AST and MIR error here +43 | Some(v) => { +44 | map.set(String::new()); // Both AST and MIR error here | ^^^ mutable borrow occurs here ... -51 | } +55 | } | - immutable borrow ends here error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/get_default.rs:47:17 + --> $DIR/get_default.rs:50:17 | -41 | match map.get() { +42 | match map.get() { | --- immutable borrow occurs here ... -47 | map.set(String::new()); // Just AST errors here +50 | map.set(String::new()); // Just AST errors here | ^^^ mutable borrow occurs here ... -51 | } +55 | } | - immutable borrow ends here -error[E0502]: cannot borrow `(*map)` as mutable because it is also borrowed as immutable (Mir) - --> $DIR/get_default.rs:43:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) + --> $DIR/get_default.rs:44:17 | -41 | match map.get() { +42 | match map.get() { | --- immutable borrow occurs here -42 | Some(v) => { -43 | map.set(String::new()); // Both AST and MIR error here +43 | Some(v) => { +44 | map.set(String::new()); // Both AST and MIR error here | ^^^ mutable borrow occurs here error: aborting due to 4 previous errors diff --git a/src/test/ui/nll/named-region-basic.rs b/src/test/ui/nll/named-region-basic.rs index 539c2017ea6..001ce41c277 100644 --- a/src/test/ui/nll/named-region-basic.rs +++ b/src/test/ui/nll/named-region-basic.rs @@ -16,7 +16,9 @@ // compile-flags:-Znll fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { - &*x + &*x //~ ERROR free region `'a` does not outlive `'b` + //~^ ERROR `*x` does not live long enough + //~| WARN not reporting region error due to -Znll } fn main() { } diff --git a/src/test/ui/nll/named-region-basic.stderr b/src/test/ui/nll/named-region-basic.stderr index 42b2aea01f0..9c1de6c366c 100644 --- a/src/test/ui/nll/named-region-basic.stderr +++ b/src/test/ui/nll/named-region-basic.stderr @@ -1,13 +1,13 @@ warning: not reporting region error due to -Znll --> $DIR/named-region-basic.rs:19:5 | -19 | &*x +19 | &*x //~ ERROR free region `'a` does not outlive `'b` | ^^^ error[E0597]: `*x` does not live long enough --> $DIR/named-region-basic.rs:19:6 | -19 | &*x +19 | &*x //~ ERROR free region `'a` does not outlive `'b` | ^^ does not live long enough | = note: borrowed value must be valid for the static lifetime... @@ -15,14 +15,16 @@ note: ...but borrowed value is only valid for the lifetime 'a as defined on the --> $DIR/named-region-basic.rs:18:1 | 18 | / fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { -19 | | &*x -20 | | } +19 | | &*x //~ ERROR free region `'a` does not outlive `'b` +20 | | //~^ ERROR `*x` does not live long enough +21 | | //~| WARN not reporting region error due to -Znll +22 | | } | |_^ error: free region `'a` does not outlive `'b` --> $DIR/named-region-basic.rs:19:5 | -19 | &*x +19 | &*x //~ ERROR free region `'a` does not outlive `'b` | ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs index 54d3b3e0876..e7483dbd3b5 100644 --- a/src/test/ui/on-unimplemented/bad-annotation.rs +++ b/src/test/ui/on-unimplemented/bad-annotation.rs @@ -23,7 +23,7 @@ trait MyFromIterator<A> { fn my_from_iter<T: Iterator<Item=A>>(iterator: T) -> Self; } -#[rustc_on_unimplemented] //~ ERROR this attribute must have a value +#[rustc_on_unimplemented] //~ ERROR `#[rustc_on_unimplemented]` requires a value trait BadAnnotation1 {} @@ -38,27 +38,34 @@ trait BadAnnotation3<A,B> {} #[rustc_on_unimplemented(lorem="")] +//~^ this attribute must have a valid trait BadAnnotation4 {} #[rustc_on_unimplemented(lorem(ipsum(dolor)))] +//~^ this attribute must have a valid trait BadAnnotation5 {} #[rustc_on_unimplemented(message="x", message="y")] +//~^ this attribute must have a valid trait BadAnnotation6 {} #[rustc_on_unimplemented(message="x", on(desugared, message="y"))] +//~^ this attribute must have a valid trait BadAnnotation7 {} #[rustc_on_unimplemented(on(), message="y")] +//~^ empty `on`-clause trait BadAnnotation8 {} #[rustc_on_unimplemented(on="x", message="y")] +//~^ this attribute must have a valid trait BadAnnotation9 {} #[rustc_on_unimplemented(on(x="y"), message="y")] trait BadAnnotation10 {} #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] +//~^ this attribute must have a valid trait BadAnnotation11 {} pub fn main() { diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr index 73834f4422d..7126cc76eb7 100644 --- a/src/test/ui/on-unimplemented/bad-annotation.stderr +++ b/src/test/ui/on-unimplemented/bad-annotation.stderr @@ -1,7 +1,7 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value --> $DIR/bad-annotation.rs:26:1 | -26 | #[rustc_on_unimplemented] //~ ERROR this attribute must have a value +26 | #[rustc_on_unimplemented] //~ ERROR `#[rustc_on_unimplemented]` requires a value | ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here | = note: eg `#[rustc_on_unimplemented = "foo"]` @@ -27,47 +27,47 @@ error[E0232]: this attribute must have a valid value = note: eg `#[rustc_on_unimplemented = "foo"]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:43:26 + --> $DIR/bad-annotation.rs:44:26 | -43 | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] +44 | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] | ^^^^^^^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented = "foo"]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:46:39 + --> $DIR/bad-annotation.rs:48:39 | -46 | #[rustc_on_unimplemented(message="x", message="y")] +48 | #[rustc_on_unimplemented(message="x", message="y")] | ^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented = "foo"]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:49:39 + --> $DIR/bad-annotation.rs:52:39 | -49 | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))] +52 | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented = "foo"]` error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]` - --> $DIR/bad-annotation.rs:52:26 + --> $DIR/bad-annotation.rs:56:26 | -52 | #[rustc_on_unimplemented(on(), message="y")] +56 | #[rustc_on_unimplemented(on(), message="y")] | ^^^^ empty on-clause here error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:55:26 + --> $DIR/bad-annotation.rs:60:26 | -55 | #[rustc_on_unimplemented(on="x", message="y")] +60 | #[rustc_on_unimplemented(on="x", message="y")] | ^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented = "foo"]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:61:40 + --> $DIR/bad-annotation.rs:67:40 | -61 | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] +67 | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented = "foo"]` diff --git a/src/test/ui/pub/pub-restricted-error-fn.rs b/src/test/ui/pub/pub-restricted-error-fn.rs index 13514310371..58f3d379ed9 100644 --- a/src/test/ui/pub/pub-restricted-error-fn.rs +++ b/src/test/ui/pub/pub-restricted-error-fn.rs @@ -10,4 +10,4 @@ #![feature(pub_restricted)] -pub(crate) () fn foo() {} +pub(crate) () fn foo() {} //~ unmatched visibility diff --git a/src/test/ui/pub/pub-restricted-error-fn.stderr b/src/test/ui/pub/pub-restricted-error-fn.stderr index 470e8331247..9cfc3968ab1 100644 --- a/src/test/ui/pub/pub-restricted-error-fn.stderr +++ b/src/test/ui/pub/pub-restricted-error-fn.stderr @@ -1,7 +1,7 @@ error: unmatched visibility `pub` --> $DIR/pub-restricted-error-fn.rs:13:10 | -13 | pub(crate) () fn foo() {} +13 | pub(crate) () fn foo() {} //~ unmatched visibility | ^ error: aborting due to previous error diff --git a/src/test/ui/pub/pub-restricted-error.rs b/src/test/ui/pub/pub-restricted-error.rs index 99af031899a..dfc927f2cb5 100644 --- a/src/test/ui/pub/pub-restricted-error.rs +++ b/src/test/ui/pub/pub-restricted-error.rs @@ -13,7 +13,7 @@ struct Bar(pub(())); struct Foo { - pub(crate) () foo: usize, + pub(crate) () foo: usize, //~ ERROR expected identifier } diff --git a/src/test/ui/pub/pub-restricted-error.stderr b/src/test/ui/pub/pub-restricted-error.stderr index b8b4c80778d..cbf206e6aed 100644 --- a/src/test/ui/pub/pub-restricted-error.stderr +++ b/src/test/ui/pub/pub-restricted-error.stderr @@ -1,7 +1,7 @@ error: expected identifier, found `(` --> $DIR/pub-restricted-error.rs:16:16 | -16 | pub(crate) () foo: usize, +16 | pub(crate) () foo: usize, //~ ERROR expected identifier | ^ error: aborting due to previous error diff --git a/src/test/ui/pub/pub-restricted-non-path.rs b/src/test/ui/pub/pub-restricted-non-path.rs index 3f74285717a..11428b778ed 100644 --- a/src/test/ui/pub/pub-restricted-non-path.rs +++ b/src/test/ui/pub/pub-restricted-non-path.rs @@ -10,6 +10,6 @@ #![feature(pub_restricted)] -pub (.) fn afn() {} +pub (.) fn afn() {} //~ ERROR expected identifier fn main() {} diff --git a/src/test/ui/pub/pub-restricted-non-path.stderr b/src/test/ui/pub/pub-restricted-non-path.stderr index ebfccc4d720..b76e87840c6 100644 --- a/src/test/ui/pub/pub-restricted-non-path.stderr +++ b/src/test/ui/pub/pub-restricted-non-path.stderr @@ -1,7 +1,7 @@ error: expected identifier, found `.` --> $DIR/pub-restricted-non-path.rs:13:6 | -13 | pub (.) fn afn() {} +13 | pub (.) fn afn() {} //~ ERROR expected identifier | ^ error: aborting due to previous error diff --git a/src/test/ui/pub/pub-restricted.rs b/src/test/ui/pub/pub-restricted.rs index 934ad24c167..07184d935b4 100644 --- a/src/test/ui/pub/pub-restricted.rs +++ b/src/test/ui/pub/pub-restricted.rs @@ -12,8 +12,8 @@ mod a {} -pub (a) fn afn() {} -pub (b) fn bfn() {} +pub (a) fn afn() {} //~ incorrect visibility restriction +pub (b) fn bfn() {} //~ incorrect visibility restriction pub fn privfn() {} mod x { mod y { @@ -29,8 +29,8 @@ mod y { pub (super) s: usize, valid_private: usize, pub (in y) valid_in_x: usize, - pub (a) invalid: usize, - pub (in x) non_parent_invalid: usize, + pub (a) invalid: usize, //~ incorrect visibility restriction + pub (in x) non_parent_invalid: usize, //~ ERROR visibilities can only be restricted } } @@ -38,4 +38,4 @@ fn main() {} // test multichar names mod xyz {} -pub (xyz) fn xyz() {} +pub (xyz) fn xyz() {} //~ incorrect visibility restriction diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr index ae283f1fb63..0bedcddc0b4 100644 --- a/src/test/ui/pub/pub-restricted.stderr +++ b/src/test/ui/pub/pub-restricted.stderr @@ -1,7 +1,7 @@ error: incorrect visibility restriction --> $DIR/pub-restricted.rs:15:6 | -15 | pub (a) fn afn() {} +15 | pub (a) fn afn() {} //~ incorrect visibility restriction | ^ help: make this visible only to module `a` with `in`: `in a` | = help: some possible visibility restrictions are: @@ -12,7 +12,7 @@ error: incorrect visibility restriction error: incorrect visibility restriction --> $DIR/pub-restricted.rs:16:6 | -16 | pub (b) fn bfn() {} +16 | pub (b) fn bfn() {} //~ incorrect visibility restriction | ^ help: make this visible only to module `b` with `in`: `in b` | = help: some possible visibility restrictions are: @@ -23,7 +23,7 @@ error: incorrect visibility restriction error: incorrect visibility restriction --> $DIR/pub-restricted.rs:32:14 | -32 | pub (a) invalid: usize, +32 | pub (a) invalid: usize, //~ incorrect visibility restriction | ^ help: make this visible only to module `a` with `in`: `in a` | = help: some possible visibility restrictions are: @@ -34,7 +34,7 @@ error: incorrect visibility restriction error: incorrect visibility restriction --> $DIR/pub-restricted.rs:41:6 | -41 | pub (xyz) fn xyz() {} +41 | pub (xyz) fn xyz() {} //~ incorrect visibility restriction | ^^^ help: make this visible only to module `xyz` with `in`: `in xyz` | = help: some possible visibility restrictions are: @@ -45,7 +45,7 @@ error: incorrect visibility restriction error: visibilities can only be restricted to ancestor modules --> $DIR/pub-restricted.rs:33:17 | -33 | pub (in x) non_parent_invalid: usize, +33 | pub (in x) non_parent_invalid: usize, //~ ERROR visibilities can only be restricted | ^ error: aborting due to 5 previous errors diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs index 87d017adf68..dd43c58de6d 100644 --- a/src/test/ui/reachable/expr_add.rs +++ b/src/test/ui/reachable/expr_add.rs @@ -24,5 +24,5 @@ impl ops::Add<!> for Foo { } fn main() { - let x = Foo + return; + let x = Foo + return; //~ ERROR unreachable } diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr index 1a2cc252051..4ae286d2fff 100644 --- a/src/test/ui/reachable/expr_add.stderr +++ b/src/test/ui/reachable/expr_add.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_add.rs:27:13 | -27 | let x = Foo + return; +27 | let x = Foo + return; //~ ERROR unreachable | ^^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr index bf4e4dc4711..54b1d47710c 100644 --- a/src/test/ui/reachable/expr_again.stderr +++ b/src/test/ui/reachable/expr_again.stderr @@ -9,7 +9,7 @@ note: lint level defined here | 13 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs index 00e8be07725..31229668796 100644 --- a/src/test/ui/reachable/expr_array.rs +++ b/src/test/ui/reachable/expr_array.rs @@ -17,12 +17,12 @@ fn a() { // the `22` is unreachable: - let x: [usize; 2] = [return, 22]; + let x: [usize; 2] = [return, 22]; //~ ERROR unreachable } fn b() { // the `array is unreachable: - let x: [usize; 2] = [22, return]; + let x: [usize; 2] = [22, return]; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr index f8dbdb5f8bb..0f64d158503 100644 --- a/src/test/ui/reachable/expr_array.stderr +++ b/src/test/ui/reachable/expr_array.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_array.rs:20:34 | -20 | let x: [usize; 2] = [return, 22]; +20 | let x: [usize; 2] = [return, 22]; //~ ERROR unreachable | ^^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_array.rs:25:25 | -25 | let x: [usize; 2] = [22, return]; +25 | let x: [usize; 2] = [22, return]; //~ ERROR unreachable | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs index 1b9357013d2..e6fb46a5bac 100644 --- a/src/test/ui/reachable/expr_assign.rs +++ b/src/test/ui/reachable/expr_assign.rs @@ -17,7 +17,7 @@ fn foo() { // No error here. let x; - x = return; + x = return; //~ ERROR unreachable } fn bar() { @@ -27,13 +27,13 @@ fn bar() { // Here we consider the `return` unreachable because // "evaluating" the `*p` has type `!`. This is somewhat // dubious, I suppose. - *p = return; + *p = return; //~ ERROR unreachable } } fn baz() { let mut i = 0; - *{return; &mut i} = 22; + *{return; &mut i} = 22; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr index 807f6a1c1d5..42c00d5a8b7 100644 --- a/src/test/ui/reachable/expr_assign.stderr +++ b/src/test/ui/reachable/expr_assign.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_assign.rs:20:5 | -20 | x = return; +20 | x = return; //~ ERROR unreachable | ^^^^^^^^^^ | note: lint level defined here @@ -13,13 +13,13 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_assign.rs:30:14 | -30 | *p = return; +30 | *p = return; //~ ERROR unreachable | ^^^^^^ error: unreachable expression --> $DIR/expr_assign.rs:36:15 | -36 | *{return; &mut i} = 22; +36 | *{return; &mut i} = 22; //~ ERROR unreachable | ^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs index 093589b4dc8..57b5d3cabce 100644 --- a/src/test/ui/reachable/expr_block.rs +++ b/src/test/ui/reachable/expr_block.rs @@ -18,7 +18,7 @@ fn a() { // Here the tail expression is considered unreachable: let x = { return; - 22 + 22 //~ ERROR unreachable }; } diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index 542ce1c3fd9..4c361dc8855 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_block.rs:21:9 | -21 | 22 +21 | 22 //~ ERROR unreachable | ^^ | note: lint level defined here @@ -16,7 +16,7 @@ error: unreachable statement 36 | println!("foo"); | ^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_box.rs b/src/test/ui/reachable/expr_box.rs index 6509b608335..ab62cbdf837 100644 --- a/src/test/ui/reachable/expr_box.rs +++ b/src/test/ui/reachable/expr_box.rs @@ -13,6 +13,6 @@ #![deny(unreachable_code)] fn main() { - let x = box return; + let x = box return; //~ ERROR unreachable println!("hi"); } diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr index 78ba231cef9..d8b5d9f8d76 100644 --- a/src/test/ui/reachable/expr_box.stderr +++ b/src/test/ui/reachable/expr_box.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_box.rs:16:13 | -16 | let x = box return; +16 | let x = box return; //~ ERROR unreachable | ^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs index 8d9f303df7f..86b95aad9c2 100644 --- a/src/test/ui/reachable/expr_call.rs +++ b/src/test/ui/reachable/expr_call.rs @@ -20,12 +20,12 @@ fn bar(x: !) { } fn a() { // the `22` is unreachable: - foo(return, 22); + foo(return, 22); //~ ERROR unreachable } fn b() { // the call is unreachable: - bar(return); + bar(return); //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr index 5526827f59f..eaafe8dc5d5 100644 --- a/src/test/ui/reachable/expr_call.stderr +++ b/src/test/ui/reachable/expr_call.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_call.rs:23:17 | -23 | foo(return, 22); +23 | foo(return, 22); //~ ERROR unreachable | ^^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_call.rs:28:5 | -28 | bar(return); +28 | bar(return); //~ ERROR unreachable | ^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs index 926ef864ebf..76b00c00ad9 100644 --- a/src/test/ui/reachable/expr_cast.rs +++ b/src/test/ui/reachable/expr_cast.rs @@ -17,7 +17,7 @@ fn a() { // the cast is unreachable: - let x = {return} as !; + let x = {return} as !; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr index a22300dcc13..d6fb37768c5 100644 --- a/src/test/ui/reachable/expr_cast.stderr +++ b/src/test/ui/reachable/expr_cast.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_cast.rs:20:13 | -20 | let x = {return} as !; +20 | let x = {return} as !; //~ ERROR unreachable | ^^^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index 2cf17474f6e..2b77f5bb3ca 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -9,7 +9,7 @@ note: lint level defined here | 14 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index 6e98e754c54..bcfe2c5bd63 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -9,7 +9,7 @@ note: lint level defined here | 14 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:31:5 @@ -17,7 +17,7 @@ error: unreachable statement 31 | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:41:5 @@ -25,7 +25,7 @@ error: unreachable statement 41 | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs index 23bdcc035b2..d2b96e51a95 100644 --- a/src/test/ui/reachable/expr_match.rs +++ b/src/test/ui/reachable/expr_match.rs @@ -17,7 +17,7 @@ fn a() { // The match is considered unreachable here, because the `return` // diverges: - match {return} { } + match {return} { } //~ ERROR unreachable } fn b() { diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index f5857a5b345..4b44b38895c 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_match.rs:20:5 | -20 | match {return} { } +20 | match {return} { } //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -16,7 +16,7 @@ error: unreachable statement 25 | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: unreachable statement --> $DIR/expr_match.rs:35:5 @@ -24,7 +24,7 @@ error: unreachable statement 35 | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs index f1d979d7df7..8be71e464b2 100644 --- a/src/test/ui/reachable/expr_method.rs +++ b/src/test/ui/reachable/expr_method.rs @@ -23,12 +23,12 @@ impl Foo { fn a() { // the `22` is unreachable: - Foo.foo(return, 22); + Foo.foo(return, 22); //~ ERROR unreachable } fn b() { // the call is unreachable: - Foo.bar(return); + Foo.bar(return); //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr index 177d4352a37..db9d5c3d22c 100644 --- a/src/test/ui/reachable/expr_method.stderr +++ b/src/test/ui/reachable/expr_method.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_method.rs:26:21 | -26 | Foo.foo(return, 22); +26 | Foo.foo(return, 22); //~ ERROR unreachable | ^^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_method.rs:31:5 | -31 | Foo.bar(return); +31 | Foo.bar(return); //~ ERROR unreachable | ^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs index 6078d6d5bde..47ee2ba62b8 100644 --- a/src/test/ui/reachable/expr_repeat.rs +++ b/src/test/ui/reachable/expr_repeat.rs @@ -17,7 +17,7 @@ fn a() { // the repeat is unreachable: - let x: [usize; 2] = [return; 2]; + let x: [usize; 2] = [return; 2]; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr index 19afc5dd7b5..54b29b616f3 100644 --- a/src/test/ui/reachable/expr_repeat.stderr +++ b/src/test/ui/reachable/expr_repeat.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_repeat.rs:20:25 | -20 | let x: [usize; 2] = [return; 2]; +20 | let x: [usize; 2] = [return; 2]; //~ ERROR unreachable | ^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_return.rs b/src/test/ui/reachable/expr_return.rs index c640ca06630..fac1116dc68 100644 --- a/src/test/ui/reachable/expr_return.rs +++ b/src/test/ui/reachable/expr_return.rs @@ -18,7 +18,7 @@ fn a() { // Here we issue that the "2nd-innermost" return is unreachable, // but we stop there. - let x = {return {return {return;}}}; + let x = {return {return {return;}}}; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr index 3eb70a4dd7c..a96def6011e 100644 --- a/src/test/ui/reachable/expr_return.stderr +++ b/src/test/ui/reachable/expr_return.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_return.rs:21:22 | -21 | let x = {return {return {return;}}}; +21 | let x = {return {return {return;}}}; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_struct.rs b/src/test/ui/reachable/expr_struct.rs index 09e31819279..b5acd395be6 100644 --- a/src/test/ui/reachable/expr_struct.rs +++ b/src/test/ui/reachable/expr_struct.rs @@ -22,22 +22,22 @@ struct Foo { fn a() { // struct expr is unreachable: - let x = Foo { a: 22, b: 33, ..return }; + let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable } fn b() { // the `33` is unreachable: - let x = Foo { a: return, b: 33, ..return }; + let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable } fn c() { // the `..return` is unreachable: - let x = Foo { a: 22, b: return, ..return }; + let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable } fn d() { // the struct expr is unreachable: - let x = Foo { a: 22, b: return }; + let x = Foo { a: 22, b: return }; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr index 4b7ac660413..b2cb1ef19cf 100644 --- a/src/test/ui/reachable/expr_struct.stderr +++ b/src/test/ui/reachable/expr_struct.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_struct.rs:25:13 | -25 | let x = Foo { a: 22, b: 33, ..return }; +25 | let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -13,19 +13,19 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_struct.rs:30:33 | -30 | let x = Foo { a: return, b: 33, ..return }; +30 | let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable | ^^ error: unreachable expression --> $DIR/expr_struct.rs:35:39 | -35 | let x = Foo { a: 22, b: return, ..return }; +35 | let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable | ^^^^^^ error: unreachable expression --> $DIR/expr_struct.rs:40:13 | -40 | let x = Foo { a: 22, b: return }; +40 | let x = Foo { a: 22, b: return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/reachable/expr_tup.rs b/src/test/ui/reachable/expr_tup.rs index 7c75296de6c..089020bf385 100644 --- a/src/test/ui/reachable/expr_tup.rs +++ b/src/test/ui/reachable/expr_tup.rs @@ -17,12 +17,12 @@ fn a() { // the `2` is unreachable: - let x: (usize, usize) = (return, 2); + let x: (usize, usize) = (return, 2); //~ ERROR unreachable } fn b() { // the tuple is unreachable: - let x: (usize, usize) = (2, return); + let x: (usize, usize) = (2, return); //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr index 63f477fd0c3..af43162a984 100644 --- a/src/test/ui/reachable/expr_tup.stderr +++ b/src/test/ui/reachable/expr_tup.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_tup.rs:20:38 | -20 | let x: (usize, usize) = (return, 2); +20 | let x: (usize, usize) = (return, 2); //~ ERROR unreachable | ^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here error: unreachable expression --> $DIR/expr_tup.rs:25:29 | -25 | let x: (usize, usize) = (2, return); +25 | let x: (usize, usize) = (2, return); //~ ERROR unreachable | ^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs index 2fa277c382e..29c59d5304f 100644 --- a/src/test/ui/reachable/expr_type.rs +++ b/src/test/ui/reachable/expr_type.rs @@ -17,7 +17,7 @@ fn a() { // the cast is unreachable: - let x = {return}: !; + let x = {return}: !; //~ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr index 6ed79974ccb..d6bcb4ec80f 100644 --- a/src/test/ui/reachable/expr_type.stderr +++ b/src/test/ui/reachable/expr_type.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_type.rs:20:13 | -20 | let x = {return}: !; +20 | let x = {return}: !; //~ ERROR unreachable | ^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index 57901fbaa7c..6cff3ff9644 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -15,7 +15,8 @@ #![feature(never_type)] fn foo() { - let x: ! = ! { return; 22 }; + let x: ! = ! { return; 22 }; //~ ERROR unreachable + //~^ ERROR cannot apply unary operator `!` to type `!` } fn main() { } diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index 9f4562fe297..f14824728a7 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,7 +1,7 @@ error: unreachable expression --> $DIR/expr_unary.rs:18:28 | -18 | let x: ! = ! { return; 22 }; +18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here error[E0600]: cannot apply unary operator `!` to type `!` --> $DIR/expr_unary.rs:18:16 | -18 | let x: ! = ! { return; 22 }; +18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr index 066cfc86c64..31e63c324d2 100644 --- a/src/test/ui/reachable/expr_while.stderr +++ b/src/test/ui/reachable/expr_while.stderr @@ -9,7 +9,7 @@ note: lint level defined here | 14 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: unreachable statement --> $DIR/expr_while.rs:33:9 @@ -17,7 +17,7 @@ error: unreachable statement 33 | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: unreachable statement --> $DIR/expr_while.rs:35:5 @@ -25,7 +25,7 @@ error: unreachable statement 35 | println!("I am, too."); | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.rs b/src/test/ui/resolve/enums-are-namespaced-xc.rs index 4f55f33d7f8..4059aa5527e 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.rs +++ b/src/test/ui/resolve/enums-are-namespaced-xc.rs @@ -13,12 +13,9 @@ extern crate namespaced_enums; fn main() { let _ = namespaced_enums::A; - //~^ ERROR unresolved value `namespaced_enums::A` - //~| HELP you can import it into scope: `use namespaced_enums::Foo::A;` + //~^ ERROR cannot find value `A` let _ = namespaced_enums::B(10); - //~^ ERROR unresolved function `namespaced_enums::B` - //~| HELP you can import it into scope: `use namespaced_enums::Foo::B;` + //~^ ERROR cannot find function `B` let _ = namespaced_enums::C { a: 10 }; - //~^ ERROR unresolved struct, variant or union type `namespaced_enums::C` - //~| HELP you can import it into scope: `use namespaced_enums::Foo::C;` + //~^ ERROR cannot find struct, variant or union type `C` } diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr index 52d798a2ca5..5acc678df90 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -9,9 +9,9 @@ help: possible candidate is found in another module, you can import it into scop | error[E0425]: cannot find function `B` in module `namespaced_enums` - --> $DIR/enums-are-namespaced-xc.rs:18:31 + --> $DIR/enums-are-namespaced-xc.rs:17:31 | -18 | let _ = namespaced_enums::B(10); +17 | let _ = namespaced_enums::B(10); | ^ not found in `namespaced_enums` help: possible candidate is found in another module, you can import it into scope | @@ -19,9 +19,9 @@ help: possible candidate is found in another module, you can import it into scop | error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums` - --> $DIR/enums-are-namespaced-xc.rs:21:31 + --> $DIR/enums-are-namespaced-xc.rs:19:31 | -21 | let _ = namespaced_enums::C { a: 10 }; +19 | let _ = namespaced_enums::C { a: 10 }; | ^ not found in `namespaced_enums` help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-14254.rs b/src/test/ui/resolve/issue-14254.rs index b1fc6c47720..38444f69628 100644 --- a/src/test/ui/resolve/issue-14254.rs +++ b/src/test/ui/resolve/issue-14254.rs @@ -27,111 +27,92 @@ impl BarTy { impl Foo for *const BarTy { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` a; - //~^ ERROR unresolved value `a` - //~| NOTE no resolution found + //~^ ERROR cannot find value `a` + //~| NOTE not found in this scope } } impl<'a> Foo for &'a BarTy { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` x; - //~^ ERROR unresolved value `x` - //~| NOTE did you mean `self.x`? + //~^ ERROR cannot find value `x` y; - //~^ ERROR unresolved value `y` - //~| NOTE did you mean `self.y`? + //~^ ERROR cannot find value `y` a; - //~^ ERROR unresolved value `a` - //~| NOTE no resolution found + //~^ ERROR cannot find value `a` + //~| NOTE not found in this scope bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` b; - //~^ ERROR unresolved value `b` - //~| NOTE no resolution found + //~^ ERROR cannot find value `b` + //~| NOTE not found in this scope } } impl<'a> Foo for &'a mut BarTy { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` x; - //~^ ERROR unresolved value `x` - //~| NOTE did you mean `self.x`? + //~^ ERROR cannot find value `x` y; - //~^ ERROR unresolved value `y` - //~| NOTE did you mean `self.y`? + //~^ ERROR cannot find value `y` a; - //~^ ERROR unresolved value `a` - //~| NOTE no resolution found + //~^ ERROR cannot find value `a` + //~| NOTE not found in this scope bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` b; - //~^ ERROR unresolved value `b` - //~| NOTE no resolution found + //~^ ERROR cannot find value `b` + //~| NOTE not found in this scope } } impl Foo for Box<BarTy> { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` } } impl Foo for *const isize { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` } } impl<'a> Foo for &'a isize { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` } } impl<'a> Foo for &'a mut isize { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` } } impl Foo for Box<isize> { fn bar(&self) { baz(); - //~^ ERROR unresolved function `baz` - //~| NOTE did you mean `self.baz(...)`? + //~^ ERROR cannot find function `baz` bah; - //~^ ERROR unresolved value `bah` - //~| NOTE did you mean `Self::bah`? + //~^ ERROR cannot find value `bah` } } diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr index 7aa0c2707b5..a472fc861eb 100644 --- a/src/test/ui/resolve/issue-14254.stderr +++ b/src/test/ui/resolve/issue-14254.stderr @@ -5,141 +5,141 @@ error[E0425]: cannot find function `baz` in this scope | ^^^ help: try: `self.baz` error[E0425]: cannot find value `a` in this scope - --> $DIR/issue-14254.rs:32:9 + --> $DIR/issue-14254.rs:31:9 | -32 | a; +31 | a; | ^ not found in this scope error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:40:9 + --> $DIR/issue-14254.rs:39:9 | -40 | baz(); +39 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-14254.rs:43:9 + --> $DIR/issue-14254.rs:41:9 | -43 | x; +41 | x; | ^ help: try: `self.x` error[E0425]: cannot find value `y` in this scope - --> $DIR/issue-14254.rs:46:9 + --> $DIR/issue-14254.rs:43:9 | -46 | y; +43 | y; | ^ help: try: `self.y` error[E0425]: cannot find value `a` in this scope - --> $DIR/issue-14254.rs:49:9 + --> $DIR/issue-14254.rs:45:9 | -49 | a; +45 | a; | ^ not found in this scope error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:52:9 + --> $DIR/issue-14254.rs:48:9 | -52 | bah; +48 | bah; | ^^^ help: try: `Self::bah` error[E0425]: cannot find value `b` in this scope - --> $DIR/issue-14254.rs:55:9 + --> $DIR/issue-14254.rs:50:9 | -55 | b; +50 | b; | ^ not found in this scope error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:63:9 + --> $DIR/issue-14254.rs:58:9 | -63 | baz(); +58 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-14254.rs:66:9 + --> $DIR/issue-14254.rs:60:9 | -66 | x; +60 | x; | ^ help: try: `self.x` error[E0425]: cannot find value `y` in this scope - --> $DIR/issue-14254.rs:69:9 + --> $DIR/issue-14254.rs:62:9 | -69 | y; +62 | y; | ^ help: try: `self.y` error[E0425]: cannot find value `a` in this scope - --> $DIR/issue-14254.rs:72:9 + --> $DIR/issue-14254.rs:64:9 | -72 | a; +64 | a; | ^ not found in this scope error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:75:9 + --> $DIR/issue-14254.rs:67:9 | -75 | bah; +67 | bah; | ^^^ help: try: `Self::bah` error[E0425]: cannot find value `b` in this scope - --> $DIR/issue-14254.rs:78:9 + --> $DIR/issue-14254.rs:69:9 | -78 | b; +69 | b; | ^ not found in this scope error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:86:9 + --> $DIR/issue-14254.rs:77:9 | -86 | baz(); +77 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:89:9 + --> $DIR/issue-14254.rs:79:9 | -89 | bah; +79 | bah; | ^^^ help: try: `Self::bah` error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:97:9 + --> $DIR/issue-14254.rs:86:9 | -97 | baz(); +86 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:100:9 - | -100 | bah; - | ^^^ help: try: `Self::bah` + --> $DIR/issue-14254.rs:88:9 + | +88 | bah; + | ^^^ help: try: `Self::bah` error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:108:9 - | -108 | baz(); - | ^^^ help: try: `self.baz` + --> $DIR/issue-14254.rs:95:9 + | +95 | baz(); + | ^^^ help: try: `self.baz` error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:111:9 - | -111 | bah; - | ^^^ help: try: `Self::bah` + --> $DIR/issue-14254.rs:97:9 + | +97 | bah; + | ^^^ help: try: `Self::bah` error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:119:9 + --> $DIR/issue-14254.rs:104:9 | -119 | baz(); +104 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:122:9 + --> $DIR/issue-14254.rs:106:9 | -122 | bah; +106 | bah; | ^^^ help: try: `Self::bah` error[E0425]: cannot find function `baz` in this scope - --> $DIR/issue-14254.rs:130:9 + --> $DIR/issue-14254.rs:113:9 | -130 | baz(); +113 | baz(); | ^^^ help: try: `self.baz` error[E0425]: cannot find value `bah` in this scope - --> $DIR/issue-14254.rs:133:9 + --> $DIR/issue-14254.rs:115:9 | -133 | bah; +115 | bah; | ^^^ help: try: `Self::bah` error[E0601]: main function not found diff --git a/src/test/ui/resolve/issue-16058.rs b/src/test/ui/resolve/issue-16058.rs index 1f777e53632..6d9df46eed4 100644 --- a/src/test/ui/resolve/issue-16058.rs +++ b/src/test/ui/resolve/issue-16058.rs @@ -18,10 +18,6 @@ impl GslResult { pub fn new() -> GslResult { Result { //~^ ERROR expected struct, variant or union type, found enum `Result` -//~| HELP possible better candidates are found in other modules, you can import them into scope -//~| HELP std::fmt::Result -//~| HELP std::io::Result -//~| HELP std::thread::Result val: 0f64, err: 0f64 } diff --git a/src/test/ui/resolve/issue-17518.rs b/src/test/ui/resolve/issue-17518.rs index 3ac9b379d18..295880c9499 100644 --- a/src/test/ui/resolve/issue-17518.rs +++ b/src/test/ui/resolve/issue-17518.rs @@ -9,10 +9,10 @@ // except according to those terms. enum SomeEnum { +//~^ HELP you can import it into scope E } fn main() { - E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E` - //~^ HELP you can import it into scope: `use SomeEnum::E;` + E { name: "foobar" }; //~ ERROR cannot find struct, variant or union type `E` } diff --git a/src/test/ui/resolve/issue-17518.stderr b/src/test/ui/resolve/issue-17518.stderr index bdc4fb0d349..33f15267e4a 100644 --- a/src/test/ui/resolve/issue-17518.stderr +++ b/src/test/ui/resolve/issue-17518.stderr @@ -1,7 +1,7 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope - --> $DIR/issue-17518.rs:16:5 + --> $DIR/issue-17518.rs:17:5 | -16 | E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E` +17 | E { name: "foobar" }; //~ ERROR cannot find struct, variant or union type `E` | ^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-21221-1.rs b/src/test/ui/resolve/issue-21221-1.rs index b1266a5af35..d3c18d4c80a 100644 --- a/src/test/ui/resolve/issue-21221-1.rs +++ b/src/test/ui/resolve/issue-21221-1.rs @@ -51,11 +51,7 @@ struct Foo; // help: `std::ops::Mul` impl Mul for Foo { -//~^ ERROR unresolved trait `Mul` -//~| HELP possible candidates are found in other modules, you can import them into scope -//~| HELP `mul1::Mul` -//~| HELP `mul2::Mul` -//~| HELP `std::ops::Mul` +//~^ ERROR cannot find trait `Mul` } // BEFORE, we got: @@ -70,24 +66,17 @@ impl Mul for Foo { // help: `mul4::Mul` // help: and 2 other candidates fn getMul() -> Mul { -//~^ ERROR unresolved type `Mul` -//~| HELP possible candidates are found in other modules, you can import them into scope -//~| HELP `mul1::Mul` -//~| HELP `mul2::Mul` -//~| HELP `mul3::Mul` -//~| HELP `mul4::Mul` -//~| HELP and 2 other candidates +//~^ ERROR cannot find type `Mul` } // Let's also test what happens if the trait doesn't exist: impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { -//~^ ERROR unresolved trait `ThisTraitReallyDoesntExistInAnyModuleReally` +//~^ ERROR cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` } // Let's also test what happens if there's just one alternative: impl Div for Foo { -//~^ ERROR unresolved trait `Div` -//~| HELP `use std::ops::Div;` +//~^ ERROR cannot find trait `Div` } fn main() { diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index 6038c683e43..88405fd841b 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -13,9 +13,9 @@ help: possible candidates are found in other modules, you can import them into s | error[E0412]: cannot find type `Mul` in this scope - --> $DIR/issue-21221-1.rs:72:16 + --> $DIR/issue-21221-1.rs:68:16 | -72 | fn getMul() -> Mul { +68 | fn getMul() -> Mul { | ^^^ not found in this scope help: possible candidates are found in other modules, you can import them into scope | @@ -30,15 +30,15 @@ help: possible candidates are found in other modules, you can import them into s and 2 other candidates error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope - --> $DIR/issue-21221-1.rs:83:6 + --> $DIR/issue-21221-1.rs:73:6 | -83 | impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { +73 | impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error[E0405]: cannot find trait `Div` in this scope - --> $DIR/issue-21221-1.rs:88:6 + --> $DIR/issue-21221-1.rs:78:6 | -88 | impl Div for Foo { +78 | impl Div for Foo { | ^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-21221-2.rs b/src/test/ui/resolve/issue-21221-2.rs index 15e859329c4..c0ebc57efb5 100644 --- a/src/test/ui/resolve/issue-21221-2.rs +++ b/src/test/ui/resolve/issue-21221-2.rs @@ -9,6 +9,7 @@ // except according to those terms. pub mod foo { +//~^ HELP you can import it into scope pub mod bar { // note: trait T is not public, but being in the current // crate, it's fine to show it, since the programmer can @@ -26,5 +27,4 @@ pub mod baz { struct Foo; impl T for Foo { } -//~^ ERROR unresolved trait `T` -//~| HELP you can import it into scope: `use foo::bar::T;` +//~^ ERROR cannot find trait `T` diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index 0ae8052758d..ffe57c5099d 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -1,7 +1,7 @@ error[E0405]: cannot find trait `T` in this scope - --> $DIR/issue-21221-2.rs:28:6 + --> $DIR/issue-21221-2.rs:29:6 | -28 | impl T for Foo { } +29 | impl T for Foo { } | ^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-21221-3.rs b/src/test/ui/resolve/issue-21221-3.rs index 5d62cb85914..046066b1986 100644 --- a/src/test/ui/resolve/issue-21221-3.rs +++ b/src/test/ui/resolve/issue-21221-3.rs @@ -16,6 +16,7 @@ extern crate issue_21221_3; struct Foo; +//~^ HELP possible candidate is found in another module // NOTE: This shows only traits accessible from the current // crate, thus the two private entities: @@ -23,8 +24,7 @@ struct Foo; // `issue_21221_3::outer::public_module::OuterTrait` // are hidden from the view. impl OuterTrait for Foo {} -//~^ ERROR unresolved trait `OuterTrait` -//~| HELP you can import it into scope: `use issue_21221_3::outer::OuterTrait;` +//~^ ERROR cannot find trait `OuterTrait` fn main() { println!("Hello, world!"); } diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index b26a8cdacb0..f134b864414 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -1,7 +1,7 @@ error[E0405]: cannot find trait `OuterTrait` in this scope - --> $DIR/issue-21221-3.rs:25:6 + --> $DIR/issue-21221-3.rs:26:6 | -25 | impl OuterTrait for Foo {} +26 | impl OuterTrait for Foo {} | ^^^^^^^^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-21221-4.rs b/src/test/ui/resolve/issue-21221-4.rs index ff6698f8717..da8f2c6e778 100644 --- a/src/test/ui/resolve/issue-21221-4.rs +++ b/src/test/ui/resolve/issue-21221-4.rs @@ -16,10 +16,10 @@ extern crate issue_21221_4; struct Foo; +//~^ HELP possible candidate is found in another module impl T for Foo {} -//~^ ERROR unresolved trait `T` -//~| HELP you can import it into scope: `use issue_21221_4::T;` +//~^ ERROR cannot find trait `T` fn main() { println!("Hello, world!"); diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index 0a22d8e1fe1..0f3830bc258 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -1,7 +1,7 @@ error[E0405]: cannot find trait `T` in this scope - --> $DIR/issue-21221-4.rs:20:6 + --> $DIR/issue-21221-4.rs:21:6 | -20 | impl T for Foo {} +21 | impl T for Foo {} | ^ not found in this scope help: possible candidate is found in another module, you can import it into scope | diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index 19069f49167..9f7b6ff5767 100644 --- a/src/test/ui/resolve/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -13,10 +13,9 @@ pub trait ToNbt<T> { } impl ToNbt<Self> {} -//~^ ERROR unresolved type `Self` -//~| NOTE `Self` is only available in traits and impls -//~| ERROR the trait `ToNbt` cannot be made into an object -//~| NOTE the trait `ToNbt` cannot be made into an object -//~| NOTE method `new` has no receiver +//~^ ERROR unsupported cyclic reference +//~| NOTE cyclic reference +//~| NOTE the cycle begins when processing +//~| NOTE ...which then again requires fn main() {} diff --git a/src/test/ui/resolve/issue-2356.rs b/src/test/ui/resolve/issue-2356.rs index 6deb598b631..d0490ff981d 100644 --- a/src/test/ui/resolve/issue-2356.rs +++ b/src/test/ui/resolve/issue-2356.rs @@ -25,24 +25,22 @@ impl MaybeDog { fn bark() { // If this provides a suggestion, it's a bug as MaybeDog doesn't impl Groom shave(); - //~^ ERROR unresolved function `shave` - //~| NOTE no resolution found + //~^ ERROR cannot find function `shave` + //~| NOTE not found in this scope } } impl Clone for cat { fn clone(&self) -> Self { clone(); - //~^ ERROR unresolved function `clone` - //~| NOTE did you mean `self.clone(...)`? + //~^ ERROR cannot find function `clone` loop {} } } impl Default for cat { fn default() -> Self { default(); - //~^ ERROR unresolved function `default` - //~| NOTE did you mean `Self::default`? + //~^ ERROR cannot find function `default` loop {} } } @@ -50,16 +48,13 @@ impl Default for cat { impl Groom for cat { fn shave(other: usize) { whiskers -= other; - //~^ ERROR unresolved value `whiskers` - //~| ERROR unresolved value `whiskers` - //~| NOTE did you mean `self.whiskers`? + //~^ ERROR cannot find value `whiskers` //~| NOTE `self` value is only available in methods with `self` parameter shave(4); - //~^ ERROR unresolved function `shave` - //~| NOTE did you mean `Self::shave`? + //~^ ERROR cannot find function `shave` purr(); - //~^ ERROR unresolved function `purr` - //~| NOTE no resolution found + //~^ ERROR cannot find function `purr` + //~| NOTE not found in this scope } } @@ -68,17 +63,17 @@ impl cat { fn purr_louder() { static_method(); - //~^ ERROR unresolved function `static_method` - //~| NOTE no resolution found + //~^ ERROR cannot find function `static_method` + //~| NOTE not found in this scope purr(); - //~^ ERROR unresolved function `purr` - //~| NOTE no resolution found + //~^ ERROR cannot find function `purr` + //~| NOTE not found in this scope purr(); - //~^ ERROR unresolved function `purr` - //~| NOTE no resolution found + //~^ ERROR cannot find function `purr` + //~| NOTE not found in this scope purr(); - //~^ ERROR unresolved function `purr` - //~| NOTE no resolution found + //~^ ERROR cannot find function `purr` + //~| NOTE not found in this scope } } @@ -93,28 +88,25 @@ impl cat { fn purr(&self) { grow_older(); - //~^ ERROR unresolved function `grow_older` - //~| NOTE no resolution found + //~^ ERROR cannot find function `grow_older` + //~| NOTE not found in this scope shave(); - //~^ ERROR unresolved function `shave` - //~| NOTE no resolution found + //~^ ERROR cannot find function `shave` + //~| NOTE not found in this scope } fn burn_whiskers(&mut self) { whiskers = 0; - //~^ ERROR unresolved value `whiskers` - //~| NOTE did you mean `self.whiskers`? + //~^ ERROR cannot find value `whiskers` } pub fn grow_older(other:usize) { whiskers = 4; - //~^ ERROR unresolved value `whiskers` - //~| ERROR unresolved value `whiskers` - //~| NOTE did you mean `self.whiskers`? + //~^ ERROR cannot find value `whiskers` //~| NOTE `self` value is only available in methods with `self` parameter purr_louder(); - //~^ ERROR unresolved function `purr_louder` - //~| NOTE no resolution found + //~^ ERROR cannot find function `purr_louder` + //~| NOTE not found in this scope } } diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr index ed0edd52587..e98d132b519 100644 --- a/src/test/ui/resolve/issue-2356.stderr +++ b/src/test/ui/resolve/issue-2356.stderr @@ -11,99 +11,99 @@ error[E0425]: cannot find function `clone` in this scope | ^^^^^ help: try: `self.clone` error[E0425]: cannot find function `default` in this scope - --> $DIR/issue-2356.rs:43:5 + --> $DIR/issue-2356.rs:42:5 | -43 | default(); +42 | default(); | ^^^^^^^ help: try: `Self::default` error[E0425]: cannot find value `whiskers` in this scope - --> $DIR/issue-2356.rs:52:5 + --> $DIR/issue-2356.rs:50:5 | -52 | whiskers -= other; +50 | whiskers -= other; | ^^^^^^^^ | | | `self` value is only available in methods with `self` parameter | help: try: `self.whiskers` error[E0425]: cannot find function `shave` in this scope - --> $DIR/issue-2356.rs:57:5 + --> $DIR/issue-2356.rs:53:5 | -57 | shave(4); +53 | shave(4); | ^^^^^ help: try: `Self::shave` error[E0425]: cannot find function `purr` in this scope - --> $DIR/issue-2356.rs:60:5 + --> $DIR/issue-2356.rs:55:5 | -60 | purr(); +55 | purr(); | ^^^^ not found in this scope error[E0425]: cannot find function `static_method` in this scope - --> $DIR/issue-2356.rs:70:9 + --> $DIR/issue-2356.rs:65:9 | -70 | static_method(); +65 | static_method(); | ^^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `purr` in this scope - --> $DIR/issue-2356.rs:73:9 + --> $DIR/issue-2356.rs:68:9 | -73 | purr(); +68 | purr(); | ^^^^ not found in this scope error[E0425]: cannot find function `purr` in this scope - --> $DIR/issue-2356.rs:76:9 + --> $DIR/issue-2356.rs:71:9 | -76 | purr(); +71 | purr(); | ^^^^ not found in this scope error[E0425]: cannot find function `purr` in this scope - --> $DIR/issue-2356.rs:79:9 + --> $DIR/issue-2356.rs:74:9 | -79 | purr(); +74 | purr(); | ^^^^ not found in this scope error[E0424]: expected value, found module `self` - --> $DIR/issue-2356.rs:87:8 + --> $DIR/issue-2356.rs:82:8 | -87 | if self.whiskers > 3 { +82 | if self.whiskers > 3 { | ^^^^ `self` value is only available in methods with `self` parameter error[E0425]: cannot find function `grow_older` in this scope - --> $DIR/issue-2356.rs:95:5 + --> $DIR/issue-2356.rs:90:5 | -95 | grow_older(); +90 | grow_older(); | ^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `shave` in this scope - --> $DIR/issue-2356.rs:98:5 + --> $DIR/issue-2356.rs:93:5 | -98 | shave(); +93 | shave(); | ^^^^^ not found in this scope error[E0425]: cannot find value `whiskers` in this scope - --> $DIR/issue-2356.rs:104:5 - | -104 | whiskers = 0; - | ^^^^^^^^ help: try: `self.whiskers` + --> $DIR/issue-2356.rs:99:5 + | +99 | whiskers = 0; + | ^^^^^^^^ help: try: `self.whiskers` error[E0425]: cannot find value `whiskers` in this scope - --> $DIR/issue-2356.rs:110:5 + --> $DIR/issue-2356.rs:104:5 | -110 | whiskers = 4; +104 | whiskers = 4; | ^^^^^^^^ | | | `self` value is only available in methods with `self` parameter | help: try: `self.whiskers` error[E0425]: cannot find function `purr_louder` in this scope - --> $DIR/issue-2356.rs:115:5 + --> $DIR/issue-2356.rs:107:5 | -115 | purr_louder(); +107 | purr_louder(); | ^^^^^^^^^^^ not found in this scope error[E0424]: expected value, found module `self` - --> $DIR/issue-2356.rs:122:5 + --> $DIR/issue-2356.rs:114:5 | -122 | self += 1; +114 | self += 1; | ^^^^ `self` value is only available in methods with `self` parameter error: aborting due to 17 previous errors diff --git a/src/test/ui/resolve/issue-24968.rs b/src/test/ui/resolve/issue-24968.rs index 0d562cab6b8..6065646401f 100644 --- a/src/test/ui/resolve/issue-24968.rs +++ b/src/test/ui/resolve/issue-24968.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo(_: Self) { -//~^ ERROR unresolved type `Self` +//~^ ERROR cannot find type `Self` //~| NOTE `Self` is only available in traits and impls } diff --git a/src/test/ui/resolve/issue-39226.rs b/src/test/ui/resolve/issue-39226.rs index f290a74861d..f58f7cc3869 100644 --- a/src/test/ui/resolve/issue-39226.rs +++ b/src/test/ui/resolve/issue-39226.rs @@ -18,7 +18,8 @@ fn main() { let s: Something = Something { handle: Handle - //~^ ERROR cannot find value `Handle` in this scope - //~| NOTE did you mean `handle`? + //~^ ERROR expected value, found struct `Handle` + //~| NOTE did you mean `Handle { /* fields */ }`? + //~| NOTE did you mean `handle` }; } diff --git a/src/test/ui/resolve/issue-5035.rs b/src/test/ui/resolve/issue-5035.rs index 6263e6f6db4..06a753cca85 100644 --- a/src/test/ui/resolve/issue-5035.rs +++ b/src/test/ui/resolve/issue-5035.rs @@ -12,6 +12,7 @@ trait I {} type K = I; impl K for isize {} //~ ERROR expected trait, found type alias `K` //~| NOTE type aliases cannot be used for traits + //~| NOTE did you mean `I` use ImportError; //~ ERROR unresolved import `ImportError` [E0432] //~^ no `ImportError` in the root diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 3c093e068c5..c9de39759b5 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -1,7 +1,7 @@ error[E0432]: unresolved import `ImportError` - --> $DIR/issue-5035.rs:16:5 + --> $DIR/issue-5035.rs:17:5 | -16 | use ImportError; //~ ERROR unresolved import `ImportError` [E0432] +17 | use ImportError; //~ ERROR unresolved import `ImportError` [E0432] | ^^^^^^^^^^^ no `ImportError` in the root error[E0404]: expected trait, found type alias `K` diff --git a/src/test/ui/resolve/levenshtein.rs b/src/test/ui/resolve/levenshtein.rs index 53b6372d8eb..af27629385d 100644 --- a/src/test/ui/resolve/levenshtein.rs +++ b/src/test/ui/resolve/levenshtein.rs @@ -13,14 +13,18 @@ const MAX_ITEM: usize = 10; fn foo_bar() {} fn foo(c: esize) {} // Misspelled primitive type name. +//~^ ERROR cannot find enum Bar { } type A = Baz; // Misspelled type name. +//~^ ERROR cannot find type B = Opiton<u8>; // Misspelled type name from the prelude. +//~^ ERROR cannot find mod m { type A = Baz; // No suggestion here, Bar is not visible + //~^ ERROR cannot find pub struct First; pub struct Second; @@ -28,6 +32,10 @@ mod m { fn main() { let v = [0u32; MAXITEM]; // Misspelled constant name. + //~^ ERROR cannot find foobar(); // Misspelled function name. + //~^ ERROR cannot find let b: m::first = m::second; // Misspelled item in module. + //~^ ERROR cannot find + //~| ERROR cannot find } diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 4dff2620319..68d46ccf685 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -5,45 +5,45 @@ error[E0412]: cannot find type `esize` in this scope | ^^^^^ did you mean `isize`? error[E0412]: cannot find type `Baz` in this scope - --> $DIR/levenshtein.rs:19:10 + --> $DIR/levenshtein.rs:20:10 | -19 | type A = Baz; // Misspelled type name. +20 | type A = Baz; // Misspelled type name. | ^^^ did you mean `Bar`? error[E0412]: cannot find type `Opiton` in this scope - --> $DIR/levenshtein.rs:20:10 + --> $DIR/levenshtein.rs:22:10 | -20 | type B = Opiton<u8>; // Misspelled type name from the prelude. +22 | type B = Opiton<u8>; // Misspelled type name from the prelude. | ^^^^^^ did you mean `Option`? error[E0412]: cannot find type `Baz` in this scope - --> $DIR/levenshtein.rs:23:14 + --> $DIR/levenshtein.rs:26:14 | -23 | type A = Baz; // No suggestion here, Bar is not visible +26 | type A = Baz; // No suggestion here, Bar is not visible | ^^^ not found in this scope error[E0425]: cannot find value `MAXITEM` in this scope - --> $DIR/levenshtein.rs:30:20 + --> $DIR/levenshtein.rs:34:20 | -30 | let v = [0u32; MAXITEM]; // Misspelled constant name. +34 | let v = [0u32; MAXITEM]; // Misspelled constant name. | ^^^^^^^ did you mean `MAX_ITEM`? error[E0425]: cannot find function `foobar` in this scope - --> $DIR/levenshtein.rs:31:5 + --> $DIR/levenshtein.rs:36:5 | -31 | foobar(); // Misspelled function name. +36 | foobar(); // Misspelled function name. | ^^^^^^ did you mean `foo_bar`? error[E0412]: cannot find type `first` in module `m` - --> $DIR/levenshtein.rs:32:15 + --> $DIR/levenshtein.rs:38:15 | -32 | let b: m::first = m::second; // Misspelled item in module. +38 | let b: m::first = m::second; // Misspelled item in module. | ^^^^^ did you mean `First`? error[E0425]: cannot find value `second` in module `m` - --> $DIR/levenshtein.rs:32:26 + --> $DIR/levenshtein.rs:38:26 | -32 | let b: m::first = m::second; // Misspelled item in module. +38 | let b: m::first = m::second; // Misspelled item in module. | ^^^^^^ did you mean `Second`? error: aborting due to 8 previous errors diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs index 87e7b4f42a1..fe3774af47d 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.rs +++ b/src/test/ui/resolve/privacy-struct-ctor.rs @@ -25,7 +25,9 @@ mod m { n::Z; //~ ERROR tuple struct `Z` is private Z; //~^ ERROR expected value, found struct `Z` - //~| NOTE tuple struct constructors with private fields are invisible outside of their mod + //~| NOTE constructor is not visible here due to private fields + //~| NOTE did you mean `S` + //~| NOTE did you mean `Z { /* fields */ }` } } @@ -36,11 +38,13 @@ fn main() { S; //~^ ERROR expected value, found struct `S` //~| NOTE constructor is not visible here due to private fields + //~| NOTE did you mean `S { /* fields */ }` m::n::Z; //~ ERROR tuple struct `Z` is private xcrate::m::S; //~ ERROR tuple struct `S` is private xcrate::S; //~^ ERROR expected value, found struct `xcrate::S` + //~| NOTE did you mean `xcrate::S { /* fields */ }` //~| NOTE constructor is not visible here due to private fields xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private } diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index cb459ae4745..81c52a1b7c3 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -13,29 +13,29 @@ help: possible better candidate is found in another module, you can import it in | error[E0423]: expected value, found struct `S` - --> $DIR/privacy-struct-ctor.rs:36:5 + --> $DIR/privacy-struct-ctor.rs:38:5 | -36 | S; +38 | S; | ^ | | | constructor is not visible here due to private fields | did you mean `S { /* fields */ }`? help: possible better candidate is found in another module, you can import it into scope | -32 | use m::S; +34 | use m::S; | error[E0423]: expected value, found struct `xcrate::S` - --> $DIR/privacy-struct-ctor.rs:42:5 + --> $DIR/privacy-struct-ctor.rs:45:5 | -42 | xcrate::S; +45 | xcrate::S; | ^^^^^^^^^ | | | constructor is not visible here due to private fields | did you mean `xcrate::S { /* fields */ }`? help: possible better candidate is found in another module, you can import it into scope | -32 | use m::S; +34 | use m::S; | error[E0603]: tuple struct `Z` is private @@ -45,27 +45,27 @@ error[E0603]: tuple struct `Z` is private | ^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:35:5 + --> $DIR/privacy-struct-ctor.rs:37:5 | -35 | m::S; //~ ERROR tuple struct `S` is private +37 | m::S; //~ ERROR tuple struct `S` is private | ^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:39:5 + --> $DIR/privacy-struct-ctor.rs:42:5 | -39 | m::n::Z; //~ ERROR tuple struct `Z` is private +42 | m::n::Z; //~ ERROR tuple struct `Z` is private | ^^^^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:41:5 + --> $DIR/privacy-struct-ctor.rs:44:5 | -41 | xcrate::m::S; //~ ERROR tuple struct `S` is private +44 | xcrate::m::S; //~ ERROR tuple struct `S` is private | ^^^^^^^^^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:45:5 + --> $DIR/privacy-struct-ctor.rs:49:5 | -45 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private +49 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private | ^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.rs b/src/test/ui/resolve/resolve-assoc-suggestions.rs index 53e26ddafec..62d2dc7a8fa 100644 --- a/src/test/ui/resolve/resolve-assoc-suggestions.rs +++ b/src/test/ui/resolve/resolve-assoc-suggestions.rs @@ -24,34 +24,31 @@ impl Tr for S { fn method(&self) { let _: field; - //~^ ERROR unresolved type `field` - //~| NOTE no resolution found + //~^ ERROR cannot find type `field` + //~| NOTE not found in this scope let field(..); - //~^ ERROR unresolved tuple struct/variant `field` - //~| NOTE no resolution found + //~^ ERROR cannot find tuple struct/variant `field` + //~| NOTE not found in this scope field; - //~^ ERROR unresolved value `field` - //~| NOTE did you mean `self.field`? + //~^ ERROR cannot find value `field` let _: Type; - //~^ ERROR unresolved type `Type` - //~| NOTE did you mean `Self::Type`? + //~^ ERROR cannot find type `Type` let Type(..); - //~^ ERROR unresolved tuple struct/variant `Type` - //~| NOTE no resolution found + //~^ ERROR cannot find tuple struct/variant `Type` + //~| NOTE not found in this scope Type; - //~^ ERROR unresolved value `Type` - //~| NOTE no resolution found + //~^ ERROR cannot find value `Type` + //~| NOTE not found in this scope let _: method; - //~^ ERROR unresolved type `method` - //~| NOTE no resolution found + //~^ ERROR cannot find type `method` + //~| NOTE not found in this scope let method(..); - //~^ ERROR unresolved tuple struct/variant `method` - //~| NOTE no resolution found + //~^ ERROR cannot find tuple struct/variant `method` + //~| NOTE not found in this scope method; - //~^ ERROR unresolved value `method` - //~| NOTE did you mean `self.method(...)`? + //~^ ERROR cannot find value `method` } } diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.stderr b/src/test/ui/resolve/resolve-assoc-suggestions.stderr index 77aa545e2ad..4bb3947a028 100644 --- a/src/test/ui/resolve/resolve-assoc-suggestions.stderr +++ b/src/test/ui/resolve/resolve-assoc-suggestions.stderr @@ -17,39 +17,39 @@ error[E0425]: cannot find value `field` in this scope | ^^^^^ help: try: `self.field` error[E0412]: cannot find type `Type` in this scope - --> $DIR/resolve-assoc-suggestions.rs:36:16 + --> $DIR/resolve-assoc-suggestions.rs:35:16 | -36 | let _: Type; +35 | let _: Type; | ^^^^ help: try: `Self::Type` error[E0531]: cannot find tuple struct/variant `Type` in this scope - --> $DIR/resolve-assoc-suggestions.rs:39:13 + --> $DIR/resolve-assoc-suggestions.rs:37:13 | -39 | let Type(..); +37 | let Type(..); | ^^^^ not found in this scope error[E0425]: cannot find value `Type` in this scope - --> $DIR/resolve-assoc-suggestions.rs:42:9 + --> $DIR/resolve-assoc-suggestions.rs:40:9 | -42 | Type; +40 | Type; | ^^^^ not found in this scope error[E0412]: cannot find type `method` in this scope - --> $DIR/resolve-assoc-suggestions.rs:46:16 + --> $DIR/resolve-assoc-suggestions.rs:44:16 | -46 | let _: method; +44 | let _: method; | ^^^^^^ not found in this scope error[E0531]: cannot find tuple struct/variant `method` in this scope - --> $DIR/resolve-assoc-suggestions.rs:49:13 + --> $DIR/resolve-assoc-suggestions.rs:47:13 | -49 | let method(..); +47 | let method(..); | ^^^^^^ not found in this scope error[E0425]: cannot find value `method` in this scope - --> $DIR/resolve-assoc-suggestions.rs:52:9 + --> $DIR/resolve-assoc-suggestions.rs:50:9 | -52 | method; +50 | method; | ^^^^^^ help: try: `self.method` error: aborting due to 9 previous errors diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.rs b/src/test/ui/resolve/resolve-speculative-adjustment.rs index 95289e23f9e..120237b662d 100644 --- a/src/test/ui/resolve/resolve-speculative-adjustment.rs +++ b/src/test/ui/resolve/resolve-speculative-adjustment.rs @@ -25,19 +25,17 @@ impl Tr for S { // Speculative resolution of `Self` and `self` silently fails, // "did you mean" messages are not printed. field; - //~^ ERROR unresolved value `field` - //~| NOTE no resolution found + //~^ ERROR cannot find value `field` + //~| NOTE not found in this scope method(); - //~^ ERROR unresolved function `method` - //~| NOTE no resolution found + //~^ ERROR cannot find function `method` + //~| NOTE not found in this scope } field; - //~^ ERROR unresolved value `field` - //~| NOTE did you mean `self.field`? + //~^ ERROR cannot find value `field` method(); - //~^ ERROR unresolved function `method` - //~| NOTE did you mean `self.method(...)`? + //~^ ERROR cannot find function `method` } } diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.stderr b/src/test/ui/resolve/resolve-speculative-adjustment.stderr index 3e1b075679a..2d74e427ea0 100644 --- a/src/test/ui/resolve/resolve-speculative-adjustment.stderr +++ b/src/test/ui/resolve/resolve-speculative-adjustment.stderr @@ -17,9 +17,9 @@ error[E0425]: cannot find value `field` in this scope | ^^^^^ help: try: `self.field` error[E0425]: cannot find function `method` in this scope - --> $DIR/resolve-speculative-adjustment.rs:38:9 + --> $DIR/resolve-speculative-adjustment.rs:37:9 | -38 | method(); +37 | method(); | ^^^^^^ help: try: `self.method` error: aborting due to 4 previous errors diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs index 789bdfb414d..70d072a388b 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs @@ -45,6 +45,7 @@ fn h4() -> i32 { a::b.J //~^ ERROR expected value, found module `a::b` //~| NOTE did you mean `a::b::J`? + //~| NOTE did you mean `I` } fn h5() { @@ -54,23 +55,24 @@ fn h5() { let v = Vec::new(); v.push(a::b); //~^ ERROR expected value, found module `a::b` - //~| NOTE not a value + //~| NOTE did you mean `I` } fn h6() -> i32 { a::b.f() //~^ ERROR expected value, found module `a::b` //~| NOTE did you mean `a::b::f(...)`? + //~| NOTE did you mean `I` } fn h7() { a::b //~^ ERROR expected value, found module `a::b` - //~| NOTE not a value + //~| NOTE did you mean `I` } fn h8() -> i32 { a::b() //~^ ERROR expected function, found module `a::b` - //~| NOTE not a function + //~| NOTE did you mean `I` } diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index d1794d19f6a..fd5de16bdd1 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -32,42 +32,42 @@ error[E0423]: expected value, found module `a::b` | did you mean `a::b::J`? error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:51:5 + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5 | -51 | a.b.f(); +52 | a.b.f(); | ^-- | | | did you mean `a::b`? error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:12 + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:56:12 | -55 | v.push(a::b); +56 | v.push(a::b); | ^^^- | | | did you mean `I`? error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:61:5 + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:62:5 | -61 | a::b.f() +62 | a::b.f() | ^^^----- | | | | | did you mean `I`? | did you mean `a::b::f(...)`? error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:67:5 + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:69:5 | -67 | a::b +69 | a::b | ^^^- | | | did you mean `I`? error[E0423]: expected function, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:73:5 + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:75:5 | -73 | a::b() +75 | a::b() | ^^^- | | | did you mean `I`? diff --git a/src/test/ui/resolve/token-error-correct-2.rs b/src/test/ui/resolve/token-error-correct-2.rs index 6fa1260d180..121a565b2b1 100644 --- a/src/test/ui/resolve/token-error-correct-2.rs +++ b/src/test/ui/resolve/token-error-correct-2.rs @@ -13,7 +13,7 @@ fn main() { if foo { //~^ NOTE: unclosed delimiter - //~| ERROR: unresolved value `foo` - //~| NOTE: no resolution found + //~| ERROR: cannot find value `foo` + //~| NOTE: not found in this scope ) //~ ERROR: incorrect close delimiter: `)` } diff --git a/src/test/ui/resolve/token-error-correct-3.rs b/src/test/ui/resolve/token-error-correct-3.rs index f72b7adf593..746eee9ecd7 100644 --- a/src/test/ui/resolve/token-error-correct-3.rs +++ b/src/test/ui/resolve/token-error-correct-3.rs @@ -18,16 +18,19 @@ pub mod raw { pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> { - if !is_directory(path.as_ref()) { //~ ERROR: unresolved function `is_directory` - //~^ NOTE: no resolution found + if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory` + //~^ NOTE: not found in this scope callback(path.as_ref(); //~ NOTE: unclosed delimiter - //~^ ERROR: expected one of + //~^ NOTE: expected one of + //~| ERROR expected one of fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types //~^ expected (), found enum `std::result::Result` //~| expected type `()` //~| found type `std::result::Result<bool, std::io::Error>` + //~| expected one of } else { //~ ERROR: incorrect close delimiter: `}` //~^ ERROR: expected one of + //~| unexpected token Ok(false); } diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index c8e19db3707..b500a349f6c 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -1,7 +1,7 @@ error: incorrect close delimiter: `}` - --> $DIR/token-error-correct-3.rs:29:9 + --> $DIR/token-error-correct-3.rs:31:9 | -29 | } else { //~ ERROR: incorrect close delimiter: `}` +31 | } else { //~ ERROR: incorrect close delimiter: `}` | ^ | note: unclosed delimiter @@ -17,24 +17,24 @@ error: expected one of `,`, `.`, `?`, or an operator, found `;` | ^ expected one of `,`, `.`, `?`, or an operator here error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - --> $DIR/token-error-correct-3.rs:29:9 + --> $DIR/token-error-correct-3.rs:31:9 | -25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types +26 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types | - expected one of `.`, `;`, `?`, `}`, or an operator here ... -29 | } else { //~ ERROR: incorrect close delimiter: `}` +31 | } else { //~ ERROR: incorrect close delimiter: `}` | ^ unexpected token error[E0425]: cannot find function `is_directory` in this scope --> $DIR/token-error-correct-3.rs:21:13 | -21 | if !is_directory(path.as_ref()) { //~ ERROR: unresolved function `is_directory` +21 | if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory` | ^^^^^^^^^^^^ not found in this scope error[E0308]: mismatched types - --> $DIR/token-error-correct-3.rs:25:13 + --> $DIR/token-error-correct-3.rs:26:13 | -25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types +26 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;` | | | expected (), found enum `std::result::Result` diff --git a/src/test/ui/resolve/token-error-correct.rs b/src/test/ui/resolve/token-error-correct.rs index 5fd35e51336..0c7fe0df1c7 100644 --- a/src/test/ui/resolve/token-error-correct.rs +++ b/src/test/ui/resolve/token-error-correct.rs @@ -15,11 +15,6 @@ fn main() { //~^ NOTE: unclosed delimiter //~| NOTE: unclosed delimiter //~| ERROR: expected expression, found `;` - //~| ERROR: unresolved function `foo` - //~| NOTE: no resolution found - //~| ERROR: unresolved function `bar` - //~| NOTE: no resolution found - //~| ERROR: expected one of `)`, `,`, `.`, `<`, `?` } //~^ ERROR: incorrect close delimiter: `}` //~| ERROR: incorrect close delimiter: `}` diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr index 6bd63f4fbbb..cad58b30df2 100644 --- a/src/test/ui/resolve/token-error-correct.stderr +++ b/src/test/ui/resolve/token-error-correct.stderr @@ -1,7 +1,7 @@ error: incorrect close delimiter: `}` - --> $DIR/token-error-correct.rs:23:1 + --> $DIR/token-error-correct.rs:18:1 | -23 | } +18 | } | ^ | note: unclosed delimiter @@ -11,9 +11,9 @@ note: unclosed delimiter | ^ error: incorrect close delimiter: `}` - --> $DIR/token-error-correct.rs:23:1 + --> $DIR/token-error-correct.rs:18:1 | -23 | } +18 | } | ^ | note: unclosed delimiter @@ -29,9 +29,9 @@ error: expected expression, found `;` | ^ error: expected expression, found `)` - --> $DIR/token-error-correct.rs:23:1 + --> $DIR/token-error-correct.rs:18:1 | -23 | } +18 | } | ^ error: aborting due to 4 previous errors diff --git a/src/test/ui/resolve/tuple-struct-alias.rs b/src/test/ui/resolve/tuple-struct-alias.rs index c9c05202fea..0dbca07b771 100644 --- a/src/test/ui/resolve/tuple-struct-alias.rs +++ b/src/test/ui/resolve/tuple-struct-alias.rs @@ -13,16 +13,16 @@ type A = S; impl S { fn f() { - let s = Self(0, 1); + let s = Self(0, 1); //~ ERROR expected function match s { - Self(..) => {} + Self(..) => {} //~ ERROR expected tuple struct/variant } } } fn main() { - let s = A(0, 1); + let s = A(0, 1); //~ ERROR expected function match s { - A(..) => {} + A(..) => {} //~ ERROR expected tuple struct/variant } } diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index e2ef8f0e568..aea9fc356bf 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -1,19 +1,19 @@ error[E0423]: expected function, found self type `Self` --> $DIR/tuple-struct-alias.rs:16:17 | -16 | let s = Self(0, 1); +16 | let s = Self(0, 1); //~ ERROR expected function | ^^^^ did you mean `Self { /* fields */ }`? error[E0532]: expected tuple struct/variant, found self type `Self` --> $DIR/tuple-struct-alias.rs:18:13 | -18 | Self(..) => {} +18 | Self(..) => {} //~ ERROR expected tuple struct/variant | ^^^^ did you mean `Self { /* fields */ }`? error[E0423]: expected function, found type alias `A` --> $DIR/tuple-struct-alias.rs:24:13 | -24 | let s = A(0, 1); +24 | let s = A(0, 1); //~ ERROR expected function | ^ | | | did you mean `S`? @@ -22,7 +22,7 @@ error[E0423]: expected function, found type alias `A` error[E0532]: expected tuple struct/variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:26:9 | -26 | A(..) => {} +26 | A(..) => {} //~ ERROR expected tuple struct/variant | ^ | | | did you mean `S`? diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs index 57f6ddd2d3c..ee4c40f2c8d 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs @@ -9,8 +9,8 @@ // except according to those terms. fn f<F:Nonexist(isize) -> isize>(x: F) {} -//~^ ERROR unresolved trait `Nonexist` -//~| NOTE no resolution found +//~^ ERROR cannot find trait `Nonexist` +//~| NOTE not found in this scope type Typedef = isize; diff --git a/src/test/ui/resolve/unresolved_static_type_field.rs b/src/test/ui/resolve/unresolved_static_type_field.rs index 19beabd8823..711e46b1248 100644 --- a/src/test/ui/resolve/unresolved_static_type_field.rs +++ b/src/test/ui/resolve/unresolved_static_type_field.rs @@ -17,9 +17,7 @@ struct Foo { impl Foo { fn bar() { f(cx); - //~^ ERROR unresolved value `cx` - //~| ERROR unresolved value `cx` - //~| NOTE did you mean `self.cx`? + //~^ ERROR cannot find value `cx` in this scope //~| NOTE `self` value is only available in methods with `self` parameter } } diff --git a/src/test/ui/resolve/use_suggestion_placement.rs b/src/test/ui/resolve/use_suggestion_placement.rs index a43b8fc99df..87f38df0442 100644 --- a/src/test/ui/resolve/use_suggestion_placement.rs +++ b/src/test/ui/resolve/use_suggestion_placement.rs @@ -22,15 +22,15 @@ mod foo { // test whether the use suggestion isn't // placed into the expansion of `#[derive(Debug)] - type Bar = Path; + type Bar = Path; //~ ERROR cannot find } fn main() { y!(); - let _ = A; + let _ = A; //~ ERROR cannot find foo(); } fn foo() { - type Dict<K, V> = HashMap<K, V>; + type Dict<K, V> = HashMap<K, V>; //~ ERROR cannot find } diff --git a/src/test/ui/resolve/use_suggestion_placement.stderr b/src/test/ui/resolve/use_suggestion_placement.stderr index 401825367dd..1cc2d06ab68 100644 --- a/src/test/ui/resolve/use_suggestion_placement.stderr +++ b/src/test/ui/resolve/use_suggestion_placement.stderr @@ -1,7 +1,7 @@ error[E0412]: cannot find type `Path` in this scope --> $DIR/use_suggestion_placement.rs:25:16 | -25 | type Bar = Path; +25 | type Bar = Path; //~ ERROR cannot find | ^^^^ not found in this scope help: possible candidate is found in another module, you can import it into scope | @@ -11,7 +11,7 @@ help: possible candidate is found in another module, you can import it into scop error[E0425]: cannot find value `A` in this scope --> $DIR/use_suggestion_placement.rs:30:13 | -30 | let _ = A; +30 | let _ = A; //~ ERROR cannot find | ^ not found in this scope help: possible candidate is found in another module, you can import it into scope | @@ -21,7 +21,7 @@ help: possible candidate is found in another module, you can import it into scop error[E0412]: cannot find type `HashMap` in this scope --> $DIR/use_suggestion_placement.rs:35:23 | -35 | type Dict<K, V> = HashMap<K, V>; +35 | type Dict<K, V> = HashMap<K, V>; //~ ERROR cannot find | ^^^^^^^ not found in this scope help: possible candidates are found in other modules, you can import them into scope | diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.rs b/src/test/ui/rfc-2005-default-binding-mode/const.rs index 31923343b6a..fca99f064a2 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/const.rs @@ -23,7 +23,7 @@ fn main() { let f = Foo{bar:6}; match &f { - FOO => {}, + FOO => {}, //~ ERROR mismatched types _ => panic!(), } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr index 0dfd79f3565..afcbf76c1a4 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/const.rs:26:9 | -26 | FOO => {}, +26 | FOO => {}, //~ ERROR mismatched types | ^^^ expected &Foo, found struct `Foo` | = note: expected type `&Foo` diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfc-2005-default-binding-mode/enum.rs index 58902bf06b3..76ea64e248e 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.rs @@ -18,17 +18,17 @@ use Wrapper::Wrap; pub fn main() { let Wrap(x) = &Wrap(3); - *x += 1; + *x += 1; //~ ERROR cannot assign to immutable if let Some(x) = &Some(3) { - *x += 1; + *x += 1; //~ ERROR cannot assign to immutable } else { panic!(); } while let Some(x) = &Some(3) { - *x += 1; + *x += 1; //~ ERROR cannot assign to immutable break; } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr index ad08ae83a49..052ab5892d2 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr @@ -3,7 +3,7 @@ error[E0594]: cannot assign to immutable borrowed content `*x` | 20 | let Wrap(x) = &Wrap(3); | - consider changing this to `x` -21 | *x += 1; +21 | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` @@ -11,7 +11,7 @@ error[E0594]: cannot assign to immutable borrowed content `*x` | 24 | if let Some(x) = &Some(3) { | - consider changing this to `x` -25 | *x += 1; +25 | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` @@ -19,7 +19,7 @@ error[E0594]: cannot assign to immutable borrowed content `*x` | 30 | while let Some(x) = &Some(3) { | - consider changing this to `x` -31 | *x += 1; +31 | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs index b5287b7cccc..2e43d9722a9 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs @@ -16,7 +16,7 @@ fn main() { match &&Some(5i32) { Some(n) => { - *n += 1; + *n += 1; //~ ERROR cannot assign to immutable let _ = n; } None => {}, @@ -24,7 +24,7 @@ fn main() { match &mut &Some(5i32) { Some(n) => { - *n += 1; + *n += 1; //~ ERROR cannot assign to immutable let _ = n; } None => {}, @@ -32,7 +32,7 @@ fn main() { match &&mut Some(5i32) { Some(n) => { - *n += 1; + *n += 1; //~ ERROR cannot assign to immutable let _ = n; } None => {}, diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr index 1dbd769373b..c1c59fe6785 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr @@ -3,7 +3,7 @@ error[E0594]: cannot assign to immutable borrowed content `*n` | 18 | Some(n) => { | - consider changing this to `n` -19 | *n += 1; +19 | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` @@ -11,7 +11,7 @@ error[E0594]: cannot assign to immutable borrowed content `*n` | 26 | Some(n) => { | - consider changing this to `n` -27 | *n += 1; +27 | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` @@ -19,7 +19,7 @@ error[E0594]: cannot assign to immutable borrowed content `*n` | 34 | Some(n) => { | - consider changing this to `n` -35 | *n += 1; +35 | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs index 35f8fbb9b71..e9004c13a0e 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs @@ -16,5 +16,6 @@ pub fn main() { let mut tups = vec![(Foo{}, Foo{})]; // The below desugars to &(ref n, mut m). for (n, mut m) in &tups { + //~^ ERROR cannot bind by-move and by-ref in the same pattern } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs index 294d6b88596..9fbcf5d68b6 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs @@ -16,6 +16,7 @@ pub fn main() { let x = &Some((3, 3)); let _: &i32 = match x { Some((x, 3)) | &Some((ref x, 5)) => x, + //~^ ERROR is bound in inconsistent ways _ => &5i32, }; } diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfc-2005-default-binding-mode/lit.rs index 54cee39209b..783287fd458 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.rs @@ -16,7 +16,7 @@ fn with_str() { let s: &'static str = "abc"; match &s { - "abc" => true, + "abc" => true, //~ ERROR mismatched types _ => panic!(), }; } @@ -25,7 +25,7 @@ fn with_bytes() { let s: &'static [u8] = b"abc"; match &s { - b"abc" => true, + b"abc" => true, //~ ERROR mismatched types _ => panic!(), }; } diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr index 811d3b8074f..f5ed7ee7181 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/lit.rs:19:13 | -19 | "abc" => true, +19 | "abc" => true, //~ ERROR mismatched types | ^^^^^ expected &str, found str | = note: expected type `&&str` @@ -10,7 +10,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/lit.rs:28:9 | -28 | b"abc" => true, +28 | b"abc" => true, //~ ERROR mismatched types | ^^^^^^ expected &[u8], found array of 3 elements | = note: expected type `&&[u8]` diff --git a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.rs b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.rs index a0134c499bb..0b2318d7621 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.rs @@ -15,7 +15,7 @@ fn main() { let foo = 22; match foo { - u32::XXX => { } + u32::XXX => { } //~ ERROR no associated item named _ => { } } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr index da065eea897..83042287588 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr @@ -1,8 +1,8 @@ error[E0599]: no associated item named `XXX` found for type `u32` in the current scope --> $DIR/no-double-error.rs:18:9 | -18 | u32::XXX => { } - | ^^^^^^^^ +18 | u32::XXX => { } //~ ERROR no associated item named + | ^^^^^^^^ associated item not found in `u32` error: aborting due to previous error diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index fb87ed72abc..40aa957242c 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -14,7 +14,7 @@ pub fn main() { let sl: &[u8] = b"foo"; - match sl { + match sl { //~ ERROR non-exhaustive patterns [first, remainder..] => {}, }; } diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index 90a2f75c07f..ec2225c9f92 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -1,7 +1,7 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered --> $DIR/slice.rs:17:11 | -17 | match sl { +17 | match sl { //~ ERROR non-exhaustive patterns | ^^ pattern `&[]` not covered error: aborting due to previous error diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs b/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs index 52ff817dff4..b9b974ff3c5 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - if let Some(y) = &Some(22) { + if let Some(y) = &Some(22) { //~ ERROR non-reference pattern println!("{}", y); } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr index 0594f865f32..b10980d6bd6 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr @@ -1,7 +1,7 @@ error: non-reference pattern used to match a reference (see issue #42640) --> $DIR/suggestion.rs:12:12 | -12 | if let Some(y) = &Some(22) { +12 | if let Some(y) = &Some(22) { //~ ERROR non-reference pattern | ^^^^^^^ help: consider using: `&Some(y)` | = help: add #![feature(match_default_bindings)] to the crate attributes to enable diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs index 3741ba4f3ae..b24b2d0fb24 100644 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs +++ b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs @@ -56,21 +56,22 @@ fn need_to_use_this_value() -> bool { } fn main() { - need_to_use_this_value(); + need_to_use_this_value(); //~ WARN unused return value let mut m = MyStruct { n: 2 }; let n = MyStruct { n: 3 }; - m.need_to_use_this_method_value(); + m.need_to_use_this_method_value(); //~ WARN unused return value m.is_even(); // trait method! + //~^ WARN unused return value m.replace(3); // won't warn (annotation needs to be in trait definition) // comparison methods are `must_use` - 2.eq(&3); - m.eq(&n); + 2.eq(&3); //~ WARN unused return value + m.eq(&n); //~ WARN unused return value // lint includes comparison operators - 2 == 3; - m == n; + 2 == 3; //~ WARN unused comparison + m == n; //~ WARN unused comparison } diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr index fdd0a591bc7..4778f2e6d1b 100644 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr +++ b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr @@ -1,7 +1,7 @@ warning: unused return value of `need_to_use_this_value` which must be used: it's important --> $DIR/fn_must_use.rs:59:5 | -59 | need_to_use_this_value(); +59 | need_to_use_this_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -13,7 +13,7 @@ note: lint level defined here warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used --> $DIR/fn_must_use.rs:64:5 | -64 | m.need_to_use_this_method_value(); +64 | m.need_to_use_this_method_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused return value of `EvenNature::is_even` which must be used: no side effects @@ -23,26 +23,26 @@ warning: unused return value of `EvenNature::is_even` which must be used: no sid | ^^^^^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:70:5 + --> $DIR/fn_must_use.rs:71:5 | -70 | 2.eq(&3); +71 | 2.eq(&3); //~ WARN unused return value | ^^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:71:5 + --> $DIR/fn_must_use.rs:72:5 | -71 | m.eq(&n); +72 | m.eq(&n); //~ WARN unused return value | ^^^^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:74:5 + --> $DIR/fn_must_use.rs:75:5 | -74 | 2 == 3; +75 | 2 == 3; //~ WARN unused comparison | ^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:75:5 + --> $DIR/fn_must_use.rs:76:5 | -75 | m == n; +76 | m == n; //~ WARN unused comparison | ^^^^^^ diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/similar-tokens.rs index 986382bc8ee..b16d584ed42 100644 --- a/src/test/ui/similar-tokens.rs +++ b/src/test/ui/similar-tokens.rs @@ -14,6 +14,6 @@ mod x { } // `.` is similar to `,` so list parsing should continue to closing `}` -use x::{A. B}; +use x::{A. B}; //~ ERROR expected one of `,` or `as`, found `.` fn main() {} diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr index cf0ed646db7..1b9eb1d8ef5 100644 --- a/src/test/ui/similar-tokens.stderr +++ b/src/test/ui/similar-tokens.stderr @@ -1,7 +1,7 @@ error: expected one of `,` or `as`, found `.` --> $DIR/similar-tokens.rs:17:10 | -17 | use x::{A. B}; +17 | use x::{A. B}; //~ ERROR expected one of `,` or `as`, found `.` | ^ expected one of `,` or `as` here error: aborting due to previous error diff --git a/src/test/ui/span/E0072.rs b/src/test/ui/span/E0072.rs index 18ade4f1ab6..554dfc619d7 100644 --- a/src/test/ui/span/E0072.rs +++ b/src/test/ui/span/E0072.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct ListNode { +struct ListNode { //~ ERROR has infinite size head: u8, tail: Option<ListNode>, } diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr index 1f6dd6b1d16..82b8579d5a1 100644 --- a/src/test/ui/span/E0072.stderr +++ b/src/test/ui/span/E0072.stderr @@ -1,7 +1,7 @@ error[E0072]: recursive type `ListNode` has infinite size --> $DIR/E0072.rs:11:1 | -11 | struct ListNode { +11 | struct ListNode { //~ ERROR has infinite size | ^^^^^^^^^^^^^^^ recursive type has infinite size 12 | head: u8, 13 | tail: Option<ListNode>, diff --git a/src/test/ui/span/E0204.rs b/src/test/ui/span/E0204.rs index 9fb37607c7d..0ad6b67330d 100644 --- a/src/test/ui/span/E0204.rs +++ b/src/test/ui/span/E0204.rs @@ -12,9 +12,9 @@ struct Foo { foo: Vec<u32>, } -impl Copy for Foo { } +impl Copy for Foo { } //~ ERROR may not be implemented for this type -#[derive(Copy)] +#[derive(Copy)] //~ ERROR may not be implemented for this type struct Foo2<'a> { ty: &'a mut bool, } @@ -24,9 +24,9 @@ enum EFoo { Baz, } -impl Copy for EFoo { } +impl Copy for EFoo { } //~ ERROR may not be implemented for this type -#[derive(Copy)] +#[derive(Copy)] //~ ERROR may not be implemented for this type enum EFoo2<'a> { Bar(&'a mut bool), Baz, diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr index 4fe6afaca8e..0d9617c4c73 100644 --- a/src/test/ui/span/E0204.stderr +++ b/src/test/ui/span/E0204.stderr @@ -4,13 +4,13 @@ error[E0204]: the trait `Copy` may not be implemented for this type 12 | foo: Vec<u32>, | ------------- this field does not implement `Copy` ... -15 | impl Copy for Foo { } +15 | impl Copy for Foo { } //~ ERROR may not be implemented for this type | ^^^^ error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/E0204.rs:17:10 | -17 | #[derive(Copy)] +17 | #[derive(Copy)] //~ ERROR may not be implemented for this type | ^^^^ 18 | struct Foo2<'a> { 19 | ty: &'a mut bool, @@ -22,13 +22,13 @@ error[E0204]: the trait `Copy` may not be implemented for this type 23 | Bar { x: Vec<u32> }, | ----------- this field does not implement `Copy` ... -27 | impl Copy for EFoo { } +27 | impl Copy for EFoo { } //~ ERROR may not be implemented for this type | ^^^^ error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/E0204.rs:29:10 | -29 | #[derive(Copy)] +29 | #[derive(Copy)] //~ ERROR may not be implemented for this type | ^^^^ 30 | enum EFoo2<'a> { 31 | Bar(&'a mut bool), diff --git a/src/test/ui/span/E0493.rs b/src/test/ui/span/E0493.rs index 7915564cafb..de81068e268 100644 --- a/src/test/ui/span/E0493.rs +++ b/src/test/ui/span/E0493.rs @@ -25,6 +25,7 @@ impl Drop for Bar { } const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1; +//~^ destructors cannot be evaluated at compile-time fn main() { } diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs index 29fea052b06..1c45771ff8a 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs @@ -24,6 +24,7 @@ fn call<F>(mut f: F) where F: FnMut(Fn) { //~| NOTE first mutable borrow occurs here //~| NOTE second mutable borrow occurs here f((Box::new(|| {}))) + //~^ NOTE borrow occurs due to use of `f` in closure })); //~^ NOTE first borrow ends here } @@ -66,7 +67,7 @@ fn test6() { fn test7() { fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {} let mut f = |g: Box<FnMut(isize)>, b: isize| {}; - //~^ NOTE moved + //~^ NOTE captured outer variable f(Box::new(|a| { //~^ NOTE borrow of `f` occurs here foo(f); diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 6e7d0c17f1d..0a1429d5509 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -8,43 +8,44 @@ error[E0499]: cannot borrow `f` as mutable more than once at a time ... 26 | f((Box::new(|| {}))) | - borrow occurs due to use of `f` in closure -27 | })); +27 | //~^ NOTE borrow occurs due to use of `f` in closure +28 | })); | - first borrow ends here error[E0596]: cannot borrow immutable borrowed content `*f` as mutable - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:39:5 + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:40:5 | -37 | fn test2<F>(f: &F) where F: FnMut() { +38 | fn test2<F>(f: &F) where F: FnMut() { | -- use `&mut F` here to make mutable -38 | //~^ NOTE use `&mut F` here to make mutable -39 | (*f)(); +39 | //~^ NOTE use `&mut F` here to make mutable +40 | (*f)(); | ^^^^ cannot borrow as mutable error[E0596]: cannot borrow immutable `Box` content `*f.f` as mutable - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:50:5 + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:51:5 | -48 | fn test4(f: &Test) { +49 | fn test4(f: &Test) { | ----- use `&mut Test` here to make mutable -49 | //~^ NOTE use `&mut Test` here to make mutable -50 | f.f.call_mut(()) +50 | //~^ NOTE use `&mut Test` here to make mutable +51 | f.f.call_mut(()) | ^^^ cannot borrow as mutable error[E0504]: cannot move `f` into closure because it is borrowed - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:72:13 + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:73:13 | -70 | f(Box::new(|a| { +71 | f(Box::new(|a| { | - borrow of `f` occurs here -71 | //~^ NOTE borrow of `f` occurs here -72 | foo(f); +72 | //~^ NOTE borrow of `f` occurs here +73 | foo(f); | ^ move into closure occurs here error[E0507]: cannot move out of captured outer variable in an `FnMut` closure - --> $DIR/borrowck-call-is-borrow-issue-12224.rs:72:13 + --> $DIR/borrowck-call-is-borrow-issue-12224.rs:73:13 | -68 | let mut f = |g: Box<FnMut(isize)>, b: isize| {}; +69 | let mut f = |g: Box<FnMut(isize)>, b: isize| {}; | ----- captured outer variable ... -72 | foo(f); +73 | foo(f); | ^ cannot move out of captured outer variable in an `FnMut` closure error: aborting due to 5 previous errors diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs index 9e316b989a4..b31ba324b0c 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs @@ -26,7 +26,7 @@ fn f() { v3.push(&id('x')); // statement 6 //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here - //~| NOTE temporary value only lives until here + //~| NOTE temporary value dropped here while still borrowed //~| NOTE consider using a `let` binding to increase its lifetime { @@ -36,7 +36,7 @@ fn f() { v4.push(&id('y')); //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here - //~| NOTE temporary value only lives until here + //~| NOTE temporary value dropped here while still borrowed //~| NOTE consider using a `let` binding to increase its lifetime } // (statement 7) @@ -47,7 +47,7 @@ fn f() { v5.push(&id('z')); //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here - //~| NOTE temporary value only lives until here + //~| NOTE temporary value dropped here while still borrowed //~| NOTE consider using a `let` binding to increase its lifetime v1.push(&old[0]); diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.rs b/src/test/ui/span/borrowck-ref-into-rvalue.rs index 726d4bcdf1d..a059232daca 100644 --- a/src/test/ui/span/borrowck-ref-into-rvalue.rs +++ b/src/test/ui/span/borrowck-ref-into-rvalue.rs @@ -11,10 +11,10 @@ fn main() { let msg; match Some("Hello".to_string()) { - Some(ref m) => { //~ ERROR borrowed value does not live long enough + Some(ref m) => { msg = m; }, None => { panic!() } - } + } //~ ERROR borrowed value does not live long enough println!("{}", *msg); } diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr index ced1f762af4..91f9cddd589 100644 --- a/src/test/ui/span/borrowck-ref-into-rvalue.stderr +++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr @@ -1,10 +1,10 @@ error[E0597]: borrowed value does not live long enough --> $DIR/borrowck-ref-into-rvalue.rs:18:5 | -14 | Some(ref m) => { //~ ERROR borrowed value does not live long enough +14 | Some(ref m) => { | ----- borrow occurs here ... -18 | } +18 | } //~ ERROR borrowed value does not live long enough | ^ borrowed value dropped here while still borrowed 19 | println!("{}", *msg); 20 | } diff --git a/src/test/ui/span/coerce-suggestions.rs b/src/test/ui/span/coerce-suggestions.rs index 32d80069f00..a1a250b0e9a 100644 --- a/src/test/ui/span/coerce-suggestions.rs +++ b/src/test/ui/span/coerce-suggestions.rs @@ -18,37 +18,26 @@ fn main() { //~^ ERROR E0308 //~| NOTE expected usize, found struct `std::string::String` //~| NOTE expected type `usize` - //~| NOTE found type `std::string::String` //~| HELP here are some functions which might fulfill your needs: let x: &str = String::new(); //~^ ERROR E0308 //~| NOTE expected &str, found struct `std::string::String` //~| NOTE expected type `&str` - //~| NOTE found type `std::string::String` //~| HELP try with `&String::new()` let y = String::new(); test(&y); //~^ ERROR E0308 //~| NOTE types differ in mutability //~| NOTE expected type `&mut std::string::String` - //~| NOTE found type `&std::string::String` test2(&y); //~^ ERROR E0308 //~| NOTE types differ in mutability //~| NOTE expected type `&mut i32` - //~| NOTE found type `&std::string::String` let f; f = box f; //~^ ERROR E0308 //~| NOTE cyclic type of infinite size - //~| NOTE expected type `_` - //~| NOTE found type `Box<_>` let s = &mut String::new(); s = format!("foo"); - //~^ ERROR E0308 - //~| NOTE expected mutable reference, found struct `std::string::String` - //~| NOTE expected type `&mut std::string::String` - //~| HELP try with `&mut format!("foo")` - //~| NOTE this error originates in a macro outside of the current crate } diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index b703632bf90..73169e86a1c 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -11,9 +11,9 @@ error[E0308]: mismatched types - .len() error[E0308]: mismatched types - --> $DIR/coerce-suggestions.rs:23:19 + --> $DIR/coerce-suggestions.rs:22:19 | -23 | let x: &str = String::new(); +22 | let x: &str = String::new(); | ^^^^^^^^^^^^^ expected &str, found struct `std::string::String` | = note: expected type `&str` @@ -21,42 +21,39 @@ error[E0308]: mismatched types = help: try with `&String::new()` error[E0308]: mismatched types - --> $DIR/coerce-suggestions.rs:30:10 + --> $DIR/coerce-suggestions.rs:28:10 | -30 | test(&y); +28 | test(&y); | ^^ types differ in mutability | = note: expected type `&mut std::string::String` found type `&std::string::String` error[E0308]: mismatched types - --> $DIR/coerce-suggestions.rs:35:11 + --> $DIR/coerce-suggestions.rs:32:11 | -35 | test2(&y); +32 | test2(&y); | ^^ types differ in mutability | = note: expected type `&mut i32` found type `&std::string::String` error[E0308]: mismatched types - --> $DIR/coerce-suggestions.rs:41:9 + --> $DIR/coerce-suggestions.rs:37:9 | -41 | f = box f; +37 | f = box f; | ^^^^^ cyclic type of infinite size - | - = note: expected type `_` - found type `std::boxed::Box<_>` error[E0308]: mismatched types - --> $DIR/coerce-suggestions.rs:48:9 + --> $DIR/coerce-suggestions.rs:42:9 | -48 | s = format!("foo"); +42 | s = format!("foo"); | ^^^^^^^^^^^^^^ expected mutable reference, found struct `std::string::String` | = note: expected type `&mut std::string::String` found type `std::string::String` = help: try with `&mut format!("foo")` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/span/destructor-restrictions.rs b/src/test/ui/span/destructor-restrictions.rs index 22f615cafd7..7c80867856d 100644 --- a/src/test/ui/span/destructor-restrictions.rs +++ b/src/test/ui/span/destructor-restrictions.rs @@ -15,7 +15,7 @@ use std::cell::RefCell; fn main() { let b = { let a = Box::new(RefCell::new(4)); - *a.borrow() + 1 //~ ERROR `*a` does not live long enough - }; + *a.borrow() + 1 + }; //~ ERROR `*a` does not live long enough println!("{}", b); } diff --git a/src/test/ui/span/destructor-restrictions.stderr b/src/test/ui/span/destructor-restrictions.stderr index ee885454169..e6d24d7c135 100644 --- a/src/test/ui/span/destructor-restrictions.stderr +++ b/src/test/ui/span/destructor-restrictions.stderr @@ -1,9 +1,9 @@ error[E0597]: `*a` does not live long enough --> $DIR/destructor-restrictions.rs:19:5 | -18 | *a.borrow() + 1 //~ ERROR `*a` does not live long enough +18 | *a.borrow() + 1 | - borrow occurs here -19 | }; +19 | }; //~ ERROR `*a` does not live long enough | ^- borrowed value needs to live until here | | | `*a` dropped here while still borrowed diff --git a/src/test/ui/span/gated-features-attr-spans.rs b/src/test/ui/span/gated-features-attr-spans.rs index d5ccd2ea7ad..ace185d0169 100644 --- a/src/test/ui/span/gated-features-attr-spans.rs +++ b/src/test/ui/span/gated-features-attr-spans.rs @@ -10,14 +10,14 @@ #![feature(attr_literals)] -#[repr(align(16))] +#[repr(align(16))] //~ ERROR is experimental struct Gem { mohs_hardness: u8, poofed: bool, weapon: Weapon, } -#[repr(simd)] +#[repr(simd)] //~ ERROR are experimental struct Weapon { name: String, damage: u32 @@ -25,9 +25,10 @@ struct Weapon { impl Gem { #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon } + //~^ WARN is experimental } -#[must_use] +#[must_use] //~ WARN is experimental fn bubble(gem: Gem) -> Result<Gem, ()> { if gem.poofed { Ok(gem) diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index 66b2567f728..d067470942e 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -1,7 +1,7 @@ error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626) --> $DIR/gated-features-attr-spans.rs:13:1 | -13 | #[repr(align(16))] +13 | #[repr(align(16))] //~ ERROR is experimental | ^^^^^^^^^^^^^^^^^^ | = help: add #![feature(repr_align)] to the crate attributes to enable @@ -9,7 +9,7 @@ error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33 error: SIMD types are experimental and possibly buggy (see issue #27731) --> $DIR/gated-features-attr-spans.rs:20:1 | -20 | #[repr(simd)] +20 | #[repr(simd)] //~ ERROR are experimental | ^^^^^^^^^^^^^ | = help: add #![feature(repr_simd)] to the crate attributes to enable @@ -23,9 +23,9 @@ warning: `#[must_use]` on methods is experimental (see issue #43302) = help: add #![feature(fn_must_use)] to the crate attributes to enable warning: `#[must_use]` on functions is experimental (see issue #43302) - --> $DIR/gated-features-attr-spans.rs:30:1 + --> $DIR/gated-features-attr-spans.rs:31:1 | -30 | #[must_use] +31 | #[must_use] //~ WARN is experimental | ^^^^^^^^^^^ | = help: add #![feature(fn_must_use)] to the crate attributes to enable diff --git a/src/test/ui/span/impl-wrong-item-for-trait.rs b/src/test/ui/span/impl-wrong-item-for-trait.rs index 091df1d5dc8..d4aafabed37 100644 --- a/src/test/ui/span/impl-wrong-item-for-trait.rs +++ b/src/test/ui/span/impl-wrong-item-for-trait.rs @@ -13,7 +13,13 @@ use std::fmt::Debug; trait Foo { fn bar(&self); + //~^ NOTE item in trait + //~| NOTE `bar` from trait + //~| NOTE item in trait + //~| NOTE `bar` from trait const MY_CONST: u32; + //~^ NOTE item in trait + //~| NOTE `MY_CONST` from trait } pub struct FooConstForMethod; @@ -46,10 +52,15 @@ impl Foo for FooTypeForMethod { type bar = u64; //~^ ERROR E0325 //~| NOTE does not match trait + //~| NOTE not a member + //~| ERROR E0437 const MY_CONST: u32 = 1; } impl Debug for FooTypeForMethod { } +//~^^ ERROR E0046 +//~| NOTE missing `fmt` in implementation +//~| NOTE `fmt` from trait: fn main () {} diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr index 5812cab0d05..dfca435f2a0 100644 --- a/src/test/ui/span/impl-wrong-item-for-trait.stderr +++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr @@ -1,86 +1,86 @@ error[E0437]: type `bar` is not a member of trait `Foo` - --> $DIR/impl-wrong-item-for-trait.rs:46:5 + --> $DIR/impl-wrong-item-for-trait.rs:52:5 | -46 | type bar = u64; +52 | type bar = u64; | ^^^^^^^^^^^^^^^ not a member of trait `Foo` error[E0323]: item `bar` is an associated const, which doesn't match its trait `Foo` - --> $DIR/impl-wrong-item-for-trait.rs:24:5 + --> $DIR/impl-wrong-item-for-trait.rs:30:5 | 15 | fn bar(&self); | -------------- item in trait ... -24 | const bar: u64 = 1; +30 | const bar: u64 = 1; | ^^^^^^^^^^^^^^^^^^^ does not match trait error[E0046]: not all trait items implemented, missing: `bar` - --> $DIR/impl-wrong-item-for-trait.rs:21:1 + --> $DIR/impl-wrong-item-for-trait.rs:27:1 | 15 | fn bar(&self); | -------------- `bar` from trait ... -21 | / impl Foo for FooConstForMethod { -22 | | //~^ ERROR E0046 -23 | | //~| NOTE missing `bar` in implementation -24 | | const bar: u64 = 1; +27 | / impl Foo for FooConstForMethod { +28 | | //~^ ERROR E0046 +29 | | //~| NOTE missing `bar` in implementation +30 | | const bar: u64 = 1; ... | -27 | | const MY_CONST: u32 = 1; -28 | | } +33 | | const MY_CONST: u32 = 1; +34 | | } | |_^ missing `bar` in implementation error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `Foo` - --> $DIR/impl-wrong-item-for-trait.rs:36:5 + --> $DIR/impl-wrong-item-for-trait.rs:42:5 | -16 | const MY_CONST: u32; +20 | const MY_CONST: u32; | -------------------- item in trait ... -36 | fn MY_CONST() {} +42 | fn MY_CONST() {} | ^^^^^^^^^^^^^^^^ does not match trait error[E0046]: not all trait items implemented, missing: `MY_CONST` - --> $DIR/impl-wrong-item-for-trait.rs:32:1 + --> $DIR/impl-wrong-item-for-trait.rs:38:1 | -16 | const MY_CONST: u32; +20 | const MY_CONST: u32; | -------------------- `MY_CONST` from trait ... -32 | / impl Foo for FooMethodForConst { -33 | | //~^ ERROR E0046 -34 | | //~| NOTE missing `MY_CONST` in implementation -35 | | fn bar(&self) {} +38 | / impl Foo for FooMethodForConst { +39 | | //~^ ERROR E0046 +40 | | //~| NOTE missing `MY_CONST` in implementation +41 | | fn bar(&self) {} ... | -38 | | //~| NOTE does not match trait -39 | | } +44 | | //~| NOTE does not match trait +45 | | } | |_^ missing `MY_CONST` in implementation error[E0325]: item `bar` is an associated type, which doesn't match its trait `Foo` - --> $DIR/impl-wrong-item-for-trait.rs:46:5 + --> $DIR/impl-wrong-item-for-trait.rs:52:5 | 15 | fn bar(&self); | -------------- item in trait ... -46 | type bar = u64; +52 | type bar = u64; | ^^^^^^^^^^^^^^^ does not match trait error[E0046]: not all trait items implemented, missing: `bar` - --> $DIR/impl-wrong-item-for-trait.rs:43:1 + --> $DIR/impl-wrong-item-for-trait.rs:49:1 | 15 | fn bar(&self); | -------------- `bar` from trait ... -43 | / impl Foo for FooTypeForMethod { -44 | | //~^ ERROR E0046 -45 | | //~| NOTE missing `bar` in implementation -46 | | type bar = u64; +49 | / impl Foo for FooTypeForMethod { +50 | | //~^ ERROR E0046 +51 | | //~| NOTE missing `bar` in implementation +52 | | type bar = u64; ... | -49 | | const MY_CONST: u32 = 1; -50 | | } +57 | | const MY_CONST: u32 = 1; +58 | | } | |_^ missing `bar` in implementation error[E0046]: not all trait items implemented, missing: `fmt` - --> $DIR/impl-wrong-item-for-trait.rs:52:1 + --> $DIR/impl-wrong-item-for-trait.rs:60:1 | -52 | / impl Debug for FooTypeForMethod { -53 | | } +60 | / impl Debug for FooTypeForMethod { +61 | | } | |_^ missing `fmt` in implementation | = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` diff --git a/src/test/ui/span/issue-11925.rs b/src/test/ui/span/issue-11925.rs index 7bea8642cce..fd5625f6892 100644 --- a/src/test/ui/span/issue-11925.rs +++ b/src/test/ui/span/issue-11925.rs @@ -15,7 +15,7 @@ fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f } fn main() { let r = { let x: Box<_> = box 42; - let f = to_fn_once(move|| &x); + let f = to_fn_once(move|| &x); //~ ERROR does not live long enough f() }; diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr index 6b2942bc7a8..057ccc8d677 100644 --- a/src/test/ui/span/issue-11925.stderr +++ b/src/test/ui/span/issue-11925.stderr @@ -1,7 +1,7 @@ error[E0597]: `x` does not live long enough --> $DIR/issue-11925.rs:18:36 | -18 | let f = to_fn_once(move|| &x); +18 | let f = to_fn_once(move|| &x); //~ ERROR does not live long enough | ^ | | | borrow occurs here diff --git a/src/test/ui/span/issue-15480.rs b/src/test/ui/span/issue-15480.rs index 871e0af50bf..90f3e1fd00a 100644 --- a/src/test/ui/span/issue-15480.rs +++ b/src/test/ui/span/issue-15480.rs @@ -13,7 +13,7 @@ fn id<T>(x: T) -> T { x } fn main() { let v = vec![ &id(3) - ]; + ]; //~ ERROR borrowed value does not live long enough for &&x in &v { println!("{}", x + 3); diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr index 7f4ca19241c..4d2e6f8374c 100644 --- a/src/test/ui/span/issue-15480.stderr +++ b/src/test/ui/span/issue-15480.stderr @@ -3,7 +3,7 @@ error[E0597]: borrowed value does not live long enough | 15 | &id(3) | ----- temporary value created here -16 | ]; +16 | ]; //~ ERROR borrowed value does not live long enough | ^ temporary value dropped here while still borrowed ... 21 | } diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs index a04edd99b8b..583c5690621 100644 --- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs +++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs @@ -24,8 +24,8 @@ fn foo(x: RefCell<String>) -> String { fn foo2(x: RefCell<String>) -> String { let ret = { let y = x; - y.borrow().clone() //~ ERROR `y` does not live long enough - }; + y.borrow().clone() + }; //~ ERROR `y` does not live long enough ret } diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr index 02c03315372..090cf1d924b 100644 --- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr +++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr @@ -11,9 +11,9 @@ error[E0597]: `y` does not live long enough error[E0597]: `y` does not live long enough --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:28:5 | -27 | y.borrow().clone() //~ ERROR `y` does not live long enough +27 | y.borrow().clone() | - borrow occurs here -28 | }; +28 | }; //~ ERROR `y` does not live long enough | ^- borrowed value needs to live until here | | | `y` dropped here while still borrowed diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs index f59d2845108..041ca6c426c 100644 --- a/src/test/ui/span/issue-24690.rs +++ b/src/test/ui/span/issue-24690.rs @@ -18,8 +18,9 @@ #![warn(unused)] #[rustc_error] -fn main() { - let theTwo = 2; - let theOtherTwo = 2; +fn main() { //~ ERROR compilation successful + let theTwo = 2; //~ WARN should have a snake case name + let theOtherTwo = 2; //~ WARN should have a snake case name + //~^ WARN unused variable println!("{}", theTwo); } diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 718720ebf83..7e19c7492ce 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -1,7 +1,7 @@ warning: unused variable: `theOtherTwo` --> $DIR/issue-24690.rs:23:9 | -23 | let theOtherTwo = 2; +23 | let theOtherTwo = 2; //~ WARN should have a snake case name | ^^^^^^^^^^^ | note: lint level defined here @@ -15,7 +15,7 @@ note: lint level defined here warning: variable `theTwo` should have a snake case name such as `the_two` --> $DIR/issue-24690.rs:22:9 | -22 | let theTwo = 2; +22 | let theTwo = 2; //~ WARN should have a snake case name | ^^^^^^ | = note: #[warn(non_snake_case)] on by default @@ -23,16 +23,17 @@ warning: variable `theTwo` should have a snake case name such as `the_two` warning: variable `theOtherTwo` should have a snake case name such as `the_other_two` --> $DIR/issue-24690.rs:23:9 | -23 | let theOtherTwo = 2; +23 | let theOtherTwo = 2; //~ WARN should have a snake case name | ^^^^^^^^^^^ error: compilation successful --> $DIR/issue-24690.rs:21:1 | -21 | / fn main() { -22 | | let theTwo = 2; -23 | | let theOtherTwo = 2; -24 | | println!("{}", theTwo); -25 | | } +21 | / fn main() { //~ ERROR compilation successful +22 | | let theTwo = 2; //~ WARN should have a snake case name +23 | | let theOtherTwo = 2; //~ WARN should have a snake case name +24 | | //~^ WARN unused variable +25 | | println!("{}", theTwo); +26 | | } | |_^ diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs index 81fcb007eb4..1e3eba4bf36 100644 --- a/src/test/ui/span/issue-27522.rs +++ b/src/test/ui/span/issue-27522.rs @@ -13,7 +13,7 @@ struct SomeType {} trait Foo { - fn handler(self: &SomeType); + fn handler(self: &SomeType); //~ ERROR invalid `self` type } fn main() {} diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr index e12fb57f15d..dc02ad73ee2 100644 --- a/src/test/ui/span/issue-27522.stderr +++ b/src/test/ui/span/issue-27522.stderr @@ -1,7 +1,7 @@ error[E0307]: invalid `self` type: &SomeType --> $DIR/issue-27522.rs:16:22 | -16 | fn handler(self: &SomeType); +16 | fn handler(self: &SomeType); //~ ERROR invalid `self` type | ^^^^^^^^^ | = note: type must be `Self` or a type that dereferences to it` diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index 2a874181c7a..22eecb9d882 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -6,7 +6,7 @@ error[E0308]: mismatched types | = note: expected type `std::fmt::Arguments<'_>` found type `std::string::String` - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/issue-34264.rs b/src/test/ui/span/issue-34264.rs index 00482f50618..8baa381fb2d 100644 --- a/src/test/ui/span/issue-34264.rs +++ b/src/test/ui/span/issue-34264.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(Option<i32>, String) {} -fn bar(x, y: usize) {} +fn foo(Option<i32>, String) {} //~ ERROR expected one of +//~^ ERROR expected one of +fn bar(x, y: usize) {} //~ ERROR expected one of fn main() { foo(Some(42), 2); - foo(Some(42), 2, ""); - bar("", ""); + foo(Some(42), 2, ""); //~ ERROR this function takes + bar("", ""); //~ ERROR mismatched types bar(1, 2); - bar(1, 2, 3); + bar(1, 2, 3); //~ ERROR this function takes } diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index e25caacac8f..6ab92cab83d 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -1,34 +1,34 @@ error: expected one of `:` or `@`, found `<` --> $DIR/issue-34264.rs:11:14 | -11 | fn foo(Option<i32>, String) {} +11 | fn foo(Option<i32>, String) {} //~ ERROR expected one of | ^ expected one of `:` or `@` here error: expected one of `:` or `@`, found `)` --> $DIR/issue-34264.rs:11:27 | -11 | fn foo(Option<i32>, String) {} +11 | fn foo(Option<i32>, String) {} //~ ERROR expected one of | ^ expected one of `:` or `@` here error: expected one of `:` or `@`, found `,` - --> $DIR/issue-34264.rs:12:9 + --> $DIR/issue-34264.rs:13:9 | -12 | fn bar(x, y: usize) {} +13 | fn bar(x, y: usize) {} //~ ERROR expected one of | ^ expected one of `:` or `@` here error[E0061]: this function takes 2 parameters but 3 parameters were supplied - --> $DIR/issue-34264.rs:16:9 + --> $DIR/issue-34264.rs:17:9 | -11 | fn foo(Option<i32>, String) {} +11 | fn foo(Option<i32>, String) {} //~ ERROR expected one of | ------------------------------ defined here ... -16 | foo(Some(42), 2, ""); +17 | foo(Some(42), 2, ""); //~ ERROR this function takes | ^^^^^^^^^^^^^^^ expected 2 parameters error[E0308]: mismatched types - --> $DIR/issue-34264.rs:17:13 + --> $DIR/issue-34264.rs:18:13 | -17 | bar("", ""); +18 | bar("", ""); //~ ERROR mismatched types | ^^ expected usize, found reference | = note: expected type `usize` @@ -37,12 +37,12 @@ error[E0308]: mismatched types - .len() error[E0061]: this function takes 2 parameters but 3 parameters were supplied - --> $DIR/issue-34264.rs:19:9 + --> $DIR/issue-34264.rs:20:9 | -12 | fn bar(x, y: usize) {} +13 | fn bar(x, y: usize) {} //~ ERROR expected one of | ---------------------- defined here ... -19 | bar(1, 2, 3); +20 | bar(1, 2, 3); //~ ERROR this function takes | ^^^^^^^ expected 2 parameters error: aborting due to 6 previous errors diff --git a/src/test/ui/span/issue-35987.rs b/src/test/ui/span/issue-35987.rs index 8ff5f3b8398..fa0410686c2 100644 --- a/src/test/ui/span/issue-35987.rs +++ b/src/test/ui/span/issue-35987.rs @@ -13,6 +13,7 @@ struct Foo<T: Clone>(T); use std::ops::Add; impl<T: Clone, Add> Add for Foo<T> { +//~^ ERROR expected trait, found type parameter type Output = usize; fn add(self, rhs: Self) -> Self::Output { diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs index 893c2168c2e..c6cdb8b6db7 100644 --- a/src/test/ui/span/issue-36530.rs +++ b/src/test/ui/span/issue-36530.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[foo] +#[foo] //~ ERROR is currently unknown to the compiler mod foo { - #![foo] + #![foo] //~ ERROR is currently unknown to the compiler } diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index dc6190c2e76..50908b2ca39 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -1,7 +1,7 @@ error: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/issue-36530.rs:11:1 | -11 | #[foo] +11 | #[foo] //~ ERROR is currently unknown to the compiler | ^^^^^^ | = help: add #![feature(custom_attribute)] to the crate attributes to enable @@ -9,7 +9,7 @@ error: The attribute `foo` is currently unknown to the compiler and may have mea error: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/issue-36530.rs:13:5 | -13 | #![foo] +13 | #![foo] //~ ERROR is currently unknown to the compiler | ^^^^^^^ | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/span/issue-37767.rs b/src/test/ui/span/issue-37767.rs index 49ad40259d9..2b0250d332d 100644 --- a/src/test/ui/span/issue-37767.rs +++ b/src/test/ui/span/issue-37767.rs @@ -17,7 +17,7 @@ trait B : A { } fn bar<T: B>(a: &T) { - a.foo() + a.foo() //~ ERROR multiple applicable items } trait C { @@ -29,7 +29,7 @@ trait D : C { } fn quz<T: D>(a: &T) { - a.foo() + a.foo() //~ ERROR multiple applicable items } trait E : Sized { @@ -41,7 +41,7 @@ trait F : E { } fn foo<T: F>(a: T) { - a.foo() + a.foo() //~ ERROR multiple applicable items } fn pass<T: C>(a: &T) { diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr index 7cf74eaab8d..8babcc74ed5 100644 --- a/src/test/ui/span/issue-37767.stderr +++ b/src/test/ui/span/issue-37767.stderr @@ -1,7 +1,7 @@ error[E0034]: multiple applicable items in scope --> $DIR/issue-37767.rs:20:7 | -20 | a.foo() +20 | a.foo() //~ ERROR multiple applicable items | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `A` @@ -20,7 +20,7 @@ note: candidate #2 is defined in the trait `B` error[E0034]: multiple applicable items in scope --> $DIR/issue-37767.rs:32:7 | -32 | a.foo() +32 | a.foo() //~ ERROR multiple applicable items | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `C` @@ -39,7 +39,7 @@ note: candidate #2 is defined in the trait `D` error[E0034]: multiple applicable items in scope --> $DIR/issue-37767.rs:44:7 | -44 | a.foo() +44 | a.foo() //~ ERROR multiple applicable items | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `E` diff --git a/src/test/ui/span/issue-39018.rs b/src/test/ui/span/issue-39018.rs index 1cbc5ff1d2a..4c9d10ba46b 100644 --- a/src/test/ui/span/issue-39018.rs +++ b/src/test/ui/span/issue-39018.rs @@ -10,11 +10,13 @@ pub fn main() { let x = "Hello " + "World!"; + //~^ ERROR cannot be applied to type // Make sure that the span outputs a warning // for not having an implementation for std::ops::Add // that won't output for the above string concatenation let y = World::Hello + World::Goodbye; + //~^ ERROR cannot be applied to type } enum World { diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index e865b5192a4..db662a1df59 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -9,9 +9,9 @@ help: `to_owned()` can be used to create an owned `String` from a string referen | ^^^^^^^^^^^^^^^^^^^ error[E0369]: binary operation `+` cannot be applied to type `World` - --> $DIR/issue-39018.rs:17:13 + --> $DIR/issue-39018.rs:18:13 | -17 | let y = World::Hello + World::Goodbye; +18 | let y = World::Hello + World::Goodbye; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: an implementation of `std::ops::Add` might be missing for `World` diff --git a/src/test/ui/span/issue-39698.rs b/src/test/ui/span/issue-39698.rs index 17b3f1c5a88..33071c468b8 100644 --- a/src/test/ui/span/issue-39698.rs +++ b/src/test/ui/span/issue-39698.rs @@ -18,5 +18,9 @@ enum T { fn main() { match T::T1(123, 456) { T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + //~^ ERROR is not bound in all patterns + //~| ERROR is not bound in all patterns + //~| ERROR is not bound in all patterns + //~| ERROR is not bound in all patterns } } diff --git a/src/test/ui/span/issue-40157.rs b/src/test/ui/span/issue-40157.rs index 8f3a7ae3417..9e33ecde91c 100644 --- a/src/test/ui/span/issue-40157.rs +++ b/src/test/ui/span/issue-40157.rs @@ -10,4 +10,5 @@ fn main () { {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });} + //~^ ERROR does not live long enough } diff --git a/src/test/ui/span/issue-40157.stderr b/src/test/ui/span/issue-40157.stderr index b689bef63f1..0879cb5fac2 100644 --- a/src/test/ui/span/issue-40157.stderr +++ b/src/test/ui/span/issue-40157.stderr @@ -8,7 +8,7 @@ error[E0597]: `foo` does not live long enough | | borrow occurs here | borrowed value needs to live until here | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs index cf2a4b8d037..782cce26a95 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.rs +++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs @@ -11,6 +11,7 @@ #![allow(dead_code)] #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! +//~^ ERROR `derive` may only be applied to structs, enums and unions struct DerivedOn; fn main() {} diff --git a/src/test/ui/span/issue-7575.rs b/src/test/ui/span/issue-7575.rs index b74036c4f5c..f7059e01261 100644 --- a/src/test/ui/span/issue-7575.rs +++ b/src/test/ui/span/issue-7575.rs @@ -45,7 +45,7 @@ impl OtherTrait for usize { } } -struct Myisize(isize); +struct Myisize(isize); //~ NOTE not found for this impl Myisize { fn fff(i: isize) -> isize { //~ NOTE candidate @@ -74,18 +74,18 @@ fn no_param_bound(u: usize, m: Myisize) -> usize { u.f8(42) + u.f9(342) + m.fff(42) //~^ ERROR no method named `f9` found for type `usize` in the current scope //~| NOTE found the following associated functions; to be used as methods, functions must have a `self` parameter - //~| NOTE to use it here write `CtxtFn::f9(u, 342)` instead + //~| NOTE the following traits define an item //~| ERROR no method named `fff` found for type `Myisize` in the current scope //~| NOTE found the following associated functions; to be used as methods, functions must have a `self` parameter - //~| NOTE to use it here write `OtherTrait::f9(u, 342)` instead - //~| NOTE to use it here write `UnusedTrait::f9(u, 342)` instead + + } fn param_bound<T: ManyImplTrait>(t: T) -> bool { t.is_str() //~^ ERROR no method named `is_str` found for type `T` in the current scope //~| NOTE found the following associated functions; to be used as methods, functions must have a `self` parameter - //~| NOTE to use it here write `ManyImplTrait::is_str(t)` instead + //~| NOTE the following trait defines } fn main() { diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 08ec2a87fcd..a1ed5db69c0 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -33,6 +33,9 @@ note: candidate #3 is defined in the trait `UnusedTrait` error[E0599]: no method named `fff` found for type `Myisize` in the current scope --> $DIR/issue-7575.rs:74:30 | +48 | struct Myisize(isize); //~ NOTE not found for this + | ---------------------- method `fff` not found for this +... 74 | u.f8(42) + u.f9(342) + m.fff(42) | ^^^ | diff --git a/src/test/ui/span/macro-span-replacement.rs b/src/test/ui/span/macro-span-replacement.rs index b7aae39c469..71f37f6555e 100644 --- a/src/test/ui/span/macro-span-replacement.rs +++ b/src/test/ui/span/macro-span-replacement.rs @@ -12,7 +12,7 @@ macro_rules! m { ($a:tt $b:tt) => { - $b $a; + $b $a; //~ WARN struct is never used } } diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index af03aa6a369..ed961896306 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -1,7 +1,7 @@ warning: struct is never used: `S` --> $DIR/macro-span-replacement.rs:15:9 | -15 | $b $a; +15 | $b $a; //~ WARN struct is never used | ^^^^^^ ... 20 | m!(S struct); diff --git a/src/test/ui/span/macro-ty-params.rs b/src/test/ui/span/macro-ty-params.rs index c2443b024ce..5d93b1266a4 100644 --- a/src/test/ui/span/macro-ty-params.rs +++ b/src/test/ui/span/macro-ty-params.rs @@ -15,7 +15,8 @@ macro_rules! m { } fn main() { - foo::<T>!(); - foo::<>!(); - m!(MyTrait<>); + foo::<T>!(); //~ ERROR generic arguments in macro path + foo::<>!(); //~ ERROR generic arguments in macro path + m!(MyTrait<>); //~ ERROR generic arguments in macro path + //~^ ERROR unexpected generic arguments in path } diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr index 017a449d96f..e3e9334d9fb 100644 --- a/src/test/ui/span/macro-ty-params.stderr +++ b/src/test/ui/span/macro-ty-params.stderr @@ -1,25 +1,25 @@ error: unexpected generic arguments in path --> $DIR/macro-ty-params.rs:20:8 | -20 | m!(MyTrait<>); +20 | m!(MyTrait<>); //~ ERROR generic arguments in macro path | ^^^^^^^^^ error: generic arguments in macro path --> $DIR/macro-ty-params.rs:18:8 | -18 | foo::<T>!(); +18 | foo::<T>!(); //~ ERROR generic arguments in macro path | ^^^^^ error: generic arguments in macro path --> $DIR/macro-ty-params.rs:19:8 | -19 | foo::<>!(); +19 | foo::<>!(); //~ ERROR generic arguments in macro path | ^^^^ error: generic arguments in macro path --> $DIR/macro-ty-params.rs:20:15 | -20 | m!(MyTrait<>); +20 | m!(MyTrait<>); //~ ERROR generic arguments in macro path | ^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/span/missing-unit-argument.rs b/src/test/ui/span/missing-unit-argument.rs index ba1a999121c..a586d33eaa7 100644 --- a/src/test/ui/span/missing-unit-argument.rs +++ b/src/test/ui/span/missing-unit-argument.rs @@ -18,10 +18,10 @@ impl S { } fn main() { - let _: Result<(), String> = Ok(); - foo(); - foo(()); - bar(); - S.baz(); - S.generic::<()>(); + let _: Result<(), String> = Ok(); //~ ERROR this function takes + foo(); //~ ERROR this function takes + foo(()); //~ ERROR this function takes + bar(); //~ ERROR this function takes + S.baz(); //~ ERROR this function takes + S.generic::<()>(); //~ ERROR this function takes } diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr index 672b0718a02..27f9972557b 100644 --- a/src/test/ui/span/missing-unit-argument.stderr +++ b/src/test/ui/span/missing-unit-argument.stderr @@ -1,11 +1,11 @@ error[E0061]: this function takes 1 parameter but 0 parameters were supplied --> $DIR/missing-unit-argument.rs:21:33 | -21 | let _: Result<(), String> = Ok(); +21 | let _: Result<(), String> = Ok(); //~ ERROR this function takes | ^^^^ help: expected the unit value `()`; create it with empty parentheses | -21 | let _: Result<(), String> = Ok(()); +21 | let _: Result<(), String> = Ok(()); //~ ERROR this function takes | ^^ error[E0061]: this function takes 2 parameters but 0 parameters were supplied @@ -14,7 +14,7 @@ error[E0061]: this function takes 2 parameters but 0 parameters were supplied 11 | fn foo(():(), ():()) {} | ----------------------- defined here ... -22 | foo(); +22 | foo(); //~ ERROR this function takes | ^^^^^ expected 2 parameters error[E0061]: this function takes 2 parameters but 1 parameter was supplied @@ -23,7 +23,7 @@ error[E0061]: this function takes 2 parameters but 1 parameter was supplied 11 | fn foo(():(), ():()) {} | ----------------------- defined here ... -23 | foo(()); +23 | foo(()); //~ ERROR this function takes | ^^ expected 2 parameters error[E0061]: this function takes 1 parameter but 0 parameters were supplied @@ -32,11 +32,11 @@ error[E0061]: this function takes 1 parameter but 0 parameters were supplied 12 | fn bar(():()) {} | ---------------- defined here ... -24 | bar(); +24 | bar(); //~ ERROR this function takes | ^^^^^ help: expected the unit value `()`; create it with empty parentheses | -24 | bar(()); +24 | bar(()); //~ ERROR this function takes | ^^ error[E0061]: this function takes 1 parameter but 0 parameters were supplied @@ -45,11 +45,11 @@ error[E0061]: this function takes 1 parameter but 0 parameters were supplied 16 | fn baz(self, (): ()) { } | ------------------------ defined here ... -25 | S.baz(); +25 | S.baz(); //~ ERROR this function takes | ^^^ help: expected the unit value `()`; create it with empty parentheses | -25 | S.baz(()); +25 | S.baz(()); //~ ERROR this function takes | ^^ error[E0061]: this function takes 1 parameter but 0 parameters were supplied @@ -58,11 +58,11 @@ error[E0061]: this function takes 1 parameter but 0 parameters were supplied 17 | fn generic<T>(self, _: T) { } | ----------------------------- defined here ... -26 | S.generic::<()>(); +26 | S.generic::<()>(); //~ ERROR this function takes | ^^^^^^^ help: expected the unit value `()`; create it with empty parentheses | -26 | S.generic::<()>(()); +26 | S.generic::<()>(()); //~ ERROR this function takes | ^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/span/move-closure.rs b/src/test/ui/span/move-closure.rs index e11ef0dddaa..87ce1529297 100644 --- a/src/test/ui/span/move-closure.rs +++ b/src/test/ui/span/move-closure.rs @@ -12,5 +12,5 @@ // Make sure that the span of a closure marked `move` begins at the `move` keyword. fn main() { - let x: () = move || (); + let x: () = move || (); //~ ERROR mismatched types } diff --git a/src/test/ui/span/move-closure.stderr b/src/test/ui/span/move-closure.stderr index 2294e6476d6..9135a26bbaf 100644 --- a/src/test/ui/span/move-closure.stderr +++ b/src/test/ui/span/move-closure.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/move-closure.rs:15:17 | -15 | let x: () = move || (); +15 | let x: () = move || (); //~ ERROR mismatched types | ^^^^^^^^^^ expected (), found closure | = note: expected type `()` diff --git a/src/test/ui/span/multiline-span-E0072.rs b/src/test/ui/span/multiline-span-E0072.rs index 323e7fb5a42..2344d72f45c 100644 --- a/src/test/ui/span/multiline-span-E0072.rs +++ b/src/test/ui/span/multiline-span-E0072.rs @@ -9,7 +9,7 @@ // except according to those terms. // It should just use the entire body instead of pointing at the next two lines -struct +struct //~ ERROR has infinite size ListNode { head: u8, diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr index a06cbd04deb..124a53219a9 100644 --- a/src/test/ui/span/multiline-span-E0072.stderr +++ b/src/test/ui/span/multiline-span-E0072.stderr @@ -1,7 +1,7 @@ error[E0072]: recursive type `ListNode` has infinite size --> $DIR/multiline-span-E0072.rs:12:1 | -12 | / struct +12 | / struct //~ ERROR has infinite size 13 | | ListNode 14 | | { 15 | | head: u8, diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs index 451492ba693..f8e4cbcbf19 100644 --- a/src/test/ui/span/multiline-span-simple.rs +++ b/src/test/ui/span/multiline-span-simple.rs @@ -20,7 +20,7 @@ fn main() { let x = 1; let y = 2; let z = 3; - foo(1 as u32 + + foo(1 as u32 + //~ ERROR not satisfied bar(x, diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index 3915f1b655c..b068798630e 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied --> $DIR/multiline-span-simple.rs:23:18 | -23 | foo(1 as u32 + +23 | foo(1 as u32 + //~ ERROR not satisfied | ^ no implementation for `u32 + ()` | = help: the trait `std::ops::Add<()>` is not implemented for `u32` diff --git a/src/test/ui/span/multispan-import-lint.rs b/src/test/ui/span/multispan-import-lint.rs index 66536b29c02..c3582b0a0c5 100644 --- a/src/test/ui/span/multispan-import-lint.rs +++ b/src/test/ui/span/multispan-import-lint.rs @@ -11,6 +11,7 @@ #![warn(unused)] use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd}; +//~^ WARN unused imports fn main() { let _ = min(1, 2); diff --git a/src/test/ui/span/mut-arg-hint.rs b/src/test/ui/span/mut-arg-hint.rs index 296ee6ca10e..b22cadf3ef2 100644 --- a/src/test/ui/span/mut-arg-hint.rs +++ b/src/test/ui/span/mut-arg-hint.rs @@ -10,19 +10,19 @@ trait B { fn foo(mut a: &String) { - a.push_str("bar"); + a.push_str("bar"); //~ ERROR cannot borrow immutable borrowed content } } pub fn foo<'a>(mut a: &'a String) { - a.push_str("foo"); + a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content } struct A {} impl A { pub fn foo(mut a: &String) { - a.push_str("foo"); + a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content } } diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr index f8584c67390..02c607ddc37 100644 --- a/src/test/ui/span/mut-arg-hint.stderr +++ b/src/test/ui/span/mut-arg-hint.stderr @@ -3,7 +3,7 @@ error[E0596]: cannot borrow immutable borrowed content `*a` as mutable | 12 | fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable -13 | a.push_str("bar"); +13 | a.push_str("bar"); //~ ERROR cannot borrow immutable borrowed content | ^ cannot borrow as mutable error[E0596]: cannot borrow immutable borrowed content `*a` as mutable @@ -11,7 +11,7 @@ error[E0596]: cannot borrow immutable borrowed content `*a` as mutable | 17 | pub fn foo<'a>(mut a: &'a String) { | ---------- use `&'a mut String` here to make mutable -18 | a.push_str("foo"); +18 | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content | ^ cannot borrow as mutable error[E0596]: cannot borrow immutable borrowed content `*a` as mutable @@ -19,7 +19,7 @@ error[E0596]: cannot borrow immutable borrowed content `*a` as mutable | 24 | pub fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable -25 | a.push_str("foo"); +25 | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content | ^ cannot borrow as mutable error: aborting due to 3 previous errors diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.rs b/src/test/ui/span/mut-ptr-cant-outlive-ref.rs index 8e968d90a2f..135b577d7f7 100644 --- a/src/test/ui/span/mut-ptr-cant-outlive-ref.rs +++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.rs @@ -15,6 +15,6 @@ fn main() { let p; { let b = m.borrow(); - p = &*b; //~ ERROR `b` does not live long enough - } + p = &*b; + } //~ ERROR `b` does not live long enough } diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr index 007a9fad830..d9f5736061a 100644 --- a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr +++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr @@ -1,9 +1,9 @@ error[E0597]: `b` does not live long enough --> $DIR/mut-ptr-cant-outlive-ref.rs:19:5 | -18 | p = &*b; //~ ERROR `b` does not live long enough +18 | p = &*b; | - borrow occurs here -19 | } +19 | } //~ ERROR `b` does not live long enough | ^ `b` dropped here while still borrowed 20 | } | - borrowed value needs to live until here diff --git a/src/test/ui/span/non-existing-module-import.rs b/src/test/ui/span/non-existing-module-import.rs index 3d45a94d531..ad6409f014a 100644 --- a/src/test/ui/span/non-existing-module-import.rs +++ b/src/test/ui/span/non-existing-module-import.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::bar::{foo1, foo2}; +use std::bar::{foo1, foo2}; //~ ERROR unresolved import fn main() {} diff --git a/src/test/ui/span/non-existing-module-import.stderr b/src/test/ui/span/non-existing-module-import.stderr index 93339576f49..74f5dac4937 100644 --- a/src/test/ui/span/non-existing-module-import.stderr +++ b/src/test/ui/span/non-existing-module-import.stderr @@ -1,7 +1,7 @@ error[E0432]: unresolved import `std::bar` --> $DIR/non-existing-module-import.rs:11:10 | -11 | use std::bar::{foo1, foo2}; +11 | use std::bar::{foo1, foo2}; //~ ERROR unresolved import | ^^^ Could not find `bar` in `std` error: aborting due to previous error diff --git a/src/test/ui/span/pub-struct-field.rs b/src/test/ui/span/pub-struct-field.rs index 54cb0b59c75..11af361e8a8 100644 --- a/src/test/ui/span/pub-struct-field.rs +++ b/src/test/ui/span/pub-struct-field.rs @@ -13,8 +13,8 @@ struct Foo { bar: u8, - pub bar: u8, - pub(crate) bar: u8, + pub bar: u8, //~ ERROR is already declared + pub(crate) bar: u8, //~ ERROR is already declared } fn main() {} diff --git a/src/test/ui/span/pub-struct-field.stderr b/src/test/ui/span/pub-struct-field.stderr index c66361c8546..5b303758d2b 100644 --- a/src/test/ui/span/pub-struct-field.stderr +++ b/src/test/ui/span/pub-struct-field.stderr @@ -3,7 +3,7 @@ error[E0124]: field `bar` is already declared | 15 | bar: u8, | ------- `bar` first declared here -16 | pub bar: u8, +16 | pub bar: u8, //~ ERROR is already declared | ^^^^^^^^^^^ field already declared error[E0124]: field `bar` is already declared @@ -11,8 +11,8 @@ error[E0124]: field `bar` is already declared | 15 | bar: u8, | ------- `bar` first declared here -16 | pub bar: u8, -17 | pub(crate) bar: u8, +16 | pub bar: u8, //~ ERROR is already declared +17 | pub(crate) bar: u8, //~ ERROR is already declared | ^^^^^^^^^^^^^^^^^^ field already declared error: aborting due to 2 previous errors diff --git a/src/test/ui/span/range-2.rs b/src/test/ui/span/range-2.rs index 94967693ecf..589f7182129 100644 --- a/src/test/ui/span/range-2.rs +++ b/src/test/ui/span/range-2.rs @@ -15,7 +15,7 @@ pub fn main() { let a = 42; let b = 42; &a..&b - //~^ ERROR `a` does not live long enough - //~^^ ERROR `b` does not live long enough }; + //~^ ERROR `a` does not live long enough + //~^^ ERROR `b` does not live long enough } diff --git a/src/test/ui/span/range-2.stderr b/src/test/ui/span/range-2.stderr index 285ab4aee4b..80d364cd8be 100644 --- a/src/test/ui/span/range-2.stderr +++ b/src/test/ui/span/range-2.stderr @@ -1,22 +1,22 @@ error[E0597]: `a` does not live long enough - --> $DIR/range-2.rs:20:5 + --> $DIR/range-2.rs:18:5 | 17 | &a..&b | - borrow occurs here -... -20 | }; +18 | }; | ^ `a` dropped here while still borrowed +... 21 | } | - borrowed value needs to live until here error[E0597]: `b` does not live long enough - --> $DIR/range-2.rs:20:5 + --> $DIR/range-2.rs:18:5 | 17 | &a..&b | - borrow occurs here -... -20 | }; +18 | }; | ^ `b` dropped here while still borrowed +... 21 | } | - borrowed value needs to live until here diff --git a/src/test/ui/span/recursive-type-field.rs b/src/test/ui/span/recursive-type-field.rs index 6fef4d30f7a..764b5392578 100644 --- a/src/test/ui/span/recursive-type-field.rs +++ b/src/test/ui/span/recursive-type-field.rs @@ -10,12 +10,12 @@ use std::rc::Rc; -struct Foo<'a> { +struct Foo<'a> { //~ ERROR recursive type bar: Bar<'a>, b: Rc<Bar<'a>>, } -struct Bar<'a> { +struct Bar<'a> { //~ ERROR recursive type y: (Foo<'a>, Foo<'a>), z: Option<Bar<'a>>, a: &'a Foo<'a>, diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr index b4d0b5a6a25..bd9f5f032ef 100644 --- a/src/test/ui/span/recursive-type-field.stderr +++ b/src/test/ui/span/recursive-type-field.stderr @@ -1,7 +1,7 @@ error[E0072]: recursive type `Foo` has infinite size --> $DIR/recursive-type-field.rs:13:1 | -13 | struct Foo<'a> { +13 | struct Foo<'a> { //~ ERROR recursive type | ^^^^^^^^^^^^^^ recursive type has infinite size 14 | bar: Bar<'a>, | ------------ recursive without indirection @@ -11,7 +11,7 @@ error[E0072]: recursive type `Foo` has infinite size error[E0072]: recursive type `Bar` has infinite size --> $DIR/recursive-type-field.rs:18:1 | -18 | struct Bar<'a> { +18 | struct Bar<'a> { //~ ERROR recursive type | ^^^^^^^^^^^^^^ recursive type has infinite size 19 | y: (Foo<'a>, Foo<'a>), | --------------------- recursive without indirection diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs b/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs index 8ec6036762f..74a6a2960c9 100644 --- a/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs +++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs @@ -14,7 +14,7 @@ fn main() { let mut f; { let c = 1; - let c_ref = &c; //~ ERROR `c` does not live long enough + let c_ref = &c; f = move |a: isize, b: isize| { a + b + *c_ref }; - } + } //~ ERROR `c` does not live long enough } diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr index 29848412e4e..acd995c6bb8 100644 --- a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr +++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr @@ -1,10 +1,10 @@ error[E0597]: `c` does not live long enough --> $DIR/regionck-unboxed-closure-lifetimes.rs:19:5 | -17 | let c_ref = &c; //~ ERROR `c` does not live long enough +17 | let c_ref = &c; | - borrow occurs here 18 | f = move |a: isize, b: isize| { a + b + *c_ref }; -19 | } +19 | } //~ ERROR `c` does not live long enough | ^ `c` dropped here while still borrowed 20 | } | - borrowed value needs to live until here diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs index 99b0d6ed296..5449bbfdce3 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs @@ -21,5 +21,5 @@ fn main() { { let ss: &isize = &id(1); blah = box ss as Box<Foo>; - } + } //~ ERROR does not live long enough } diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr index 6a3625441b4..69bdde88916 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr @@ -4,7 +4,7 @@ error[E0597]: borrowed value does not live long enough 22 | let ss: &isize = &id(1); | ----- temporary value created here 23 | blah = box ss as Box<Foo>; -24 | } +24 | } //~ ERROR does not live long enough | ^ temporary value dropped here while still borrowed 25 | } | - temporary value needs to live until here diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.rs b/src/test/ui/span/regions-close-over-type-parameter-2.rs index 053af49e068..cd838db92e1 100644 --- a/src/test/ui/span/regions-close-over-type-parameter-2.rs +++ b/src/test/ui/span/regions-close-over-type-parameter-2.rs @@ -30,7 +30,7 @@ fn main() { let _ = { let tmp0 = 3; - let tmp1 = &tmp0; //~ ERROR `tmp0` does not live long enough + let tmp1 = &tmp0; repeater3(tmp1) - }; + }; //~ ERROR `tmp0` does not live long enough } diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.stderr b/src/test/ui/span/regions-close-over-type-parameter-2.stderr index a89127b1436..a7f79f8b265 100644 --- a/src/test/ui/span/regions-close-over-type-parameter-2.stderr +++ b/src/test/ui/span/regions-close-over-type-parameter-2.stderr @@ -1,10 +1,10 @@ error[E0597]: `tmp0` does not live long enough --> $DIR/regions-close-over-type-parameter-2.rs:35:5 | -33 | let tmp1 = &tmp0; //~ ERROR `tmp0` does not live long enough +33 | let tmp1 = &tmp0; | ---- borrow occurs here 34 | repeater3(tmp1) -35 | }; +35 | }; //~ ERROR `tmp0` does not live long enough | ^- borrowed value needs to live until here | | | `tmp0` dropped here while still borrowed diff --git a/src/test/ui/span/regions-escape-loop-via-variable.rs b/src/test/ui/span/regions-escape-loop-via-variable.rs index f588655d1af..1dc1ae60715 100644 --- a/src/test/ui/span/regions-escape-loop-via-variable.rs +++ b/src/test/ui/span/regions-escape-loop-via-variable.rs @@ -18,6 +18,6 @@ fn main() { loop { let x = 1 + *p; - p = &x; //~ ERROR `x` does not live long enough - } + p = &x; + } //~ ERROR `x` does not live long enough } diff --git a/src/test/ui/span/regions-escape-loop-via-variable.stderr b/src/test/ui/span/regions-escape-loop-via-variable.stderr index cfdd1c8b153..554ffe91e6d 100644 --- a/src/test/ui/span/regions-escape-loop-via-variable.stderr +++ b/src/test/ui/span/regions-escape-loop-via-variable.stderr @@ -1,9 +1,9 @@ error[E0597]: `x` does not live long enough --> $DIR/regions-escape-loop-via-variable.rs:22:5 | -21 | p = &x; //~ ERROR `x` does not live long enough +21 | p = &x; | - borrow occurs here -22 | } +22 | } //~ ERROR `x` does not live long enough | ^ `x` dropped here while still borrowed 23 | } | - borrowed value needs to live until here diff --git a/src/test/ui/span/regions-escape-loop-via-vec.rs b/src/test/ui/span/regions-escape-loop-via-vec.rs index 8982b5cd98d..7c4834751d8 100644 --- a/src/test/ui/span/regions-escape-loop-via-vec.rs +++ b/src/test/ui/span/regions-escape-loop-via-vec.rs @@ -19,12 +19,11 @@ fn broken() { //~^ NOTE use of borrowed `x` let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed //~^ NOTE use of borrowed `x` - _y.push(&mut z); //~ ERROR `z` does not live long enough - //~^ NOTE does not live long enough + _y.push(&mut z); //~ NOTE borrow occurs here x += 1; //~ ERROR cannot assign //~^ NOTE assignment to borrowed `x` occurs here - } - //~^ NOTE borrowed value only lives until here + } //~ NOTE `z` dropped here while still borrowed + //~^ ERROR `z` does not live long enough } //~^ NOTE borrowed value needs to live until here diff --git a/src/test/ui/span/regions-escape-loop-via-vec.stderr b/src/test/ui/span/regions-escape-loop-via-vec.stderr index b61df82e8a1..a7224fcd4cc 100644 --- a/src/test/ui/span/regions-escape-loop-via-vec.stderr +++ b/src/test/ui/span/regions-escape-loop-via-vec.stderr @@ -1,13 +1,13 @@ error[E0597]: `z` does not live long enough - --> $DIR/regions-escape-loop-via-vec.rs:26:5 + --> $DIR/regions-escape-loop-via-vec.rs:25:5 | -22 | _y.push(&mut z); //~ ERROR `z` does not live long enough +22 | _y.push(&mut z); //~ NOTE borrow occurs here | - borrow occurs here ... -26 | } +25 | } //~ NOTE `z` dropped here while still borrowed | ^ `z` dropped here while still borrowed -27 | //~^ NOTE borrowed value only lives until here -28 | } +26 | //~^ ERROR `z` does not live long enough +27 | } | - borrowed value needs to live until here error[E0503]: cannot use `x` because it was mutably borrowed @@ -29,12 +29,12 @@ error[E0503]: cannot use `x` because it was mutably borrowed | ^^^^^ use of borrowed `x` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/regions-escape-loop-via-vec.rs:24:9 + --> $DIR/regions-escape-loop-via-vec.rs:23:9 | 14 | let mut _y = vec![&mut x]; | - borrow of `x` occurs here ... -24 | x += 1; //~ ERROR cannot assign +23 | x += 1; //~ ERROR cannot assign | ^^^^^^ assignment to borrowed `x` occurs here error: aborting due to 4 previous errors diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs b/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs index a05658e9e58..3bb069813a2 100644 --- a/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs +++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs @@ -21,11 +21,11 @@ fn foo<C, M>(mut cond: C, mut make_box: M) where // Here we complain because the resulting region // of this borrow is the fn body as a whole. - y = borrow(&*x); //~ ERROR `*x` does not live long enough + y = borrow(&*x); assert_eq!(*x, *y); if cond() { break; } - } + } //~ ERROR `*x` does not live long enough assert!(*y != 0); } diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr index 0960f5e1b25..4a44a3a6813 100644 --- a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr +++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr @@ -1,10 +1,10 @@ error[E0597]: `*x` does not live long enough --> $DIR/regions-infer-borrow-scope-within-loop.rs:28:5 | -24 | y = borrow(&*x); //~ ERROR `*x` does not live long enough +24 | y = borrow(&*x); | -- borrow occurs here ... -28 | } +28 | } //~ ERROR `*x` does not live long enough | ^ `*x` dropped here while still borrowed 29 | assert!(*y != 0); 30 | } diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.rs b/src/test/ui/span/send-is-not-static-ensures-scoping.rs index 1b7718d2283..d294840bdfb 100644 --- a/src/test/ui/span/send-is-not-static-ensures-scoping.rs +++ b/src/test/ui/span/send-is-not-static-ensures-scoping.rs @@ -23,13 +23,13 @@ impl<'a> Guard<'a> { fn main() { let bad = { let x = 1; - let y = &x; //~ ERROR `x` does not live long enough + let y = &x; scoped(|| { let _z = y; //~^ ERROR `y` does not live long enough }) - }; + }; //~ ERROR `x` does not live long enough bad.join(); } diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr index 02fc9820495..cc12b2c1ee2 100644 --- a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr +++ b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr @@ -1,10 +1,10 @@ error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-ensures-scoping.rs:32:5 | -26 | let y = &x; //~ ERROR `x` does not live long enough +26 | let y = &x; | - borrow occurs here ... -32 | }; +32 | }; //~ ERROR `x` does not live long enough | ^ `x` dropped here while still borrowed ... 35 | } @@ -18,7 +18,7 @@ error[E0597]: `y` does not live long enough 29 | let _z = y; | ^ does not live long enough ... -32 | }; +32 | }; //~ ERROR `x` does not live long enough | - borrowed value only lives until here ... 35 | } diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.rs b/src/test/ui/span/send-is-not-static-std-sync-2.rs index d9d3706586b..762eeffaa6a 100644 --- a/src/test/ui/span/send-is-not-static-std-sync-2.rs +++ b/src/test/ui/span/send-is-not-static-std-sync-2.rs @@ -18,8 +18,8 @@ use std::sync::{Mutex, RwLock, mpsc}; fn mutex() { let lock = { let x = 1; - Mutex::new(&x) //~ ERROR does not live long enough - }; + Mutex::new(&x) + }; //~ ERROR does not live long enough let _dangling = *lock.lock().unwrap(); } @@ -27,8 +27,8 @@ fn mutex() { fn rwlock() { let lock = { let x = 1; - RwLock::new(&x) //~ ERROR does not live long enough - }; + RwLock::new(&x) + }; //~ ERROR does not live long enough let _dangling = *lock.read().unwrap(); } @@ -36,9 +36,9 @@ fn channel() { let (_tx, rx) = { let x = 1; let (tx, rx) = mpsc::channel(); - let _ = tx.send(&x); //~ ERROR does not live long enough + let _ = tx.send(&x); (tx, rx) - }; + }; //~ ERROR does not live long enough let _dangling = rx.recv(); } diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.stderr index 318dab599f5..beee85c8b1d 100644 --- a/src/test/ui/span/send-is-not-static-std-sync-2.stderr +++ b/src/test/ui/span/send-is-not-static-std-sync-2.stderr @@ -1,9 +1,9 @@ error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:22:5 | -21 | Mutex::new(&x) //~ ERROR does not live long enough +21 | Mutex::new(&x) | - borrow occurs here -22 | }; +22 | }; //~ ERROR does not live long enough | ^ `x` dropped here while still borrowed ... 25 | } @@ -12,9 +12,9 @@ error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:31:5 | -30 | RwLock::new(&x) //~ ERROR does not live long enough +30 | RwLock::new(&x) | - borrow occurs here -31 | }; +31 | }; //~ ERROR does not live long enough | ^ `x` dropped here while still borrowed 32 | let _dangling = *lock.read().unwrap(); 33 | } @@ -23,10 +23,10 @@ error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:41:5 | -39 | let _ = tx.send(&x); //~ ERROR does not live long enough +39 | let _ = tx.send(&x); | - borrow occurs here 40 | (tx, rx) -41 | }; +41 | }; //~ ERROR does not live long enough | ^ `x` dropped here while still borrowed ... 44 | } diff --git a/src/test/ui/span/send-is-not-static-std-sync.rs b/src/test/ui/span/send-is-not-static-std-sync.rs index 8ec2fe8a1ec..05cb9627558 100644 --- a/src/test/ui/span/send-is-not-static-std-sync.rs +++ b/src/test/ui/span/send-is-not-static-std-sync.rs @@ -23,8 +23,8 @@ fn mutex() { drop(y); //~ ERROR cannot move out { let z = 2; - *lock.lock().unwrap() = &z; //~ ERROR does not live long enough - } + *lock.lock().unwrap() = &z; + } //~ ERROR does not live long enough } fn rwlock() { @@ -35,8 +35,8 @@ fn rwlock() { drop(y); //~ ERROR cannot move out { let z = 2; - *lock.write().unwrap() = &z; //~ ERROR does not live long enough - } + *lock.write().unwrap() = &z; + } //~ ERROR does not live long enough } fn channel() { @@ -49,8 +49,8 @@ fn channel() { drop(y); //~ ERROR cannot move out { let z = 2; - tx.send(&z).unwrap(); //~ ERROR does not live long enough - } + tx.send(&z).unwrap(); + } //~ ERROR does not live long enough } fn main() {} diff --git a/src/test/ui/span/send-is-not-static-std-sync.stderr b/src/test/ui/span/send-is-not-static-std-sync.stderr index 988ff228105..e078e4e14a5 100644 --- a/src/test/ui/span/send-is-not-static-std-sync.stderr +++ b/src/test/ui/span/send-is-not-static-std-sync.stderr @@ -1,9 +1,9 @@ error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:27:5 | -26 | *lock.lock().unwrap() = &z; //~ ERROR does not live long enough +26 | *lock.lock().unwrap() = &z; | - borrow occurs here -27 | } +27 | } //~ ERROR does not live long enough | ^ `z` dropped here while still borrowed 28 | } | - borrowed value needs to live until here @@ -19,9 +19,9 @@ error[E0505]: cannot move out of `y` because it is borrowed error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:39:5 | -38 | *lock.write().unwrap() = &z; //~ ERROR does not live long enough +38 | *lock.write().unwrap() = &z; | - borrow occurs here -39 | } +39 | } //~ ERROR does not live long enough | ^ `z` dropped here while still borrowed 40 | } | - borrowed value needs to live until here @@ -37,9 +37,9 @@ error[E0505]: cannot move out of `y` because it is borrowed error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:53:5 | -52 | tx.send(&z).unwrap(); //~ ERROR does not live long enough +52 | tx.send(&z).unwrap(); | - borrow occurs here -53 | } +53 | } //~ ERROR does not live long enough | ^ `z` dropped here while still borrowed 54 | } | - borrowed value needs to live until here diff --git a/src/test/ui/span/slice-borrow.rs b/src/test/ui/span/slice-borrow.rs index 1b022f23246..6bb98c34b7e 100644 --- a/src/test/ui/span/slice-borrow.rs +++ b/src/test/ui/span/slice-borrow.rs @@ -15,5 +15,5 @@ fn main() { { let x: &[isize] = &vec![1, 2, 3, 4, 5]; y = &x[1..]; - } + } //~ ERROR does not live long enough } diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index 5e8edf80df6..d1e5cf62a02 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -4,12 +4,12 @@ error[E0597]: borrowed value does not live long enough 16 | let x: &[isize] = &vec![1, 2, 3, 4, 5]; | ------------------- temporary value created here 17 | y = &x[1..]; -18 | } +18 | } //~ ERROR does not live long enough | ^ temporary value dropped here while still borrowed 19 | } | - temporary value needs to live until here | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/span/suggestion-non-ascii.rs b/src/test/ui/span/suggestion-non-ascii.rs index 67dbe1dc7b5..2d82bba33c5 100644 --- a/src/test/ui/span/suggestion-non-ascii.rs +++ b/src/test/ui/span/suggestion-non-ascii.rs @@ -11,6 +11,6 @@ fn main() { let tup = (1,); - println!("☃{}", tup[0]); + println!("☃{}", tup[0]); //~ ERROR cannot index into a value of type } diff --git a/src/test/ui/span/suggestion-non-ascii.stderr b/src/test/ui/span/suggestion-non-ascii.stderr index c67a8fe32b9..9ee8ccb01d0 100644 --- a/src/test/ui/span/suggestion-non-ascii.stderr +++ b/src/test/ui/span/suggestion-non-ascii.stderr @@ -1,7 +1,7 @@ error[E0608]: cannot index into a value of type `({integer},)` --> $DIR/suggestion-non-ascii.rs:14:21 | -14 | println!("☃{}", tup[0]); +14 | println!("☃{}", tup[0]); //~ ERROR cannot index into a value of type | ^^^^^^ help: to access tuple elements, use: `tup.0` error: aborting due to previous error diff --git a/src/test/ui/span/type-binding.rs b/src/test/ui/span/type-binding.rs index 05285c732f4..d8a2e332a03 100644 --- a/src/test/ui/span/type-binding.rs +++ b/src/test/ui/span/type-binding.rs @@ -14,5 +14,6 @@ use std::ops::Deref; fn homura<T: Deref<Trget = i32>>(_: T) {} +//~^ ERROR not found fn main() {} diff --git a/src/test/ui/span/typo-suggestion.rs b/src/test/ui/span/typo-suggestion.rs index 536bf16142b..7aeaa44bec2 100644 --- a/src/test/ui/span/typo-suggestion.rs +++ b/src/test/ui/span/typo-suggestion.rs @@ -12,8 +12,8 @@ fn main() { let foo = 1; // `foo` shouldn't be suggested, it is too dissimilar from `bar`. - println!("Hello {}", bar); + println!("Hello {}", bar); //~ ERROR cannot find value // But this is close enough. - println!("Hello {}", fob); + println!("Hello {}", fob); //~ ERROR cannot find value } diff --git a/src/test/ui/span/typo-suggestion.stderr b/src/test/ui/span/typo-suggestion.stderr index dca0a93f897..2a084b1ae67 100644 --- a/src/test/ui/span/typo-suggestion.stderr +++ b/src/test/ui/span/typo-suggestion.stderr @@ -1,13 +1,13 @@ error[E0425]: cannot find value `bar` in this scope --> $DIR/typo-suggestion.rs:15:26 | -15 | println!("Hello {}", bar); +15 | println!("Hello {}", bar); //~ ERROR cannot find value | ^^^ not found in this scope error[E0425]: cannot find value `fob` in this scope --> $DIR/typo-suggestion.rs:18:26 | -18 | println!("Hello {}", fob); +18 | println!("Hello {}", fob); //~ ERROR cannot find value | ^^^ did you mean `foo`? error: aborting due to 2 previous errors diff --git a/src/test/ui/span/unused-warning-point-at-signature.rs b/src/test/ui/span/unused-warning-point-at-signature.rs index eb659d08da0..6a7071d49ae 100644 --- a/src/test/ui/span/unused-warning-point-at-signature.rs +++ b/src/test/ui/span/unused-warning-point-at-signature.rs @@ -12,25 +12,25 @@ #![warn(unused)] -enum Enum { +enum Enum { //~ WARN enum is never used A, B, C, D, } -struct Struct { +struct Struct { //~ WARN struct is never used a: usize, b: usize, c: usize, d: usize, } -fn func() -> usize { +fn func() -> usize { //~ WARN function is never used 3 } -fn +fn //~ WARN function is never used func_complete_span() -> usize { diff --git a/src/test/ui/span/unused-warning-point-at-signature.stderr b/src/test/ui/span/unused-warning-point-at-signature.stderr index 8e658670e9c..ed36bd17801 100644 --- a/src/test/ui/span/unused-warning-point-at-signature.stderr +++ b/src/test/ui/span/unused-warning-point-at-signature.stderr @@ -1,7 +1,7 @@ warning: enum is never used: `Enum` --> $DIR/unused-warning-point-at-signature.rs:15:1 | -15 | enum Enum { +15 | enum Enum { //~ WARN enum is never used | ^^^^^^^^^ | note: lint level defined here @@ -14,19 +14,19 @@ note: lint level defined here warning: struct is never used: `Struct` --> $DIR/unused-warning-point-at-signature.rs:22:1 | -22 | struct Struct { +22 | struct Struct { //~ WARN struct is never used | ^^^^^^^^^^^^^ warning: function is never used: `func` --> $DIR/unused-warning-point-at-signature.rs:29:1 | -29 | fn func() -> usize { +29 | fn func() -> usize { //~ WARN function is never used | ^^^^^^^^^^^^^^^^^^ warning: function is never used: `func_complete_span` --> $DIR/unused-warning-point-at-signature.rs:33:1 | -33 | / fn +33 | / fn //~ WARN function is never used 34 | | func_complete_span() 35 | | -> usize 36 | | { diff --git a/src/test/ui/span/visibility-ty-params.rs b/src/test/ui/span/visibility-ty-params.rs index 2a4a5edd04c..5df28971e99 100644 --- a/src/test/ui/span/visibility-ty-params.rs +++ b/src/test/ui/span/visibility-ty-params.rs @@ -14,7 +14,6 @@ macro_rules! m { struct S<T>(T); m!{ S<u8> } //~ ERROR unexpected generic arguments in path -//~^ ERROR expected module, found struct `S` mod m { m!{ m<> } //~ ERROR unexpected generic arguments in path diff --git a/src/test/ui/span/visibility-ty-params.stderr b/src/test/ui/span/visibility-ty-params.stderr index 673b9a38e03..8460f81af83 100644 --- a/src/test/ui/span/visibility-ty-params.stderr +++ b/src/test/ui/span/visibility-ty-params.stderr @@ -5,9 +5,9 @@ error: unexpected generic arguments in path | ^^^^^ error: unexpected generic arguments in path - --> $DIR/visibility-ty-params.rs:20:9 + --> $DIR/visibility-ty-params.rs:19:9 | -20 | m!{ m<> } //~ ERROR unexpected generic arguments in path +19 | m!{ m<> } //~ ERROR unexpected generic arguments in path | ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/span/wf-method-late-bound-regions.rs b/src/test/ui/span/wf-method-late-bound-regions.rs index b9d292fd156..ce5ec63fbd1 100644 --- a/src/test/ui/span/wf-method-late-bound-regions.rs +++ b/src/test/ui/span/wf-method-late-bound-regions.rs @@ -27,7 +27,7 @@ fn main() { let f2 = f; let dangling = { let pointer = Box::new(42); - f2.xmute(&pointer) //~ ERROR `pointer` does not live long enough - }; + f2.xmute(&pointer) + }; //~ ERROR `pointer` does not live long enough println!("{}", dangling); } diff --git a/src/test/ui/span/wf-method-late-bound-regions.stderr b/src/test/ui/span/wf-method-late-bound-regions.stderr index a37b5d17aac..a3fdc53b8e5 100644 --- a/src/test/ui/span/wf-method-late-bound-regions.stderr +++ b/src/test/ui/span/wf-method-late-bound-regions.stderr @@ -1,9 +1,9 @@ error[E0597]: `pointer` does not live long enough --> $DIR/wf-method-late-bound-regions.rs:31:5 | -30 | f2.xmute(&pointer) //~ ERROR `pointer` does not live long enough +30 | f2.xmute(&pointer) | ------- borrow occurs here -31 | }; +31 | }; //~ ERROR `pointer` does not live long enough | ^ `pointer` dropped here while still borrowed 32 | println!("{}", dangling); 33 | } diff --git a/src/test/ui/static-lifetime.rs b/src/test/ui/static-lifetime.rs index 7b1887b2d1a..62abf11654e 100644 --- a/src/test/ui/static-lifetime.rs +++ b/src/test/ui/static-lifetime.rs @@ -10,7 +10,7 @@ pub trait Arbitrary: Sized + 'static {} -impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} +impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound fn main() { -} \ No newline at end of file +} diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr index adeabd91302..a99dbf21e54 100644 --- a/src/test/ui/static-lifetime.stderr +++ b/src/test/ui/static-lifetime.stderr @@ -1,13 +1,13 @@ error[E0478]: lifetime bound not satisfied --> $DIR/static-lifetime.rs:13:20 | -13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} +13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound | ^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 13:1 --> $DIR/static-lifetime.rs:13:1 | -13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} +13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but lifetime parameter must outlive the static lifetime diff --git a/src/test/ui/str-lit-type-mismatch.rs b/src/test/ui/str-lit-type-mismatch.rs index 0fd7d3a9d86..4a062f78a32 100644 --- a/src/test/ui/str-lit-type-mismatch.rs +++ b/src/test/ui/str-lit-type-mismatch.rs @@ -10,7 +10,7 @@ fn main() { - let x: &[u8] = "foo"; - let y: &[u8; 4] = "baaa"; - let z: &str = b"foo"; + let x: &[u8] = "foo"; //~ ERROR mismatched types + let y: &[u8; 4] = "baaa"; //~ ERROR mismatched types + let z: &str = b"foo"; //~ ERROR mismatched types } diff --git a/src/test/ui/str-lit-type-mismatch.stderr b/src/test/ui/str-lit-type-mismatch.stderr index 47418522df8..bf7646d81eb 100644 --- a/src/test/ui/str-lit-type-mismatch.stderr +++ b/src/test/ui/str-lit-type-mismatch.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:13:20 | -13 | let x: &[u8] = "foo"; +13 | let x: &[u8] = "foo"; //~ ERROR mismatched types | ^^^^^ expected slice, found str | = note: expected type `&[u8]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:14:23 | -14 | let y: &[u8; 4] = "baaa"; +14 | let y: &[u8; 4] = "baaa"; //~ ERROR mismatched types | ^^^^^^ expected array of 4 elements, found str | = note: expected type `&[u8; 4]` @@ -21,7 +21,7 @@ error[E0308]: mismatched types error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:15:19 | -15 | let z: &str = b"foo"; +15 | let z: &str = b"foo"; //~ ERROR mismatched types | ^^^^^^ expected str, found array of 3 elements | = note: expected type `&str` diff --git a/src/test/ui/struct-field-init-syntax.rs b/src/test/ui/struct-field-init-syntax.rs index 8ea62fef9fa..f1e24495f84 100644 --- a/src/test/ui/struct-field-init-syntax.rs +++ b/src/test/ui/struct-field-init-syntax.rs @@ -16,12 +16,12 @@ fn main() { let foo = Foo { one: 111, ..Foo::default(), - //~^ ERROR cannot use a comma after struct expansion + //~^ ERROR cannot use a comma after the base struct }; let foo = Foo { ..Foo::default(), - //~^ ERROR cannot use a comma after struct expansion + //~^ ERROR cannot use a comma after the base struct one: 111, }; } diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.rs b/src/test/ui/suggestions/closure-immutable-outer-variable.rs index fe8e2bc6c8e..1d14afd6a01 100644 --- a/src/test/ui/suggestions/closure-immutable-outer-variable.rs +++ b/src/test/ui/suggestions/closure-immutable-outer-variable.rs @@ -16,5 +16,5 @@ fn foo(mut f: Box<FnMut()>) { fn main() { let y = true; - foo(Box::new(move || y = false) as Box<_>); + foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable } diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr index 19f1cd07171..f272a3582c6 100644 --- a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr +++ b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr @@ -3,7 +3,7 @@ error[E0594]: cannot assign to captured outer variable in an `FnMut` closure | 18 | let y = true; | - help: consider making `y` mutable: `mut y` -19 | foo(Box::new(move || y = false) as Box<_>); +19 | foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs index fc3c58e5223..6e0f9999ec1 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Obj<F> where F: FnMut() -> u32 { +struct Obj<F> where F: FnMut() -> u32 { //~ NOTE not found for this closure: F, } diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr index 0ca61127634..62dceceedf3 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.rs:16:28: 16:33]>` in the current scope --> $DIR/issue-18343.rs:17:7 | +11 | struct Obj<F> where F: FnMut() -> u32 { //~ NOTE not found for this + | ------------------------------------- method `closure` not found for this +... 17 | o.closure(); | ^^^^^^^ field, not a method | diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs index f84f35ce84b..cba0ecbf58e 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs @@ -13,6 +13,9 @@ use std::boxed::FnBox; struct FuncContainer { +//~^ NOTE not found for this +//~| NOTE not found for this +//~| NOTE not found for this f1: fn(data: u8), f2: extern "C" fn(data: u8), f3: unsafe fn(data: u8), @@ -23,11 +26,19 @@ struct FuncContainerOuter { } struct Obj<F> where F: FnOnce() -> u32 { +//~^ NOTE not found for this +//~| NOTE not found for this +//~| NOTE not found for this +//~| NOTE not found for this +//~| NOTE not found for this +//~| NOTE not found for this closure: F, not_closure: usize, } struct BoxedObj { +//~^ NOTE not found for this +//~| NOTE not found for this boxed_closure: Box<FnBox() -> u32>, } diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr index c6f134f118d..b4086b16027 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr @@ -1,87 +1,120 @@ -error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope - --> $DIR/issue-2392.rs:50:15 +error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:60:36: 60:41]>` in the current scope + --> $DIR/issue-2392.rs:61:15 | -50 | o_closure.closure(); //~ ERROR no method named `closure` found +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `closure` not found for this +... +61 | o_closure.closure(); //~ ERROR no method named `closure` found | ^^^^^^^ field, not a method | = help: use `(o_closure.closure)(...)` if you meant to call the function stored in the `closure` field -error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope - --> $DIR/issue-2392.rs:54:15 +error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:60:36: 60:41]>` in the current scope + --> $DIR/issue-2392.rs:65:15 | -54 | o_closure.not_closure(); +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `not_closure` not found for this +... +65 | o_closure.not_closure(); | ^^^^^^^^^^^ field, not a method | = help: did you mean to write `o_closure.not_closure` instead of `o_closure.not_closure(...)`? error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:60:12 + --> $DIR/issue-2392.rs:71:12 | -60 | o_func.closure(); //~ ERROR no method named `closure` found +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `closure` not found for this +... +71 | o_func.closure(); //~ ERROR no method named `closure` found | ^^^^^^^ field, not a method | = help: use `(o_func.closure)(...)` if you meant to call the function stored in the `closure` field error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope - --> $DIR/issue-2392.rs:65:14 + --> $DIR/issue-2392.rs:76:14 | -65 | boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found +39 | struct BoxedObj { + | --------------- method `boxed_closure` not found for this +... +76 | boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found | ^^^^^^^^^^^^^ field, not a method | = help: use `(boxed_fn.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope - --> $DIR/issue-2392.rs:70:19 + --> $DIR/issue-2392.rs:81:19 | -70 | boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found +39 | struct BoxedObj { + | --------------- method `boxed_closure` not found for this +... +81 | boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found | ^^^^^^^^^^^^^ field, not a method | = help: use `(boxed_closure.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:77:12 + --> $DIR/issue-2392.rs:88:12 | -77 | w.wrap.closure();//~ ERROR no method named `closure` found +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `closure` not found for this +... +88 | w.wrap.closure();//~ ERROR no method named `closure` found | ^^^^^^^ field, not a method | = help: use `(w.wrap.closure)(...)` if you meant to call the function stored in the `closure` field error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:81:12 + --> $DIR/issue-2392.rs:92:12 | -81 | w.wrap.not_closure(); +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `not_closure` not found for this +... +92 | w.wrap.not_closure(); | ^^^^^^^^^^^ field, not a method | = 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<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope - --> $DIR/issue-2392.rs:86:24 + --> $DIR/issue-2392.rs:97:24 | -86 | check_expression().closure();//~ ERROR no method named `closure` found +28 | struct Obj<F> where F: FnOnce() -> u32 { + | -------------------------------------- method `closure` not found for this +... +97 | check_expression().closure();//~ ERROR no method named `closure` found | ^^^^^^^ field, not a method | = help: use `(check_expression().closure)(...)` if you meant to call the function stored in the `closure` field error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:94:31 - | -94 | (*self.container).f1(1); //~ ERROR no method named `f1` found - | ^^ field, not a method - | - = help: use `((*self.container).f1)(...)` if you meant to call the function stored in the `f1` field + --> $DIR/issue-2392.rs:105:31 + | +15 | struct FuncContainer { + | -------------------- method `f1` not found for this +... +105 | (*self.container).f1(1); //~ ERROR no method named `f1` found + | ^^ field, not a method + | + = help: use `((*self.container).f1)(...)` if you meant to call the function stored in the `f1` field error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:97:31 - | -97 | (*self.container).f2(1); //~ ERROR no method named `f2` found - | ^^ field, not a method - | - = help: use `((*self.container).f2)(...)` if you meant to call the function stored in the `f2` field + --> $DIR/issue-2392.rs:108:31 + | +15 | struct FuncContainer { + | -------------------- method `f2` not found for this +... +108 | (*self.container).f2(1); //~ ERROR no method named `f2` found + | ^^ field, not a method + | + = help: use `((*self.container).f2)(...)` if you meant to call the function stored in the `f2` field error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:100:31 + --> $DIR/issue-2392.rs:111:31 | -100 | (*self.container).f3(1); //~ ERROR no method named `f3` found +15 | struct FuncContainer { + | -------------------- method `f3` not found for this +... +111 | (*self.container).f3(1); //~ ERROR no method named `f3` found | ^^ field, not a method | = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs index 2fd7dc246c2..32d5c7f5e8a 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Example { +struct Example { //~ NOTE not found for this example: Box<Fn(i32) -> i32> } diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr index a45e70d48c9..813b6060db0 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `example` found for type `Example` in the current scope --> $DIR/issue-32128.rs:22:10 | +11 | struct Example { //~ NOTE not found for this + | -------------- method `example` not found for this +... 22 | demo.example(1); | ^^^^^^^ field, not a method | diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs index 03c84fc57be..87349855221 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs @@ -36,14 +36,14 @@ fn main() { let p = &o; p.closure(); //~ ERROR no method named `closure` found //~^ HELP use `(p.closure)(...)` if you meant to call the function stored in the `closure` field - //~| NOTE `closure` is a field storing a function, not a method + //~| NOTE field, not a method let q = &p; q.fn_ptr(); //~ ERROR no method named `fn_ptr` found //~^ HELP use `(q.fn_ptr)(...)` if you meant to call the function stored in the `fn_ptr` field - //~| NOTE `fn_ptr` is a field storing a function, not a method + //~| NOTE field, not a method let r = D(C { c_fn_ptr: empty }); let s = &r; s.c_fn_ptr(); //~ ERROR no method named `c_fn_ptr` found //~^ HELP use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` - //~| NOTE `c_fn_ptr` is a field storing a function, not a method + //~| NOTE field, not a method } diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.rs b/src/test/ui/suggestions/confuse-field-and-method/private-field.rs index 94cf38fb32f..4cf939bbed6 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/private-field.rs +++ b/src/test/ui/suggestions/confuse-field-and-method/private-field.rs @@ -23,7 +23,7 @@ pub mod animal { fn main() { let dog = animal::Dog::new(3); - let dog_age = dog.dog_age(); + let dog_age = dog.dog_age(); //~ ERROR no method //let dog_age = dog.dog_age; println!("{}", dog_age); } diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr index 94519266260..caf78af6eb9 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr @@ -1,7 +1,10 @@ error[E0599]: no method named `dog_age` found for type `animal::Dog` in the current scope --> $DIR/private-field.rs:26:23 | -26 | let dog_age = dog.dog_age(); +12 | pub struct Dog { + | -------------- method `dog_age` not found for this +... +26 | let dog_age = dog.dog_age(); //~ ERROR no method | ^^^^^^^ private field, not a method error: aborting due to previous error diff --git a/src/test/ui/suggestions/extern-crate-rename.rs b/src/test/ui/suggestions/extern-crate-rename.rs index b3fa5871a82..b58149fb0b8 100644 --- a/src/test/ui/suggestions/extern-crate-rename.rs +++ b/src/test/ui/suggestions/extern-crate-rename.rs @@ -13,6 +13,6 @@ extern crate m1; -extern crate m2 as m1; +extern crate m2 as m1; //~ ERROR is defined multiple times fn main() {} diff --git a/src/test/ui/suggestions/extern-crate-rename.stderr b/src/test/ui/suggestions/extern-crate-rename.stderr index c15e238e8b0..6268935b08c 100644 --- a/src/test/ui/suggestions/extern-crate-rename.stderr +++ b/src/test/ui/suggestions/extern-crate-rename.stderr @@ -3,7 +3,7 @@ error[E0259]: the name `m1` is defined multiple times | 15 | extern crate m1; | ---------------- previous import of the extern crate `m1` here -16 | extern crate m2 as m1; +16 | extern crate m2 as m1; //~ ERROR is defined multiple times | ^^^^^^^^^^^^^^^^^^^^^^ | | | `m1` reimported here diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs index 51aba27498f..9d71ab1a788 100644 --- a/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs +++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs @@ -17,6 +17,6 @@ pub mod extension2 { } use extension1::ConstructorExtension; -use extension2::ConstructorExtension; +use extension2::ConstructorExtension; //~ ERROR is defined multiple times fn main() {} diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr index 07985191284..ae892db364b 100644 --- a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr +++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr @@ -3,13 +3,13 @@ error[E0252]: the name `ConstructorExtension` is defined multiple times | 19 | use extension1::ConstructorExtension; | -------------------------------- previous import of the trait `ConstructorExtension` here -20 | use extension2::ConstructorExtension; +20 | use extension2::ConstructorExtension; //~ ERROR is defined multiple times | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ConstructorExtension` reimported here | = note: `ConstructorExtension` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -20 | use extension2::ConstructorExtension as OtherConstructorExtension; +20 | use extension2::ConstructorExtension as OtherConstructorExtension; //~ ERROR is defined multiple times | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-43420-no-over-suggest.rs b/src/test/ui/suggestions/issue-43420-no-over-suggest.rs index d504b7cae28..8c5bde45bae 100644 --- a/src/test/ui/suggestions/issue-43420-no-over-suggest.rs +++ b/src/test/ui/suggestions/issue-43420-no-over-suggest.rs @@ -15,5 +15,5 @@ fn foo(b: &[u16]) {} fn main() { let a: Vec<u8> = Vec::new(); - foo(&a); + foo(&a); //~ ERROR mismatched types } diff --git a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr index bcad9ce56c6..c3f64fef50c 100644 --- a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr +++ b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/issue-43420-no-over-suggest.rs:18:9 | -18 | foo(&a); +18 | foo(&a); //~ ERROR mismatched types | ^^ expected slice, found struct `std::vec::Vec` | = note: expected type `&[u16]` diff --git a/src/test/ui/suggestions/suggest-labels.rs b/src/test/ui/suggestions/suggest-labels.rs index 5bebce79ecc..8c97301f40b 100644 --- a/src/test/ui/suggestions/suggest-labels.rs +++ b/src/test/ui/suggestions/suggest-labels.rs @@ -11,16 +11,16 @@ #[allow(unreachable_code)] fn main() { 'foo: loop { - break 'fo; + break 'fo; //~ ERROR use of undeclared label } 'bar: loop { - continue 'bor; + continue 'bor; //~ ERROR use of undeclared label } 'longlabel: loop { 'longlabel1: loop { - break 'longlable; + break 'longlable; //~ ERROR use of undeclared label } } } diff --git a/src/test/ui/suggestions/suggest-labels.stderr b/src/test/ui/suggestions/suggest-labels.stderr index 23aa18a3655..c82b5decfd8 100644 --- a/src/test/ui/suggestions/suggest-labels.stderr +++ b/src/test/ui/suggestions/suggest-labels.stderr @@ -1,19 +1,19 @@ error[E0426]: use of undeclared label `'fo` --> $DIR/suggest-labels.rs:14:15 | -14 | break 'fo; +14 | break 'fo; //~ ERROR use of undeclared label | ^^^ did you mean `'foo`? error[E0426]: use of undeclared label `'bor` --> $DIR/suggest-labels.rs:18:18 | -18 | continue 'bor; +18 | continue 'bor; //~ ERROR use of undeclared label | ^^^^ did you mean `'bar`? error[E0426]: use of undeclared label `'longlable` --> $DIR/suggest-labels.rs:23:19 | -23 | break 'longlable; +23 | break 'longlable; //~ ERROR use of undeclared label | ^^^^^^^^^^ did you mean `'longlabel1`? error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/suggest-methods.rs b/src/test/ui/suggestions/suggest-methods.rs index b02881dc7ee..49027deecc1 100644 --- a/src/test/ui/suggestions/suggest-methods.rs +++ b/src/test/ui/suggestions/suggest-methods.rs @@ -25,16 +25,16 @@ impl FooT for Foo { fn main() { let f = Foo; - f.bat(1.0); + f.bat(1.0); //~ ERROR no method named let s = "foo".to_string(); - let _ = s.is_emtpy(); + let _ = s.is_emtpy(); //~ ERROR no method named // Generates a warning for `count_zeros()`. `count_ones()` is also a close // match, but the former is closer. - let _ = 63u32.count_eos(); + let _ = 63u32.count_eos(); //~ ERROR no method named // Does not generate a warning - let _ = 63u32.count_o(); + let _ = 63u32.count_o(); //~ ERROR no method named } diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr index 41beb73b1bc..d3d8d302c70 100644 --- a/src/test/ui/suggestions/suggest-methods.stderr +++ b/src/test/ui/suggestions/suggest-methods.stderr @@ -1,7 +1,10 @@ error[E0599]: no method named `bat` found for type `Foo` in the current scope --> $DIR/suggest-methods.rs:28:7 | -28 | f.bat(1.0); +11 | struct Foo; + | ----------- method `bat` not found for this +... +28 | f.bat(1.0); //~ ERROR no method named | ^^^ | = help: did you mean `bar`? @@ -9,7 +12,7 @@ error[E0599]: no method named `bat` found for type `Foo` in the current scope error[E0599]: no method named `is_emtpy` found for type `std::string::String` in the current scope --> $DIR/suggest-methods.rs:31:15 | -31 | let _ = s.is_emtpy(); +31 | let _ = s.is_emtpy(); //~ ERROR no method named | ^^^^^^^^ | = help: did you mean `is_empty`? @@ -17,7 +20,7 @@ error[E0599]: no method named `is_emtpy` found for type `std::string::String` in error[E0599]: no method named `count_eos` found for type `u32` in the current scope --> $DIR/suggest-methods.rs:35:19 | -35 | let _ = 63u32.count_eos(); +35 | let _ = 63u32.count_eos(); //~ ERROR no method named | ^^^^^^^^^ | = help: did you mean `count_zeros`? @@ -25,7 +28,7 @@ error[E0599]: no method named `count_eos` found for type `u32` in the current sc error[E0599]: no method named `count_o` found for type `u32` in the current scope --> $DIR/suggest-methods.rs:38:19 | -38 | let _ = 63u32.count_o(); +38 | let _ = 63u32.count_o(); //~ ERROR no method named | ^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/try-on-option.rs b/src/test/ui/suggestions/try-on-option.rs index 4cd8cd81151..65ca23402d2 100644 --- a/src/test/ui/suggestions/try-on-option.rs +++ b/src/test/ui/suggestions/try-on-option.rs @@ -14,12 +14,12 @@ fn main() {} fn foo() -> Result<u32, ()> { let x: Option<u32> = None; - x?; + x?; //~ the trait bound Ok(22) } fn bar() -> u32 { let x: Option<u32> = None; - x?; + x?; //~ the `?` operator 22 } diff --git a/src/test/ui/suggestions/try-on-option.stderr b/src/test/ui/suggestions/try-on-option.stderr index 86d4510cad3..b1be9ad3cf6 100644 --- a/src/test/ui/suggestions/try-on-option.stderr +++ b/src/test/ui/suggestions/try-on-option.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `(): std::convert::From<std::option::NoneError>` is not satisfied --> $DIR/try-on-option.rs:17:5 | -17 | x?; +17 | x?; //~ the trait bound | ^^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()` | = note: required by `std::convert::From::from` @@ -9,7 +9,7 @@ error[E0277]: the trait bound `(): std::convert::From<std::option::NoneError>` i error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`) --> $DIR/try-on-option.rs:23:5 | -23 | x?; +23 | x?; //~ the `?` operator | -- | | | cannot use the `?` operator in a function that returns `u32` diff --git a/src/test/ui/suggestions/try-operator-on-main.rs b/src/test/ui/suggestions/try-operator-on-main.rs index eadd12924df..e9d285941b7 100644 --- a/src/test/ui/suggestions/try-operator-on-main.rs +++ b/src/test/ui/suggestions/try-operator-on-main.rs @@ -14,20 +14,20 @@ use std::ops::Try; fn main() { // error for a `Try` type on a non-`Try` fn - std::fs::File::open("foo")?; + std::fs::File::open("foo")?; //~ ERROR the `?` operator can only // a non-`Try` type on a non-`Try` fn - ()?; + ()?; //~ ERROR the `?` operator can only // an unrelated use of `Try` - try_trait_generic::<()>(); + try_trait_generic::<()>(); //~ ERROR the trait bound } fn try_trait_generic<T: Try>() -> T { // and a non-`Try` object on a `Try` fn. - ()?; + ()?; //~ ERROR the `?` operator can only loop {} } diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index e83bf2abc15..8b17e06065b 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -1,7 +1,7 @@ error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`) --> $DIR/try-operator-on-main.rs:17:5 | -17 | std::fs::File::open("foo")?; +17 | std::fs::File::open("foo")?; //~ ERROR the `?` operator can only | --------------------------- | | | cannot use the `?` operator in a function that returns `()` @@ -13,7 +13,7 @@ error[E0277]: the `?` operator can only be used in a function that returns `Resu error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/try-operator-on-main.rs:20:5 | -20 | ()?; +20 | ()?; //~ ERROR the `?` operator can only | --- | | | the `?` operator cannot be applied to type `()` @@ -25,7 +25,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `std error[E0277]: the trait bound `(): std::ops::Try` is not satisfied --> $DIR/try-operator-on-main.rs:23:5 | -23 | try_trait_generic::<()>(); +23 | try_trait_generic::<()>(); //~ ERROR the trait bound | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()` | = note: required by `try_trait_generic` @@ -33,7 +33,7 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/try-operator-on-main.rs:30:5 | -30 | ()?; +30 | ()?; //~ ERROR the `?` operator can only | --- | | | the `?` operator cannot be applied to type `()` diff --git a/src/test/ui/suggestions/tuple-float-index.rs b/src/test/ui/suggestions/tuple-float-index.rs index 8bfbd0e74db..0a188305a92 100644 --- a/src/test/ui/suggestions/tuple-float-index.rs +++ b/src/test/ui/suggestions/tuple-float-index.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main () { - (1, (2, 3)).1.1; + (1, (2, 3)).1.1; //~ ERROR unexpected token: `1.1` } diff --git a/src/test/ui/suggestions/tuple-float-index.stderr b/src/test/ui/suggestions/tuple-float-index.stderr index 4b1be26c86b..7d133f11cbb 100644 --- a/src/test/ui/suggestions/tuple-float-index.stderr +++ b/src/test/ui/suggestions/tuple-float-index.stderr @@ -1,7 +1,7 @@ error: unexpected token: `1.1` --> $DIR/tuple-float-index.rs:14:17 | -14 | (1, (2, 3)).1.1; +14 | (1, (2, 3)).1.1; //~ ERROR unexpected token: `1.1` | ------------^^^ | | | | | unexpected token diff --git a/src/test/ui/suggestions/type-ascription-instead-of-initializer.rs b/src/test/ui/suggestions/type-ascription-instead-of-initializer.rs index bcd965f10fa..d80dad8fbd4 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-initializer.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-initializer.rs @@ -9,5 +9,6 @@ // except according to those terms. fn main() { - let x: Vec::with_capacity(10, 20); + let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` + //~^ ERROR this function takes 1 parameter } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr b/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr index 647e3f84685..c3e8d7fcd61 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr @@ -1,7 +1,7 @@ error: expected type, found `10` --> $DIR/type-ascription-instead-of-initializer.rs:12:31 | -12 | let x: Vec::with_capacity(10, 20); +12 | let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` | -- ^^ | || | |help: use `=` if you meant to assign @@ -10,7 +10,7 @@ error: expected type, found `10` error[E0061]: this function takes 1 parameter but 2 parameters were supplied --> $DIR/type-ascription-instead-of-initializer.rs:12:31 | -12 | let x: Vec::with_capacity(10, 20); +12 | let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` | ^^^^^^ expected 1 parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs index 93de55a39e9..01d773dd5e1 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs @@ -12,9 +12,9 @@ fn main() { println!("test"): - 0; + 0; //~ ERROR expected type, found `0` } fn foo() { - println!("test"): 0; + println!("test"): 0; //~ ERROR expected type, found `0` } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr index 550048c7b88..9d26d004674 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr @@ -3,13 +3,13 @@ error: expected type, found `0` | 14 | println!("test"): | - help: did you mean to use `;` here? -15 | 0; +15 | 0; //~ ERROR expected type, found `0` | ^ expecting a type here because of type ascription error: expected type, found `0` --> $DIR/type-ascription-instead-of-statement-end.rs:19:23 | -19 | println!("test"): 0; +19 | println!("test"): 0; //~ ERROR expected type, found `0` | ^ expecting a type here because of type ascription error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/type-ascription-with-fn-call.rs b/src/test/ui/suggestions/type-ascription-with-fn-call.rs index 7c10bf98c84..b2c25c37e8e 100644 --- a/src/test/ui/suggestions/type-ascription-with-fn-call.rs +++ b/src/test/ui/suggestions/type-ascription-with-fn-call.rs @@ -12,7 +12,7 @@ fn main() { f() : - f(); + f(); //~ ERROR expected type, found function } fn f() {} diff --git a/src/test/ui/suggestions/type-ascription-with-fn-call.stderr b/src/test/ui/suggestions/type-ascription-with-fn-call.stderr index 93c65c263dd..d5e0b00f3df 100644 --- a/src/test/ui/suggestions/type-ascription-with-fn-call.stderr +++ b/src/test/ui/suggestions/type-ascription-with-fn-call.stderr @@ -3,7 +3,7 @@ error[E0573]: expected type, found function `f` | 14 | f() : | - help: did you mean to use `;` here instead? -15 | f(); +15 | f(); //~ ERROR expected type, found function | ^^^ | | | not a type diff --git a/src/test/ui/token/bounds-obj-parens.rs b/src/test/ui/token/bounds-obj-parens.rs index 02c119cf727..9617df8fa21 100644 --- a/src/test/ui/token/bounds-obj-parens.rs +++ b/src/test/ui/token/bounds-obj-parens.rs @@ -14,4 +14,3 @@ type A = Box<(Fn(D::Error) -> E) + 'static + Send + Sync>; // OK (but see #39318 FAIL //~^ ERROR -//~| ERROR diff --git a/src/test/ui/token/issue-10636-2.rs b/src/test/ui/token/issue-10636-2.rs index 93759123618..c22baee680a 100644 --- a/src/test/ui/token/issue-10636-2.rs +++ b/src/test/ui/token/issue-10636-2.rs @@ -15,6 +15,6 @@ pub fn trace_option(option: Option<isize>) { option.map(|some| 42; //~ NOTE: unclosed delimiter //~^ ERROR: expected one of //~| NOTE: expected one of - //~| NOTE: unexpected token + } //~ ERROR: incorrect close delimiter //~^ ERROR: expected expression, found `)` diff --git a/src/test/ui/token/issue-41155.rs b/src/test/ui/token/issue-41155.rs index 0f473c9e073..550a90fc6af 100644 --- a/src/test/ui/token/issue-41155.rs +++ b/src/test/ui/token/issue-41155.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -impl S { +impl S { //~ ERROR cannot find type pub -} +} //~ ERROR expected one of diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr index 50a38da9d8c..707784272ed 100644 --- a/src/test/ui/token/issue-41155.stderr +++ b/src/test/ui/token/issue-41155.stderr @@ -3,13 +3,13 @@ error: expected one of `(`, `const`, `default`, `extern`, `fn`, `type`, or `unsa | 12 | pub | - expected one of 7 possible tokens here -13 | } +13 | } //~ ERROR expected one of | ^ unexpected token error[E0412]: cannot find type `S` in this scope --> $DIR/issue-41155.rs:11:6 | -11 | impl S { +11 | impl S { //~ ERROR cannot find type | ^ not found in this scope error[E0601]: main function not found diff --git a/src/test/ui/token/macro-incomplete-parse.rs b/src/test/ui/token/macro-incomplete-parse.rs index 08749373432..fd2561ce496 100644 --- a/src/test/ui/token/macro-incomplete-parse.rs +++ b/src/test/ui/token/macro-incomplete-parse.rs @@ -21,7 +21,7 @@ macro_rules! ignored_item { macro_rules! ignored_expr { () => ( 1, //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,` //~^ NOTE expected one of `.`, `;`, `?`, `}`, or an operator here - //~| NOTE unexpected token + 2 ) } diff --git a/src/test/ui/token/trailing-plus-in-bounds.rs b/src/test/ui/token/trailing-plus-in-bounds.rs index 2bb2c97790c..72cae6abc2d 100644 --- a/src/test/ui/token/trailing-plus-in-bounds.rs +++ b/src/test/ui/token/trailing-plus-in-bounds.rs @@ -18,4 +18,3 @@ fn main() { FAIL //~^ ERROR -//~| ERROR diff --git a/src/test/ui/trait-method-private.rs b/src/test/ui/trait-method-private.rs index 5c1bd668ac6..54cf6e6783e 100644 --- a/src/test/ui/trait-method-private.rs +++ b/src/test/ui/trait-method-private.rs @@ -26,5 +26,5 @@ mod inner { fn main() { let foo = inner::Foo; - foo.method(); + foo.method(); //~ ERROR is private } diff --git a/src/test/ui/trait-method-private.stderr b/src/test/ui/trait-method-private.stderr index c7a7b689edc..7406541a9da 100644 --- a/src/test/ui/trait-method-private.stderr +++ b/src/test/ui/trait-method-private.stderr @@ -1,12 +1,14 @@ error[E0624]: method `method` is private --> $DIR/trait-method-private.rs:29:9 | -29 | foo.method(); +29 | foo.method(); //~ ERROR is private | ^^^^^^ | = help: items from traits can only be used if the trait is in scope - = note: the following trait is implemented but not in scope, perhaps add a `use` for it: - candidate #1: `use inner::Bar;` +help: the following trait is implemented but not in scope, perhaps add a `use` for it: + | +11 | use inner::Bar; + | error: aborting due to previous error diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.rs b/src/test/ui/transmute/transmute-from-fn-item-types-error.rs index d60c97f1d59..0a0214a24ff 100644 --- a/src/test/ui/transmute/transmute-from-fn-item-types-error.rs +++ b/src/test/ui/transmute/transmute-from-fn-item-types-error.rs @@ -12,16 +12,16 @@ use std::mem; unsafe fn foo() -> (i8, *const (), Option<fn()>) { let i = mem::transmute(bar); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR transmute called with types of different sizes + let p = mem::transmute(foo); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + let of = mem::transmute(main); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + (i, p, of) } @@ -30,15 +30,15 @@ unsafe fn bar() { // Error as usual if the resulting type is not pointer-sized. mem::transmute::<_, u8>(main); //~^ ERROR transmute called with types of different sizes - //~^^ NOTE transmuting between fn() {main} and u8 + mem::transmute::<_, *mut ()>(foo); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + mem::transmute::<_, fn()>(bar); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + // No error if a coercion would otherwise occur. mem::transmute::<fn(), usize>(main); @@ -46,16 +46,16 @@ unsafe fn bar() { unsafe fn baz() { mem::transmute::<_, *mut ()>(Some(foo)); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + mem::transmute::<_, fn()>(Some(bar)); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + mem::transmute::<_, Option<fn()>>(Some(baz)); - //~^ ERROR is zero-sized and can't be transmuted - //~^^ NOTE cast with `as` to a pointer instead + //~^ ERROR can't transmute zero-sized type + // No error if a coercion would otherwise occur. mem::transmute::<Option<fn()>, usize>(Some(main)); diff --git a/src/test/ui/transmute/transmute-type-parameters.rs b/src/test/ui/transmute/transmute-type-parameters.rs index 117fc2cc5df..fe340295f74 100644 --- a/src/test/ui/transmute/transmute-type-parameters.rs +++ b/src/test/ui/transmute/transmute-type-parameters.rs @@ -19,17 +19,17 @@ use std::mem::transmute; unsafe fn f<T>(x: T) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: T (size can vary) to i32 +//~^ ERROR transmute called with types of different sizes } unsafe fn g<T>(x: (T, i32)) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: (T, i32) (size can vary because of T) to i32 +//~^ ERROR transmute called with types of different sizes } unsafe fn h<T>(x: [T; 10]) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: [T; 10] (size can vary because of T) to i32 +//~^ ERROR transmute called with types of different sizes } struct Bad<T> { @@ -38,7 +38,7 @@ struct Bad<T> { unsafe fn i<T>(x: Bad<T>) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: Bad<T> (size can vary because of T) to i32 +//~^ ERROR transmute called with types of different sizes } enum Worse<T> { @@ -48,12 +48,12 @@ enum Worse<T> { unsafe fn j<T>(x: Worse<T>) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: Worse<T> (size can vary because of T) to i32 +//~^ ERROR transmute called with types of different sizes } unsafe fn k<T>(x: Option<T>) { let _: i32 = transmute(x); -//~^ ERROR differently sized types: std::option::Option<T> (size can vary because of T) to i32 +//~^ ERROR transmute called with types of different sizes } fn main() {} diff --git a/src/test/ui/type-check/assignment-in-if.rs b/src/test/ui/type-check/assignment-in-if.rs index 98dc55c6663..e4422f0b99a 100644 --- a/src/test/ui/type-check/assignment-in-if.rs +++ b/src/test/ui/type-check/assignment-in-if.rs @@ -24,25 +24,25 @@ fn main() { // `x { ... }` should not be interpreted as a struct literal here if x = x { //~^ ERROR mismatched types - //~| HELP did you mean to compare equality? + //~| HELP try comparing for equality println!("{}", x); } // Explicit parentheses on the left should match behavior of above if (x = x) { //~^ ERROR mismatched types - //~| HELP did you mean to compare equality? + //~| HELP try comparing for equality println!("{}", x); } // The struct literal interpretation is fine with explicit parentheses on the right if y = (Foo { foo: x }) { //~^ ERROR mismatched types - //~| HELP did you mean to compare equality? + //~| HELP try comparing for equality println!("{}", x); } // "invalid left-hand side expression" error is suppresed if 3 = x { //~^ ERROR mismatched types - //~| HELP did you mean to compare equality? + //~| HELP try comparing for equality println!("{}", x); } if (if true { x = 4 } else { x = 5 }) { diff --git a/src/test/ui/type-check/cannot_infer_local_or_array.rs b/src/test/ui/type-check/cannot_infer_local_or_array.rs index 0b35a9c3dbe..3ec96144da5 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_array.rs +++ b/src/test/ui/type-check/cannot_infer_local_or_array.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x = []; + let x = []; //~ ERROR type annotations needed } diff --git a/src/test/ui/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type-check/cannot_infer_local_or_array.stderr index 8c52bb5a1d3..19369f5ca60 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_array.stderr @@ -1,7 +1,7 @@ error[E0282]: type annotations needed --> $DIR/cannot_infer_local_or_array.rs:12:13 | -12 | let x = []; +12 | let x = []; //~ ERROR type annotations needed | - ^^ cannot infer type for `_` | | | consider giving `x` a type diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr index 4788fad2088..923dcd01070 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr @@ -6,7 +6,7 @@ error[E0282]: type annotations needed | | | consider giving `x` a type | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr index ccffadebe9e..24f2cef4a6c 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -6,7 +6,7 @@ error[E0282]: type annotations needed | | | consider giving the pattern a type | - = note: this error originates in a macro outside of the current crate + = note: this error originates in a macro outside of the current crate (run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type-check/issue-22897.rs b/src/test/ui/type-check/issue-22897.rs index 296dc81a89b..62eaa616d31 100644 --- a/src/test/ui/type-check/issue-22897.rs +++ b/src/test/ui/type-check/issue-22897.rs @@ -11,5 +11,5 @@ fn main() { } fn unconstrained_type() { - []; + []; //~ ERROR type annotations needed } diff --git a/src/test/ui/type-check/issue-22897.stderr b/src/test/ui/type-check/issue-22897.stderr index 95684118851..5ee350746be 100644 --- a/src/test/ui/type-check/issue-22897.stderr +++ b/src/test/ui/type-check/issue-22897.stderr @@ -1,7 +1,7 @@ error[E0282]: type annotations needed --> $DIR/issue-22897.rs:14:5 | -14 | []; +14 | []; //~ ERROR type annotations needed | ^^ cannot infer type for `[_; 0]` error: aborting due to previous error diff --git a/src/test/ui/type-check/issue-40294.rs b/src/test/ui/type-check/issue-40294.rs index d30a425d109..d2817062b27 100644 --- a/src/test/ui/type-check/issue-40294.rs +++ b/src/test/ui/type-check/issue-40294.rs @@ -12,7 +12,7 @@ trait Foo: Sized { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) +fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required where &'a T : Foo, &'b T : Foo { diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr index bb3a371b26e..2ca97aa3ef0 100644 --- a/src/test/ui/type-check/issue-40294.stderr +++ b/src/test/ui/type-check/issue-40294.stderr @@ -1,7 +1,7 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo` --> $DIR/issue-40294.rs:15:1 | -15 | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) +15 | / fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required 16 | | where &'a T : Foo, 17 | | &'b T : Foo 18 | | { diff --git a/src/test/ui/type-check/issue-41314.rs b/src/test/ui/type-check/issue-41314.rs index 5127a8ce174..7b4d2f05f5f 100644 --- a/src/test/ui/type-check/issue-41314.rs +++ b/src/test/ui/type-check/issue-41314.rs @@ -14,6 +14,7 @@ enum X { fn main() { match X::Y(0) { - X::Y { number } => {} + X::Y { number } => {} //~ ERROR does not have a field named `number` + //~^ ERROR pattern does not mention field `0` } } diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index acae7a35087..569924da6f4 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -1,13 +1,13 @@ error[E0026]: variant `X::Y` does not have a field named `number` --> $DIR/issue-41314.rs:17:16 | -17 | X::Y { number } => {} +17 | X::Y { number } => {} //~ ERROR does not have a field named `number` | ^^^^^^ variant `X::Y` does not have field `number` error[E0027]: pattern does not mention field `0` --> $DIR/issue-41314.rs:17:9 | -17 | X::Y { number } => {} +17 | X::Y { number } => {} //~ ERROR does not have a field named `number` | ^^^^^^^^^^^^^^^ missing field `0` | = note: trying to match a tuple variant with a struct variant pattern diff --git a/src/test/ui/type-check/unknown_type_for_closure.rs b/src/test/ui/type-check/unknown_type_for_closure.rs index f1d357df12c..0c355976330 100644 --- a/src/test/ui/type-check/unknown_type_for_closure.rs +++ b/src/test/ui/type-check/unknown_type_for_closure.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x = |_| { }; + let x = |_| { }; //~ ERROR type annotations needed } diff --git a/src/test/ui/type-check/unknown_type_for_closure.stderr b/src/test/ui/type-check/unknown_type_for_closure.stderr index afbd15ca486..1d8c0ddc8b6 100644 --- a/src/test/ui/type-check/unknown_type_for_closure.stderr +++ b/src/test/ui/type-check/unknown_type_for_closure.stderr @@ -1,7 +1,7 @@ error[E0282]: type annotations needed --> $DIR/unknown_type_for_closure.rs:12:14 | -12 | let x = |_| { }; +12 | let x = |_| { }; //~ ERROR type annotations needed | ^ consider giving this closure parameter a type error: aborting due to previous error diff --git a/src/test/ui/unboxed-closure-no-cyclic-sig.rs b/src/test/ui/unboxed-closure-no-cyclic-sig.rs new file mode 100644 index 00000000000..506bce0dbec --- /dev/null +++ b/src/test/ui/unboxed-closure-no-cyclic-sig.rs @@ -0,0 +1,19 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that unboxed closures cannot capture their own type. +// +// Also regression test for issue #21410. + +fn g<F>(_: F) where F: FnOnce(Option<F>) {} + +fn main() { + g(|_| { }); //~ ERROR closure/generator type that references itself +} diff --git a/src/test/ui/unboxed-closure-no-cyclic-sig.stderr b/src/test/ui/unboxed-closure-no-cyclic-sig.stderr new file mode 100644 index 00000000000..75a87f70660 --- /dev/null +++ b/src/test/ui/unboxed-closure-no-cyclic-sig.stderr @@ -0,0 +1,12 @@ +error[E0644]: closure/generator type that references itself + --> $DIR/unboxed-closure-no-cyclic-sig.rs:18:7 + | +18 | g(|_| { }); //~ ERROR closure/generator type that references itself + | ^^^^^^^^ cyclic type of infinite size + | + = note: closures cannot capture themselves or take themselves as argument; + this error may be the result of a recent compiler bug-fix, + see https://github.com/rust-lang/rust/issues/46062 for more details + +error: aborting due to previous error + diff --git a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.rs b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.rs index 14ef3b5f178..481346ad4b6 100644 --- a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.rs +++ b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.rs @@ -21,6 +21,6 @@ fn main() { // the closure implements `FnOnce`, not that it moves from inside // a `Fn` closure.) let y = (vec![1, 2, 3], 0); - let c = || drop(y.0); + let c = || drop(y.0); //~ ERROR expected a closure that implements the `Fn` trait foo(c); } diff --git a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr index d968c409396..d3d9ce2b34a 100644 --- a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -1,7 +1,7 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:13 | -24 | let c = || drop(y.0); +24 | let c = || drop(y.0); //~ ERROR expected a closure that implements the `Fn` trait | ^^^^^^^^^^^^ 25 | foo(c); | --- the requirement to implement `Fn` derives from here @@ -9,7 +9,7 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closur note: closure is `FnOnce` because it moves the variable `y` out of its environment --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:21 | -24 | let c = || drop(y.0); +24 | let c = || drop(y.0); //~ ERROR expected a closure that implements the `Fn` trait | ^ error: aborting due to previous error diff --git a/src/test/ui/union-fields.rs b/src/test/ui/union-fields.rs index 021f57e3eee..dc551bb8998 100644 --- a/src/test/ui/union-fields.rs +++ b/src/test/ui/union-fields.rs @@ -13,19 +13,19 @@ union U1 { a: u8, // should not be reported b: u8, // should not be reported - c: u8, // should be reported + c: u8, //~ ERROR field is never used } union U2 { - a: u8, // should be reported + a: u8, //~ ERROR field is never used b: u8, // should not be reported c: u8, // should not be reported } -union NoDropLike { a: u8 } // should be reported as unused +union NoDropLike { a: u8 } //~ ERROR field is never used union U { a: u8, // should not be reported b: u8, // should not be reported - c: u8, // should be reported + c: u8, //~ ERROR field is never used } type A = U; diff --git a/src/test/ui/union-fields.stderr b/src/test/ui/union-fields.stderr index f3a2702d5ae..ffcd178ca54 100644 --- a/src/test/ui/union-fields.stderr +++ b/src/test/ui/union-fields.stderr @@ -1,7 +1,7 @@ error: field is never used: `c` --> $DIR/union-fields.rs:16:5 | -16 | c: u8, // should be reported +16 | c: u8, //~ ERROR field is never used | ^^^^^ | note: lint level defined here @@ -13,19 +13,19 @@ note: lint level defined here error: field is never used: `a` --> $DIR/union-fields.rs:19:5 | -19 | a: u8, // should be reported +19 | a: u8, //~ ERROR field is never used | ^^^^^ error: field is never used: `a` --> $DIR/union-fields.rs:23:20 | -23 | union NoDropLike { a: u8 } // should be reported as unused +23 | union NoDropLike { a: u8 } //~ ERROR field is never used | ^^^^^ error: field is never used: `c` --> $DIR/union-fields.rs:28:5 | -28 | c: u8, // should be reported +28 | c: u8, //~ ERROR field is never used | ^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/union-sized-field.rs b/src/test/ui/union-sized-field.rs index eeca5ab7404..8999f1e0930 100644 --- a/src/test/ui/union-sized-field.rs +++ b/src/test/ui/union-sized-field.rs @@ -11,16 +11,16 @@ #![feature(untagged_unions)] union Foo<T: ?Sized> { - value: T, + value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied } struct Foo2<T: ?Sized> { - value: T, + value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied t: u32, } enum Foo3<T: ?Sized> { - Value(T), + Value(T), //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied } fn main() {} diff --git a/src/test/ui/union-sized-field.stderr b/src/test/ui/union-sized-field.stderr index ea90d97c4c3..9586f950739 100644 --- a/src/test/ui/union-sized-field.stderr +++ b/src/test/ui/union-sized-field.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied --> $DIR/union-sized-field.rs:14:5 | -14 | value: T, +14 | value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied | ^^^^^^^^ `T` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `T` @@ -11,7 +11,7 @@ error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied --> $DIR/union-sized-field.rs:18:5 | -18 | value: T, +18 | value: T, //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied | ^^^^^^^^ `T` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `T` @@ -21,7 +21,7 @@ error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied --> $DIR/union-sized-field.rs:23:11 | -23 | Value(T), +23 | Value(T), //~ ERROR the trait bound `T: std::marker::Sized` is not satisfied | ^^ `T` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `T` diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index b1122f401fe..d04231bbac0 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -60,8 +60,8 @@ const TEST_REPOS: &'static [Test] = &[ }, Test { name: "servo", - repo: "https://github.com/eddyb/servo", - sha: "6031de9a397e2feba4ff98725991825f62b68518", + repo: "https://github.com/servo/servo", + sha: "17e97b9320fdb7cdb33bbc5f4d0fde0653bbf2e4", lock: None, // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox. // This takes much less time to build than all of Servo and supports stable Rust. diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 8e9cd1a12fa..99d7dc78166 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -57,6 +57,25 @@ struct DiagnosticCode { explanation: Option<String>, } +pub fn extract_rendered(output: &str, proc_res: &ProcRes) -> String { + output.lines() + .filter_map(|line| if line.starts_with('{') { + match json::decode::<Diagnostic>(line) { + Ok(diagnostic) => diagnostic.rendered, + Err(error) => { + proc_res.fatal(Some(&format!("failed to decode compiler output as json: \ + `{}`\noutput: {}\nline: {}", + error, + line, + output))); + } + } + } else { + None + }) + .collect() +} + pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> { output.lines() .flat_map(|line| parse_line(file_name, line, output, proc_res)) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 749d1f4c378..7d20bb74c7a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1370,7 +1370,7 @@ actual:\n\ // Optionally prevent default --target if specified in test compile-flags. let custom_target = self.props.compile_flags .iter() - .fold(false, |acc, x| acc || x.starts_with("--target")); + .any(|x| x.starts_with("--target")); if !custom_target { let target = if self.props.force_host { @@ -1403,6 +1403,11 @@ actual:\n\ rustc.args(&["--error-format", "json"]); } } + Ui => { + if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { + rustc.args(&["--error-format", "json"]); + } + } MirOpt => { rustc.args(&[ "-Zdump-mir=all", @@ -1427,7 +1432,6 @@ actual:\n\ Codegen | Rustdoc | RunMake | - Ui | CodegenUnits => { // do not use JSON output } @@ -2211,6 +2215,11 @@ actual:\n\ } fn run_ui_test(&self) { + // if the user specified a format in the ui test + // print the output to the stderr file, otherwise extract + // the rendered error messages from json and print them + let explicit = self.props.compile_flags.iter().any(|s| s.contains("--error-format")); + let proc_res = self.compile_test(); let expected_stderr_path = self.expected_output_path("stderr"); @@ -2221,8 +2230,15 @@ actual:\n\ let normalized_stdout = self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout); + + let stderr = if explicit { + proc_res.stderr.clone() + } else { + json::extract_rendered(&proc_res.stderr, &proc_res) + }; + let normalized_stderr = - self.normalize_output(&proc_res.stderr, &self.props.normalize_stderr); + self.normalize_output(&stderr, &self.props.normalize_stderr); let mut errors = 0; errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout); @@ -2241,6 +2257,8 @@ actual:\n\ &proc_res); } + let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); + if self.props.run_pass { let proc_res = self.exec_compiled_test(); @@ -2248,6 +2266,15 @@ actual:\n\ self.fatal_proc_rec("test run failed!", &proc_res); } } + if !explicit { + if !expected_errors.is_empty() || !proc_res.status.success() { + // "// error-pattern" comments + self.check_expected_errors(expected_errors, &proc_res); + } else if !self.props.error_patterns.is_empty() || !proc_res.status.success() { + // "//~ERROR comments" + self.check_error_patterns(&proc_res.stderr, &proc_res); + } + } } fn run_mir_opt_test(&self) { @@ -2424,15 +2451,27 @@ actual:\n\ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String { let parent_dir = self.testpaths.file.parent().unwrap(); let cflags = self.props.compile_flags.join(" "); - let parent_dir_str = if cflags.contains("--error-format json") - || cflags.contains("--error-format pretty-json") { + let json = cflags.contains("--error-format json") || + cflags.contains("--error-format pretty-json") || + cflags.contains("--error-format=json") || + cflags.contains("--error-format=pretty-json"); + let parent_dir_str = if json { parent_dir.display().to_string().replace("\\", "\\\\") } else { parent_dir.display().to_string() }; - let mut normalized = output.replace(&parent_dir_str, "$DIR") - .replace("\\\\", "\\") // denormalize for paths on windows + let mut normalized = output.replace(&parent_dir_str, "$DIR"); + + if json { + // escaped newlines in json strings should be readable + // in the stderr files. There's no point int being correct, + // since only humans process the stderr files. + // Thus we just turn escaped newlines back into newlines. + normalized = normalized.replace("\\n", "\n"); + } + + normalized = normalized.replace("\\\\", "\\") // denormalize for paths on windows .replace("\\", "/") // normalize for paths on windows .replace("\r\n", "\n") // normalize for linebreaks on windows .replace("\t", "\\t"); // makes tabs visible diff --git a/src/tools/miri b/src/tools/miri -Subproject 80853e2f24a01db96fe9821e468dd2af75a4d2e +Subproject 6dbfe23c4d1af109c894ff9d7d5da97c025584e diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 598620fa293..bd49f288eb2 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -57,7 +57,6 @@ fn filter_dirs(path: &Path) -> bool { "src/libbacktrace", "src/libcompiler_builtins", "src/compiler-rt", - "src/rustllvm", "src/liblibc", "src/vendor", "src/rt/hoedown", diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index a689d8a8be4..40d84b98d3a 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -50,6 +50,11 @@ const UNEXPLAINED_IGNORE_DOCTEST_INFO: &str = r#"unexplained "```ignore" doctest "#; +const LLVM_UNREACHABLE_INFO: &str = r"\ +C++ code used llvm_unreachable, which triggers undefined behavior +when executed when assertions are disabled. +Use llvm::report_fatal_error for increased robustness."; + /// Parser states for line_is_url. #[derive(PartialEq)] #[allow(non_camel_case_types)] @@ -108,7 +113,7 @@ pub fn check(path: &Path, bad: &mut bool) { let mut contents = String::new(); super::walk(path, &mut super::filter_dirs, &mut |file| { let filename = file.file_name().unwrap().to_string_lossy(); - let extensions = [".rs", ".py", ".js", ".sh", ".c", ".h"]; + let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h"]; if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") { return @@ -153,6 +158,9 @@ pub fn check(path: &Path, bad: &mut bool) { if line.ends_with("```ignore") || line.ends_with("```rust,ignore") { err(UNEXPLAINED_IGNORE_DOCTEST_INFO); } + if filename.ends_with(".cpp") && line.contains("llvm_unreachable") { + err(LLVM_UNREACHABLE_INFO); + } } if !licenseck(file, &contents) { tidy_error!(bad, "{}: incorrect license", file.display()); |
