From 312e53d39f287551631b8f2e717452360e2d6786 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 20 Feb 2018 16:34:49 +0000 Subject: [PATCH 001/546] Update RELEASES.md for 1.25.0 --- RELEASES.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 64e2145e0f37b..aec2162dccd62 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,100 @@ +Version 1.25.0 (2018-03-29) +========================== + +Language +-------- +- [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358] +- [You can now use nested groups of imports.][47948] + eg. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` +- [You can now have `|` at the start of a match arm.][47947] eg. +```rust +enum Foo { A, B, C } + +fn main() { + let x = Foo::A; + match x { + | Foo::A + | Foo::B => println!("AB"), + | Foo::C => println!("C"), + } +} +``` + +Compiler +-------- +- [Upgraded to LLVM 6.][47828] +- [Added `-C lto=val` option.][47521] +- [Added `i586-unknown-linux-musl` target][47282] + +Libraries +--------- +- [Impl Send for `process::Command` on Unix.][47760] +- [Impl PartialEq and Eq for `ParseCharError`.][47790] +- [`UnsafeCell::into_inner` is now safe.][47204] +- [Implement libstd for CloudABI.][47268] +- [`Float::{from_bits, to_bits}` is now available in libcore.][46931] +- [renamed `ptr::Shared` to `ptr::NonNull`.][46952] +- [Implement `AsRef` for Component][46985] +- [Deprecated `[T]::rotate` in favor of `[T]::rotate_{left,right}`.][46777] +- [Implemented `Write` for `Cursor<&mut Vec>`][46830] +- [Moved `Duration` to libcore.][46666] + +Stabilized APIs +--------------- +- [`Location::column`] + +The following functions can now be used in a constant expression. +eg. `static MINUTE: Duration = Duration::from_secs(60);` +- [`Duration::new`][47300] +- [`Duration::from_secs`][47300] +- [`Duration::from_millis`][47300] +- [`Duration::from_micros`][47300] +- [`Duration::from_nanos`][47300] + +Cargo +----- +- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] +- [`cargo new` now defaults to creating a binary crate, instead of a + libary crate.][cargo/5029] + +Misc +---- + +Compatibility Notes +------------------- +- [Deprecated `net::lookup_host`.][47510] +- [`rustdoc` has switched to pulldown as the default markdown renderer.][47398] +- The borrow checker was sometimes incorrectly permitting overlapping borrows + around indexing operations (see #47349). This has been fixed (which also + enabled some correct code that used to cause errors (e.g. #33903 and #46095). +- [Removed deprecated unstable attribute `#[simd]`.][47251] + +[47947]: https://github.com/rust-lang/rust/pull/47947 +[47948]: https://github.com/rust-lang/rust/pull/47948 +[47760]: https://github.com/rust-lang/rust/pull/47760 +[47790]: https://github.com/rust-lang/rust/pull/47790 +[47828]: https://github.com/rust-lang/rust/pull/47828 +[47398]: https://github.com/rust-lang/rust/pull/47398 +[47510]: https://github.com/rust-lang/rust/pull/47510 +[47521]: https://github.com/rust-lang/rust/pull/47521 +[47204]: https://github.com/rust-lang/rust/pull/47204 +[47251]: https://github.com/rust-lang/rust/pull/47251 +[47268]: https://github.com/rust-lang/rust/pull/47268 +[47282]: https://github.com/rust-lang/rust/pull/47282 +[47300]: https://github.com/rust-lang/rust/pull/47300 +[46931]: https://github.com/rust-lang/rust/pull/46931 +[46952]: https://github.com/rust-lang/rust/pull/46952 +[46985]: https://github.com/rust-lang/rust/pull/46985 +[47006]: https://github.com/rust-lang/rust/pull/47006 +[46777]: https://github.com/rust-lang/rust/pull/46777 +[46830]: https://github.com/rust-lang/rust/pull/46830 +[46666]: https://github.com/rust-lang/rust/pull/46666 +[cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 +[cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 +[RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 +[`Location::column`]: https://doc.rust-lang.org/std/panic/struct.Location.html#method.column + + Version 1.24.0 (2018-02-15) ========================== From 1f3b626527ed71f70c0a6602895f677e1baf479c Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 20 Feb 2018 19:55:14 +0000 Subject: [PATCH 002/546] Update RELEASES.md --- RELEASES.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index aec2162dccd62..9ba5384602bb3 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -33,15 +33,15 @@ Libraries - [`UnsafeCell::into_inner` is now safe.][47204] - [Implement libstd for CloudABI.][47268] - [`Float::{from_bits, to_bits}` is now available in libcore.][46931] -- [renamed `ptr::Shared` to `ptr::NonNull`.][46952] + - [Implement `AsRef` for Component][46985] -- [Deprecated `[T]::rotate` in favor of `[T]::rotate_{left,right}`.][46777] - [Implemented `Write` for `Cursor<&mut Vec>`][46830] - [Moved `Duration` to libcore.][46666] Stabilized APIs --------------- - [`Location::column`] +- [`ptr::NonNull`] The following functions can now be used in a constant expression. eg. `static MINUTE: Duration = Duration::from_secs(60);` @@ -65,10 +65,11 @@ Compatibility Notes - [Deprecated `net::lookup_host`.][47510] - [`rustdoc` has switched to pulldown as the default markdown renderer.][47398] - The borrow checker was sometimes incorrectly permitting overlapping borrows - around indexing operations (see #47349). This has been fixed (which also - enabled some correct code that used to cause errors (e.g. #33903 and #46095). + around indexing operations (see [#47349][47349]). This has been fixed (which also + enabled some correct code that used to cause errors (e.g. [#33903][33903] and [#46095][46095]). - [Removed deprecated unstable attribute `#[simd]`.][47251] +[33903]: https://github.com/rust-lang/rust/pull/33903 [47947]: https://github.com/rust-lang/rust/pull/47947 [47948]: https://github.com/rust-lang/rust/pull/47948 [47760]: https://github.com/rust-lang/rust/pull/47760 @@ -82,17 +83,18 @@ Compatibility Notes [47268]: https://github.com/rust-lang/rust/pull/47268 [47282]: https://github.com/rust-lang/rust/pull/47282 [47300]: https://github.com/rust-lang/rust/pull/47300 +[47349]: https://github.com/rust-lang/rust/pull/47349 [46931]: https://github.com/rust-lang/rust/pull/46931 -[46952]: https://github.com/rust-lang/rust/pull/46952 [46985]: https://github.com/rust-lang/rust/pull/46985 [47006]: https://github.com/rust-lang/rust/pull/47006 -[46777]: https://github.com/rust-lang/rust/pull/46777 [46830]: https://github.com/rust-lang/rust/pull/46830 +[46095]: https://github.com/rust-lang/rust/pull/46095 [46666]: https://github.com/rust-lang/rust/pull/46666 [cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 [cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 [RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 [`Location::column`]: https://doc.rust-lang.org/std/panic/struct.Location.html#method.column +[`ptr::NonNull`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html Version 1.24.0 (2018-02-15) From acc1b6dc99e6b9bef412024ed0803dd08f33c1c8 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Thu, 22 Feb 2018 13:29:37 +0000 Subject: [PATCH 003/546] Update RELEASES.md --- RELEASES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 9ba5384602bb3..1b2097144d718 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,8 +5,8 @@ Language -------- - [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358] - [You can now use nested groups of imports.][47948] - eg. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` -- [You can now have `|` at the start of a match arm.][47947] eg. + e.g. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` +- [You can now have `|` at the start of a match arm.][47947] e.g. ```rust enum Foo { A, B, C } @@ -55,7 +55,7 @@ Cargo ----- - [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] - [`cargo new` now defaults to creating a binary crate, instead of a - libary crate.][cargo/5029] + library crate.][cargo/5029] Misc ---- From 518b3f7eeed94027673b55b6f459a22983ac542f Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 15:33:36 -0800 Subject: [PATCH 004/546] Update libc to bring in posix_spawn bindings for FreeBSD. --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index 56444a4545bd7..8bed48a751562 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 56444a4545bd71430d64b86b8a71714cfdbe9f5d +Subproject commit 8bed48a751562c1c396b361bb6940c677268e997 From 11696acd6d070a90e8dd386a3c9ae877740fb0e2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jan 2018 18:13:45 -0800 Subject: [PATCH 005/546] Support posix_spawn() when possible. --- src/libstd/sys/unix/process/process_unix.rs | 102 ++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 189280a4ba9a8..d66c2375140c0 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -24,6 +24,7 @@ impl Command { -> io::Result<(Process, StdioPipes)> { use sys; + const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; let envp = self.capture_env(); @@ -34,6 +35,11 @@ impl Command { } let (ours, theirs) = self.setup_io(default, needs_stdin)?; + + if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? { + return Ok((ret, ours)) + } + let (input, output) = sys::pipe::anon_pipe()?; let pid = unsafe { @@ -229,6 +235,102 @@ impl Command { libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); io::Error::last_os_error() } + + #[cfg(not(any(target_os = "linux", target_os = "macos")))] + fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + -> io::Result> + { + Ok(None) + } + + #[cfg(any(target_os = "linux", target_os = "macos"))] + fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + -> io::Result> + { + use mem; + use sys; + + if self.get_cwd().is_some() || + self.get_gid().is_some() || + self.get_uid().is_some() || + self.get_closures().len() != 0 { + return Ok(None) + } + + let mut p = Process { pid: 0, status: None }; + + struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); + + impl Drop for PosixSpawnFileActions { + fn drop(&mut self) { + unsafe { + libc::posix_spawn_file_actions_destroy(&mut self.0); + } + } + } + + struct PosixSpawnattr(libc::posix_spawnattr_t); + + impl Drop for PosixSpawnattr { + fn drop(&mut self) { + unsafe { + libc::posix_spawnattr_destroy(&mut self.0); + } + } + } + + unsafe { + let mut file_actions = PosixSpawnFileActions(mem::zeroed()); + let mut attrs = PosixSpawnattr(mem::zeroed()); + + libc::posix_spawnattr_init(&mut attrs.0); + libc::posix_spawn_file_actions_init(&mut file_actions.0); + + if let Some(fd) = stdio.stdin.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDIN_FILENO))?; + } + if let Some(fd) = stdio.stdout.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDOUT_FILENO))?; + } + if let Some(fd) = stdio.stderr.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDERR_FILENO))?; + } + + let mut set: libc::sigset_t = mem::zeroed(); + cvt(libc::sigemptyset(&mut set))?; + cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0, + &set))?; + cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?; + cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0, + &set))?; + + let flags = libc::POSIX_SPAWN_SETSIGDEF | + libc::POSIX_SPAWN_SETSIGMASK; + cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?; + + let envp = envp.map(|c| c.as_ptr()) + .unwrap_or(sys::os::environ() as *const _); + let ret = libc::posix_spawnp( + &mut p.pid, + self.get_argv()[0], + &file_actions.0, + &attrs.0, + self.get_argv().as_ptr() as *const _, + envp as *const _, + ); + if ret == 0 { + Ok(Some(p)) + } else { + Err(io::Error::last_os_error()) + } + } + } } //////////////////////////////////////////////////////////////////////////////// From f4633865d37dea15a88220e886e77839aa1fd1ba Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 17:33:44 -0800 Subject: [PATCH 006/546] Avoid error for unused variables --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index d66c2375140c0..05b4b9b085b4b 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -237,7 +237,7 @@ impl Command { } #[cfg(not(any(target_os = "linux", target_os = "macos")))] - fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) From 94630e4ca509f9b37e4c066eee94f40da12cba51 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 20:23:46 -0800 Subject: [PATCH 007/546] No need to zero when an initializer for the object is already used. --- src/libstd/sys/unix/process/process_unix.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 05b4b9b085b4b..b394d5ff41aa2 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -280,8 +280,8 @@ impl Command { } unsafe { - let mut file_actions = PosixSpawnFileActions(mem::zeroed()); - let mut attrs = PosixSpawnattr(mem::zeroed()); + let mut file_actions = PosixSpawnFileActions(mem::uninitialized()); + let mut attrs = PosixSpawnattr(mem::uninitialized()); libc::posix_spawnattr_init(&mut attrs.0); libc::posix_spawn_file_actions_init(&mut file_actions.0); @@ -302,7 +302,7 @@ impl Command { libc::STDERR_FILENO))?; } - let mut set: libc::sigset_t = mem::zeroed(); + let mut set: libc::sigset_t = mem::uninitialized(); cvt(libc::sigemptyset(&mut set))?; cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0, &set))?; From 8e3fa0d3c450051d6445aa82682416eb307b2d5b Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 23:51:19 -0800 Subject: [PATCH 008/546] Pass proper pointer for envp. --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index b394d5ff41aa2..9765ff37e9b7d 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -315,7 +315,7 @@ impl Command { cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?; let envp = envp.map(|c| c.as_ptr()) - .unwrap_or(sys::os::environ() as *const _); + .unwrap_or(*sys::os::environ() as *const _); let ret = libc::posix_spawnp( &mut p.pid, self.get_argv()[0], From b3ecf5f57ca9d34d10ffd9d064a027ce3f4888ac Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 23:51:39 -0800 Subject: [PATCH 009/546] Remove excess newline --- src/libstd/sys/unix/process/process_unix.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 9765ff37e9b7d..fa66245abb6d2 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -24,7 +24,6 @@ impl Command { -> io::Result<(Process, StdioPipes)> { use sys; - const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; let envp = self.capture_env(); From 85b82f254e28f5e50b25d8e096af0f01e4441ef7 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 27 Feb 2018 14:12:52 -0800 Subject: [PATCH 010/546] Support posix_spawn() for FreeBSD. spawn() is expected to return an error if the specified file could not be executed. FreeBSD's posix_spawn() supports returning ENOENT/ENOEXEC if the exec() fails, which not all platforms support. This brings a very significant performance improvement for FreeBSD, involving heavy use of Command in threads, due to fork() invoking jemalloc fork handlers and causing lock contention. FreeBSD's posix_spawn() avoids this problem due to using vfork() internally. --- src/libstd/sys/unix/process/process_unix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index fa66245abb6d2..c7841a861ceb7 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,14 +235,14 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "linux", target_os = "macos")))] + #[cfg(not(any(target_os = "freebsd")))] fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) } - #[cfg(any(target_os = "linux", target_os = "macos"))] + #[cfg(any(target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { From e6efd0d640742ed4a2fbd32fe79fb743772838cc Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 19:09:59 -0800 Subject: [PATCH 011/546] Add a specific test for spawn() returning ENOENT --- .../run-pass/process-spawn-nonexistent.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/run-pass/process-spawn-nonexistent.rs diff --git a/src/test/run-pass/process-spawn-nonexistent.rs b/src/test/run-pass/process-spawn-nonexistent.rs new file mode 100644 index 0000000000000..9219cd625f30f --- /dev/null +++ b/src/test/run-pass/process-spawn-nonexistent.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-cloudabi no processes +// ignore-emscripten no processes + +use std::io::ErrorKind; +use std::process::Command; + +fn main() { + assert_eq!(Command::new("nonexistent") + .spawn() + .unwrap_err() + .kind(), + ErrorKind::NotFound); +} From a9ea876960a06f3ae00049515bf9ef706cca806b Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 22:16:35 -0800 Subject: [PATCH 012/546] posix_spawn() always returns its error rather than setting errno. --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index c7841a861ceb7..c5dda6273efa3 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -326,7 +326,7 @@ impl Command { if ret == 0 { Ok(Some(p)) } else { - Err(io::Error::last_os_error()) + Err(io::Error::from_raw_os_error(ret)) } } } From 2e2d9260f9425cd700199383096d8201190737de Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 1 Mar 2018 09:17:49 -0800 Subject: [PATCH 013/546] posix_spawn() on OSX supports returning ENOENT. --- src/libstd/sys/unix/process/process_unix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index c5dda6273efa3..dcf0278b4aaa7 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,14 +235,14 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "freebsd")))] + #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) } - #[cfg(any(target_os = "freebsd"))] + #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { From ef73b3ae2eac3a03f5b966a4f8b2a568e3619d51 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 1 Mar 2018 09:18:16 -0800 Subject: [PATCH 014/546] Add comment explaining when posix_spawn() can be supported. --- src/libstd/sys/unix/process/process_unix.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index dcf0278b4aaa7..bd6a8d3f64bee 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -242,6 +242,8 @@ impl Command { Ok(None) } + // Only support platforms for which posix_spawn() can return ENOENT + // directly. #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> From 99b50efb6eb048297cda699ad017821822591d7a Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 08:50:37 -0800 Subject: [PATCH 015/546] Use _ --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index bd6a8d3f64bee..51ae0aa73159a 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -236,7 +236,7 @@ impl Command { } #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] - fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) + fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>) -> io::Result> { Ok(None) From 5ba6b3a728fb50cd65237b8eeac2f2df05c3c77f Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 12:50:07 -0800 Subject: [PATCH 016/546] Move glibc version lookup handling to sys::os and add a simpler glibc_version() --- src/libstd/sys/unix/net.rs | 33 +++++---------------------------- src/libstd/sys/unix/os.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 3f65975e60880..04d9f0b06d344 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -383,12 +383,12 @@ impl IntoInner for Socket { // believe it's thread-safe). #[cfg(target_env = "gnu")] fn on_resolver_failure() { + use sys; + // If the version fails to parse, we treat it the same as "not glibc". - if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { - if let Some(version) = parse_glibc_version(version_str) { - if version < (2, 26) { - unsafe { libc::res_init() }; - } + if let Some(version) = sys::os::glibc_version() { + if version < (2, 26) { + unsafe { libc::res_init() }; } } } @@ -396,29 +396,6 @@ fn on_resolver_failure() { #[cfg(not(target_env = "gnu"))] fn on_resolver_failure() {} -#[cfg(target_env = "gnu")] -fn glibc_version_cstr() -> Option<&'static CStr> { - weak! { - fn gnu_get_libc_version() -> *const libc::c_char - } - if let Some(f) = gnu_get_libc_version.get() { - unsafe { Some(CStr::from_ptr(f())) } - } else { - None - } -} - -// Returns Some((major, minor)) if the string is a valid "x.y" version, -// ignoring any extra dot-separated parts. Otherwise return None. -#[cfg(target_env = "gnu")] -fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { - let mut parsed_ints = version.split(".").map(str::parse::).fuse(); - match (parsed_ints.next(), parsed_ints.next()) { - (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), - _ => None - } -} - #[cfg(all(test, taget_env = "gnu"))] mod test { use super::*; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index a46e855b4a6f4..4c86fddee4b45 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -546,3 +546,35 @@ pub fn getpid() -> u32 { pub fn getppid() -> u32 { unsafe { libc::getppid() as u32 } } + +#[cfg(target_env = "gnu")] +pub fn glibc_version() -> Option<(usize, usize)> { + if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { + parse_glibc_version(version_str) + } else { + None + } +} + +#[cfg(target_env = "gnu")] +fn glibc_version_cstr() -> Option<&'static CStr> { + weak! { + fn gnu_get_libc_version() -> *const libc::c_char + } + if let Some(f) = gnu_get_libc_version.get() { + unsafe { Some(CStr::from_ptr(f())) } + } else { + None + } +} + +// Returns Some((major, minor)) if the string is a valid "x.y" version, +// ignoring any extra dot-separated parts. Otherwise return None. +#[cfg(target_env = "gnu")] +fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { + let mut parsed_ints = version.split(".").map(str::parse::).fuse(); + match (parsed_ints.next(), parsed_ints.next()) { + (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), + _ => None + } +} From d740083fc8981ee933dc48a6b3dcee21b82c993e Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 13:02:38 -0800 Subject: [PATCH 017/546] Support posix_spawn() for Linux glibc 2.24+. The relevant support was added in https://sourceware.org/bugzilla/show_bug.cgi?id=10354#c12 --- src/libstd/sys/unix/process/process_unix.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 51ae0aa73159a..29e33ee822ee5 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,7 +235,8 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] + #[cfg(not(any(target_os = "macos", target_os = "freebsd", + all(target_os = "linux", target_env = "gnu"))))] fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>) -> io::Result> { @@ -244,7 +245,8 @@ impl Command { // Only support platforms for which posix_spawn() can return ENOENT // directly. - #[cfg(any(target_os = "macos", target_os = "freebsd"))] + #[cfg(any(target_os = "macos", target_os = "freebsd", + all(target_os = "linux", target_env = "gnu")))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { @@ -258,6 +260,18 @@ impl Command { return Ok(None) } + // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly. + #[cfg(all(target_os = "linux", target_env = "gnu"))] + { + if let Some(version) = sys::os::glibc_version() { + if version < (2, 24) { + return Ok(None) + } + } else { + return Ok(None) + } + } + let mut p = Process { pid: 0, status: None }; struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); From 81130ed4b104adf28921120416dcc9db3253c996 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 11:22:55 +0100 Subject: [PATCH 018/546] Split param-bounds-ignored into two, it was testing two independent things Also, tweak the test for ignored type aliases such that replacing the type alias by a newtype struct leads to a well-formed type definition, and errors when used the way the type alias is used. --- ...s-ignored.rs => higher-lifetime-bounds.rs} | 26 +--------- ...d.stderr => higher-lifetime-bounds.stderr} | 48 ++++------------- src/test/ui/type-alias-bounds.rs | 51 +++++++++++++++++++ src/test/ui/type-alias-bounds.stderr | 32 ++++++++++++ 4 files changed, 95 insertions(+), 62 deletions(-) rename src/test/ui/{param-bounds-ignored.rs => higher-lifetime-bounds.rs} (77%) rename src/test/ui/{param-bounds-ignored.stderr => higher-lifetime-bounds.stderr} (61%) create mode 100644 src/test/ui/type-alias-bounds.rs create mode 100644 src/test/ui/type-alias-bounds.stderr diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/higher-lifetime-bounds.rs similarity index 77% rename from src/test/ui/param-bounds-ignored.rs rename to src/test/ui/higher-lifetime-bounds.rs index 94bcdec945035..70b3b34fbd8fc 100644 --- a/src/test/ui/param-bounds-ignored.rs +++ b/src/test/ui/higher-lifetime-bounds.rs @@ -10,31 +10,7 @@ #![allow(dead_code, non_camel_case_types)] -use std::rc::Rc; - -type SVec = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases -type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>; -//~^ WARN bounds on generic parameters are ignored in type aliases -type WVec<'b, T: 'b+'b> = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases -type W2Vec<'b, T> where T: 'b, T: 'b = Vec; -//~^ WARN where clauses are ignored in type aliases - -fn foo<'a>(y: &'a i32) { - // If the bounds above would matter, the code below would be rejected. - let mut x : SVec<_> = Vec::new(); - x.push(Rc::new(42)); - - let mut x : VVec<'static, 'a> = Vec::new(); - x.push(y); - - let mut x : WVec<'static, & 'a i32> = Vec::new(); - x.push(y); - - let mut x : W2Vec<'static, & 'a i32> = Vec::new(); - x.push(y); -} +// Test that bounds on higher-kinded lifetime binders are rejected. fn bar1<'a, 'b>( x: &'a i32, diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/higher-lifetime-bounds.stderr similarity index 61% rename from src/test/ui/param-bounds-ignored.stderr rename to src/test/ui/higher-lifetime-bounds.stderr index 657fec54f9608..82c0074743604 100644 --- a/src/test/ui/param-bounds-ignored.stderr +++ b/src/test/ui/higher-lifetime-bounds.stderr @@ -1,94 +1,68 @@ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:42:22 + --> $DIR/higher-lifetime-bounds.rs:18:22 | LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) | ^^^ ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:50:34 + --> $DIR/higher-lifetime-bounds.rs:26:34 | LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:65:28 + --> $DIR/higher-lifetime-bounds.rs:41:28 | LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:77:25 + --> $DIR/higher-lifetime-bounds.rs:53:25 | LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:85:28 + --> $DIR/higher-lifetime-bounds.rs:61:28 | LL | struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:87:40 + --> $DIR/higher-lifetime-bounds.rs:63:40 | LL | struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:89:37 + --> $DIR/higher-lifetime-bounds.rs:65:37 | LL | struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:92:29 + --> $DIR/higher-lifetime-bounds.rs:68:29 | LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:95:29 + --> $DIR/higher-lifetime-bounds.rs:71:29 | LL | type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:99:34 + --> $DIR/higher-lifetime-bounds.rs:75:34 | LL | let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:101:38 + --> $DIR/higher-lifetime-bounds.rs:77:38 | LL | let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; | ^^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:15:14 - | -LL | type SVec = Vec; - | ^^^^ ^^^^ - | - = note: #[warn(ignored_generic_bounds)] on by default - -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:17:19 - | -LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>; - | ^^ ^^ - -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:19:18 - | -LL | type WVec<'b, T: 'b+'b> = Vec; - | ^^ ^^ - -warning: where clauses are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:21:25 - | -LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec; - | ^^^^^ ^^^^^ - error: aborting due to 11 previous errors diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs new file mode 100644 index 0000000000000..ed368e8f1500e --- /dev/null +++ b/src/test/ui/type-alias-bounds.rs @@ -0,0 +1,51 @@ +// 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. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test ignored_generic_bounds lint warning about bounds in type aliases + +// must-compile-successfully +#![allow(dead_code)] + +use std::rc::Rc; + +type SVec = Vec; +//~^ WARN bounds on generic parameters are ignored in type aliases +type S2Vec where T: Send = Vec; +//~^ WARN where clauses are ignored in type aliases +type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); +//~^ WARN bounds on generic parameters are ignored in type aliases +type WVec<'b, T: 'b+'b> = (&'b u32, Vec); +//~^ WARN bounds on generic parameters are ignored in type aliases +type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); +//~^ WARN where clauses are ignored in type aliases + +static STATIC : u32 = 0; + +fn foo<'a>(y: &'a i32) { + // If any of the bounds above would matter, the code below would be rejected. + // This can be seen when replacing the type aliases above by newtype structs. + // (The type aliases have no unused parameters to make that a valid transformation.) + let mut x : SVec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x : S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x : VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // 'a: 'static does not hold + + let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // &'a i32: 'static does not hold + + let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // &'a i32: 'static does not hold +} + +fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr new file mode 100644 index 0000000000000..5237f3c19efcd --- /dev/null +++ b/src/test/ui/type-alias-bounds.stderr @@ -0,0 +1,32 @@ +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:18:14 + | +LL | type SVec = Vec; + | ^^^^ ^^^^ + | + = note: #[warn(ignored_generic_bounds)] on by default + +warning: where clauses are ignored in type aliases + --> $DIR/type-alias-bounds.rs:20:21 + | +LL | type S2Vec where T: Send = Vec; + | ^^^^^^^ + +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:22:19 + | +LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ + +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:24:18 + | +LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); + | ^^ ^^ + +warning: where clauses are ignored in type aliases + --> $DIR/type-alias-bounds.rs:26:25 + | +LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); + | ^^^^^ ^^^^^ + From 562b44d8c3dbcf7c36209774e50fe833e65a98d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 11:43:51 +0100 Subject: [PATCH 019/546] Rename ignored_generic_bounds -> type_alias_bounds First of all, the lint is specific for type aliases. Second, it turns out the bounds are not entirely ignored but actually used when accessing associated types. So change the wording of the lint, and adapt its name to reality. The lint has never been on stable or beta, so renaming is safe. --- src/librustc_lint/builtin.rs | 25 +++++------ src/librustc_lint/lib.rs | 2 +- src/test/compile-fail/issue-17994.rs | 2 +- .../compile-fail/private-in-public-warn.rs | 4 +- src/test/ui/type-alias-bounds.rs | 25 ++++++++--- src/test/ui/type-alias-bounds.stderr | 43 ++++++++++++++----- 6 files changed, 68 insertions(+), 33 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c6698cbd00689..bdb36ab15b624 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1316,24 +1316,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { } } -/// Lint for trait and lifetime bounds that are (accidentally) accepted by the parser, but -/// ignored later. +/// Lint for trait and lifetime bounds in type aliases being mostly ignored: +/// They are relevant when using associated types, but otherwise neither checked +/// at definition site nor enforced at use site. -pub struct IgnoredGenericBounds; +pub struct TypeAliasBounds; declare_lint! { - IGNORED_GENERIC_BOUNDS, + TYPE_ALIAS_BOUNDS, Warn, - "these generic bounds are ignored" + "bounds in type aliases are not enforced" } -impl LintPass for IgnoredGenericBounds { +impl LintPass for TypeAliasBounds { fn get_lints(&self) -> LintArray { - lint_array!(IGNORED_GENERIC_BOUNDS) + lint_array!(TYPE_ALIAS_BOUNDS) } } -impl EarlyLintPass for IgnoredGenericBounds { +impl EarlyLintPass for TypeAliasBounds { fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { let type_alias_generics = match item.node { ast::ItemKind::Ty(_, ref generics) => generics, @@ -1343,8 +1344,8 @@ impl EarlyLintPass for IgnoredGenericBounds { if !type_alias_generics.where_clause.predicates.is_empty() { let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter() .map(|pred| pred.span()).collect(); - cx.span_lint(IGNORED_GENERIC_BOUNDS, spans, - "where clauses are ignored in type aliases"); + cx.span_lint(TYPE_ALIAS_BOUNDS, spans, + "where clauses are not enforced in type aliases"); } // The parameters must not have bounds for param in type_alias_generics.params.iter() { @@ -1354,9 +1355,9 @@ impl EarlyLintPass for IgnoredGenericBounds { }; if !spans.is_empty() { cx.span_lint( - IGNORED_GENERIC_BOUNDS, + TYPE_ALIAS_BOUNDS, spans, - "bounds on generic parameters are ignored in type aliases", + "bounds on generic parameters are not enforced in type aliases", ); } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 779aa3a9037ca..38f7a0b6faa0f 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -109,7 +109,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedImportBraces, AnonymousParameters, UnusedDocComment, - IgnoredGenericBounds, + TypeAliasBounds, ); add_early_builtin_with_new!(sess, diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs index 0f30e2461cf3b..7c3811e2ef28b 100644 --- a/src/test/compile-fail/issue-17994.rs +++ b/src/test/compile-fail/issue-17994.rs @@ -10,5 +10,5 @@ trait Tr {} type Huh where T: Tr = isize; //~ ERROR type parameter `T` is unused - //~| WARNING where clauses are ignored in type aliases + //~| WARNING where clauses are not enforced in type aliases fn main() {} diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index cc9eed7e65426..8bd9b0a901d65 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,7 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING bounds on generic parameters are ignored + //~^ WARNING bounds on generic parameters are not enforced in type aliases //~| WARNING hard error pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error @@ -85,7 +85,7 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error - //~| WARNING where clauses are ignored in type aliases + //~| WARNING where clauses are not enforced in type aliases pub trait Tr2 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs index ed368e8f1500e..7ec3afd9c870a 100644 --- a/src/test/ui/type-alias-bounds.rs +++ b/src/test/ui/type-alias-bounds.rs @@ -10,21 +10,20 @@ // Test ignored_generic_bounds lint warning about bounds in type aliases -// must-compile-successfully #![allow(dead_code)] use std::rc::Rc; type SVec = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type S2Vec where T: Send = Vec; -//~^ WARN where clauses are ignored in type aliases +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type WVec<'b, T: 'b+'b> = (&'b u32, Vec); -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); -//~^ WARN where clauses are ignored in type aliases +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] static STATIC : u32 = 0; @@ -48,4 +47,18 @@ fn foo<'a>(y: &'a i32) { x.1.push(y); // &'a i32: 'static does not hold } +// Bounds are not checked either, i.e. the definition is not necessarily well-formed +struct Sendable(T); +type MySendable = Sendable; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1 = U::Assoc; +//~^ WARN bounds on generic parameters are not enforced in type aliases +type T2 where U: Bound = U::Assoc; +//~^ WARN where clauses are not enforced in type aliases +type T3 = U::Assoc; +//~^ ERROR associated type `Assoc` not found for `U` +type T4 = ::Assoc; + fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 5237f3c19efcd..46aacd7321ccb 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -1,32 +1,53 @@ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:18:14 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:17:14 | LL | type SVec = Vec; | ^^^^ ^^^^ | - = note: #[warn(ignored_generic_bounds)] on by default + = note: #[warn(type_alias_bounds)] on by default -warning: where clauses are ignored in type aliases - --> $DIR/type-alias-bounds.rs:20:21 +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:19:21 | LL | type S2Vec where T: Send = Vec; | ^^^^^^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:22:19 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:21:19 | LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); | ^^ ^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:24:18 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:23:18 | LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); | ^^ ^^ -warning: where clauses are ignored in type aliases - --> $DIR/type-alias-bounds.rs:26:25 +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:25:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); | ^^^^^ ^^^^^ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:56:12 + | +LL | type T1 = U::Assoc; + | ^^^^^ + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:58:18 + | +LL | type T2 where U: Bound = U::Assoc; + | ^^^^^^^^ + +error[E0220]: associated type `Assoc` not found for `U` + --> $DIR/type-alias-bounds.rs:60:14 + | +LL | type T3 = U::Assoc; + | ^^^^^^^^ associated type `Assoc` not found + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0220" From 0e6d40a3fb1000d1105646703c60c9201f3ed5cc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 13:32:11 +0100 Subject: [PATCH 020/546] type_alias_bounds lint: If the type alias uses an associated type without "as", suggest to use the "as" form instead. This is necessary to get rid of the type bound, and hence silence the warning. --- src/librustc/hir/mod.rs | 19 +++++++ src/librustc_lint/builtin.rs | 83 +++++++++++++++++++++++++--- src/librustc_lint/lib.rs | 2 +- src/test/ui/type-alias-bounds.rs | 17 ++++-- src/test/ui/type-alias-bounds.stderr | 58 ++++++++++++++----- 5 files changed, 150 insertions(+), 29 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f4638c23c5f4b..d4bfa7a1d308c 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -395,6 +395,15 @@ pub enum TyParamBound { RegionTyParamBound(Lifetime), } +impl TyParamBound { + pub fn span(&self) -> Span { + match self { + &TraitTyParamBound(ref t, ..) => t.span, + &RegionTyParamBound(ref l) => l.span, + } + } +} + /// A modifier on a bound, currently this is only used for `?Sized`, where the /// modifier is `Maybe`. Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -570,6 +579,16 @@ pub enum WherePredicate { EqPredicate(WhereEqPredicate), } +impl WherePredicate { + pub fn span(&self) -> Span { + match self { + &WherePredicate::BoundPredicate(ref p) => p.span, + &WherePredicate::RegionPredicate(ref p) => p.span, + &WherePredicate::EqPredicate(ref p) => p.span, + } + } +} + /// A type bound, eg `for<'c> Foo: Send+Clone+'c` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereBoundPredicate { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index bdb36ab15b624..2ea13b2cb6d68 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,6 +46,7 @@ use syntax::attr; use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::keywords; +use syntax::errors::DiagnosticBuilder; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::FnKind; @@ -1334,31 +1335,97 @@ impl LintPass for TypeAliasBounds { } } -impl EarlyLintPass for TypeAliasBounds { - fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { - let type_alias_generics = match item.node { - ast::ItemKind::Ty(_, ref generics) => generics, +impl TypeAliasBounds { + fn is_type_variable_assoc(qpath: &hir::QPath) -> bool { + match *qpath { + hir::QPath::TypeRelative(ref ty, _) => { + // If this is a type variable, we found a `T::Assoc`. + match ty.node { + hir::TyPath(hir::QPath::Resolved(None, ref path)) => { + match path.def { + Def::TyParam(_) => true, + _ => false + } + } + _ => false + } + } + hir::QPath::Resolved(..) => false, + } + } + + fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) { + // Access to associates types should use `::Assoc`, which does not need a + // bound. Let's see of this type does that. + + // We use an AST visitor to walk the type. + use rustc::hir::intravisit::{self, Visitor}; + use syntax::ast::NodeId; + struct WalkAssocTypes<'a, 'db> where 'db: 'a { + err: &'a mut DiagnosticBuilder<'db> + } + impl<'a, 'db, 'v> Visitor<'v> for WalkAssocTypes<'a, 'db> { + fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> + { + intravisit::NestedVisitorMap::None + } + + fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) { + if TypeAliasBounds::is_type_variable_assoc(qpath) { + self.err.span_help(span, + "use absolute paths (i.e., ::Assoc) to refer to associated \ + types in type aliases"); + } + intravisit::walk_qpath(self, qpath, id, span) + } + } + + // Let's go for a walk! + let mut visitor = WalkAssocTypes { err }; + visitor.visit_ty(ty); + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { + fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + let (ty, type_alias_generics) = match item.node { + hir::ItemTy(ref ty, ref generics) => (&*ty, generics), _ => return, }; + let mut suggested_changing_assoc_types = false; // There must not be a where clause if !type_alias_generics.where_clause.predicates.is_empty() { let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter() .map(|pred| pred.span()).collect(); - cx.span_lint(TYPE_ALIAS_BOUNDS, spans, + let mut err = cx.struct_span_lint(TYPE_ALIAS_BOUNDS, spans, "where clauses are not enforced in type aliases"); + err.help("the clause will not be checked when the type alias is used, \ + and should be removed"); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + suggested_changing_assoc_types = true; + } + err.emit(); } // The parameters must not have bounds for param in type_alias_generics.params.iter() { let spans : Vec<_> = match param { - &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(), - &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(), + &hir::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(), + &hir::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(), }; if !spans.is_empty() { - cx.span_lint( + let mut err = cx.struct_span_lint( TYPE_ALIAS_BOUNDS, spans, "bounds on generic parameters are not enforced in type aliases", ); + err.help("the bound will not be checked when the type alias is used, \ + and should be removed"); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + suggested_changing_assoc_types = true; + } + err.emit(); } } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 38f7a0b6faa0f..7237d2fd5d1c9 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -109,7 +109,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedImportBraces, AnonymousParameters, UnusedDocComment, - TypeAliasBounds, ); add_early_builtin_with_new!(sess, @@ -139,6 +138,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { MutableTransmutes, UnionsWithDropFields, UnreachablePub, + TypeAliasBounds, ); add_builtin_with_new!(sess, diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs index 7ec3afd9c870a..c1cdeef3a4638 100644 --- a/src/test/ui/type-alias-bounds.rs +++ b/src/test/ui/type-alias-bounds.rs @@ -10,6 +10,7 @@ // Test ignored_generic_bounds lint warning about bounds in type aliases +// must-compile-successfully #![allow(dead_code)] use std::rc::Rc; @@ -53,12 +54,16 @@ type MySendable = Sendable; // no error here! // However, bounds *are* taken into account when accessing associated types trait Bound { type Assoc; } -type T1 = U::Assoc; -//~^ WARN bounds on generic parameters are not enforced in type aliases -type T2 where U: Bound = U::Assoc; -//~^ WARN where clauses are not enforced in type aliases -type T3 = U::Assoc; -//~^ ERROR associated type `Assoc` not found for `U` +type T1 = U::Assoc; //~ WARN not enforced in type aliases +type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + +// This errors +// type T3 = U::Assoc; +// Do this instead type T4 = ::Assoc; +// Make sure the help about associatd types is not shown incorrectly +type T5 = ::Assoc; //~ WARN not enforced in type aliases +type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases + fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 46aacd7321ccb..5288dca79be68 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -1,53 +1,83 @@ warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:17:14 + --> $DIR/type-alias-bounds.rs:18:14 | LL | type SVec = Vec; | ^^^^ ^^^^ | = note: #[warn(type_alias_bounds)] on by default + = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:19:21 + --> $DIR/type-alias-bounds.rs:20:21 | LL | type S2Vec where T: Send = Vec; | ^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:21:19 + --> $DIR/type-alias-bounds.rs:22:19 | LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); | ^^ ^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:23:18 + --> $DIR/type-alias-bounds.rs:24:18 | LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); | ^^ ^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:25:25 + --> $DIR/type-alias-bounds.rs:26:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); | ^^^^^ ^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:56:12 + --> $DIR/type-alias-bounds.rs:57:12 | -LL | type T1 = U::Assoc; +LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed +help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:57:21 + | +LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases + | ^^^^^^^^ warning: where clauses are not enforced in type aliases --> $DIR/type-alias-bounds.rs:58:18 | -LL | type T2 where U: Bound = U::Assoc; +LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed +help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:58:29 + | +LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + | ^^^^^^^^ -error[E0220]: associated type `Assoc` not found for `U` - --> $DIR/type-alias-bounds.rs:60:14 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:66:12 + | +LL | type T5 = ::Assoc; //~ WARN not enforced in type aliases + | ^^^^^ | -LL | type T3 = U::Assoc; - | ^^^^^^^^ associated type `Assoc` not found + = help: the bound will not be checked when the type alias is used, and should be removed -error: aborting due to previous error +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:67:12 + | +LL | type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases + | ^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed -If you want more information on this error, try using "rustc --explain E0220" From 908328fca03c1bf69ce335974f4dcabd8e5d18f4 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 11 Mar 2018 07:41:13 -0400 Subject: [PATCH 021/546] Document when types have OS-dependent sizes As per issue #43601, types that can change size depending on the target operating system should say so in their documentation. I used this template when adding doc comments: The size of a(n) struct may vary depending on the target operating system, and may change between Rust releases. For enums, I used "instance" instead of "struct". --- src/libstd/io/stdio.rs | 9 +++++++++ src/libstd/net/addr.rs | 9 +++++++++ src/libstd/net/ip.rs | 9 +++++++++ src/libstd/time.rs | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 1f73054e3beed..4565b7fa0d6f2 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -30,18 +30,27 @@ thread_local! { /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdin_raw` function. +/// +/// The size of a StdinRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdout_raw` function. +/// +/// The size of a StdoutRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stderr_raw` function. +/// +/// The size of a StderrRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index fa430939f058c..75b050638392e 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -28,6 +28,9 @@ use slice; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// +/// The size of a SocketAddr instance may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IP address]: ../../std/net/enum.IpAddr.html /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html @@ -61,6 +64,9 @@ pub enum SocketAddr { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a SocketAddrV4 struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html @@ -88,6 +94,9 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a SocketAddrV6 struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0d73a6f4fd7f4..36a34e147d558 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -26,6 +26,9 @@ use sys_common::{AsInner, FromInner}; /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their /// respective documentation for more details. /// +/// The size of an IpAddr instance may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html /// @@ -61,6 +64,9 @@ pub enum IpAddr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an Ipv4Addr struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// @@ -93,6 +99,9 @@ pub struct Ipv4Addr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an Ipv6Addr struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 12f2a9bb85f83..054450a518629 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -49,6 +49,9 @@ pub use core::time::Duration; /// allows measuring the duration between two instants (or comparing two /// instants). /// +/// The size of an Instant struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// Example: /// /// ```no_run @@ -88,6 +91,9 @@ pub struct Instant(time::Instant); /// fixed point in time, a `SystemTime` can be converted to a human-readable time, /// or perhaps some other string representation. /// +/// The size of a SystemTime struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [`Instant`]: ../../std/time/struct.Instant.html /// [`Result`]: ../../std/result/enum.Result.html /// [`Duration`]: ../../std/time/struct.Duration.html From e63b1a0e368e2f7d3bf5eadd1262dc530a38394b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 11 Mar 2018 17:17:18 -0400 Subject: [PATCH 022/546] Remove "and may change between Rust releases" --- src/libstd/io/stdio.rs | 6 +++--- src/libstd/net/addr.rs | 6 +++--- src/libstd/net/ip.rs | 6 +++--- src/libstd/time.rs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 4565b7fa0d6f2..9a4cde7e16286 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -32,7 +32,7 @@ thread_local! { /// the `std::io::stdio::stdin_raw` function. /// /// The size of a StdinRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. @@ -41,7 +41,7 @@ struct StdinRaw(stdio::Stdin); /// the `std::io::stdio::stdout_raw` function. /// /// The size of a StdoutRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. @@ -50,7 +50,7 @@ struct StdoutRaw(stdio::Stdout); /// the `std::io::stdio::stderr_raw` function. /// /// The size of a StderrRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 75b050638392e..f985c1f2bc8ce 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -29,7 +29,7 @@ use slice; /// [`SocketAddrV6`]'s respective documentation for more details. /// /// The size of a SocketAddr instance may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IP address]: ../../std/net/enum.IpAddr.html /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html @@ -65,7 +65,7 @@ pub enum SocketAddr { /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a SocketAddrV4 struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html @@ -95,7 +95,7 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a SocketAddrV6 struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 36a34e147d558..67b9e7a2f9d6f 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -27,7 +27,7 @@ use sys_common::{AsInner, FromInner}; /// respective documentation for more details. /// /// The size of an IpAddr instance may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html @@ -65,7 +65,7 @@ pub enum IpAddr { /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// /// The size of an Ipv4Addr struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html @@ -100,7 +100,7 @@ pub struct Ipv4Addr { /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// /// The size of an Ipv6Addr struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 054450a518629..4e08301fe05b9 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -50,7 +50,7 @@ pub use core::time::Duration; /// instants). /// /// The size of an Instant struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// Example: /// @@ -92,7 +92,7 @@ pub struct Instant(time::Instant); /// or perhaps some other string representation. /// /// The size of a SystemTime struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [`Instant`]: ../../std/time/struct.Instant.html /// [`Result`]: ../../std/result/enum.Result.html From 68d6eddaf8e1d34c1fa44f60463b70c81b277665 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sun, 18 Feb 2018 18:01:33 +0100 Subject: [PATCH 023/546] Some comments and documentation for name resolution crate --- src/librustc_resolve/lib.rs | 45 ++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 317bd9217b591..cb2c206c69b16 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -162,6 +162,10 @@ enum ResolutionError<'a> { ForwardDeclaredTyParam, } +/// Combines an error with provided span and emits it +/// +/// This takes the error provided, combines it with the span and any additional spans inside the +/// error and emits it. fn resolve_error<'sess, 'a>(resolver: &'sess Resolver, span: Span, resolution_error: ResolutionError<'a>) { @@ -364,7 +368,7 @@ struct BindingInfo { binding_mode: BindingMode, } -// Map from the name in a pattern to its binding mode. +/// Map from the name in a pattern to its binding mode. type BindingMap = FxHashMap; #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -559,6 +563,9 @@ impl<'a> PathSource<'a> { } } +/// Different kinds of symbols don't influence each other. +/// +/// Therefore, they have a separate universe (namespace). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Namespace { TypeNS, @@ -566,6 +573,7 @@ pub enum Namespace { MacroNS, } +/// Just a helper ‒ separate structure for each namespace. #[derive(Clone, Default, Debug)] pub struct PerNS { value_ns: T, @@ -662,6 +670,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { } } +/// This thing walks the whole crate in DFS manner, visiting each item, resolving names as it goes. impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { fn visit_item(&mut self, item: &'tcx Item) { self.resolve_item(item); @@ -788,7 +797,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { fn visit_generics(&mut self, generics: &'tcx Generics) { // For type parameter defaults, we have to ban access // to following type parameters, as the Substs can only - // provide previous type parameters as they're built. + // provide previous type parameters as they're built. We + // put all the parameters on the ban list and then remove + // them one by one as they are processed and become available. let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind); default_ban_rib.bindings.extend(generics.params.iter() .filter_map(|p| if let GenericParam::Type(ref tp) = *p { Some(tp) } else { None }) @@ -864,6 +875,16 @@ enum RibKind<'a> { } /// One local scope. +/// +/// A rib represents a scope names can live in. Note that these appear in many places, not just +/// around braces. At any place where the list of accessible names (of the given namespace) +/// changes, a new rib is put onto a stack. This may be, for example, a `let` statement (because it +/// introduces variables), a macro, etc. +/// +/// Different [rib kinds](enum.RibKind) are transparent for different names. +/// +/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When +/// resolving, the name is looked up from inside out. #[derive(Debug)] struct Rib<'a> { bindings: FxHashMap, @@ -879,6 +900,11 @@ impl<'a> Rib<'a> { } } +/// An intermediate resolution result. +/// +/// This refers to the thing referred by a name. The difference between `Def` and `Item` is that +/// items are visible in their whole block, while defs only from the place they are defined +/// forward. enum LexicalScopeBinding<'a> { Item(&'a NameBinding<'a>), Def(Def), @@ -909,7 +935,11 @@ enum PathResult<'a> { } enum ModuleKind { + /// Inline `mod something { ... }`. Block(NodeId), + /// Module from another file. + /// + /// Also called a normal module in the following code. Def(Def, Name), } @@ -1194,6 +1224,9 @@ impl<'a> NameBinding<'a> { } /// Interns the names of the primitive types. +/// +/// All other types are defined somewhere and possibly imported, but the primitive ones need +/// special handling, since they have no place of origin. struct PrimitiveTypeTable { primitive_types: FxHashMap, } @@ -1228,6 +1261,8 @@ impl PrimitiveTypeTable { } /// The main resolver class. +/// +/// This is the visitor that walks the whole crate. pub struct Resolver<'a> { session: &'a Session, cstore: &'a CrateStore, @@ -1359,6 +1394,7 @@ pub struct Resolver<'a> { injected_crate: Option>, } +/// Nothing really interesting here, it just provides memory for the rest of the crate. pub struct ResolverArenas<'a> { modules: arena::TypedArena>, local_modules: RefCell>>, @@ -1404,10 +1440,12 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, _ => self.cstore.def_key(id).parent, - }.map(|index| DefId { index: index, ..id }) + }.map(|index| DefId { index, ..id }) } } +/// This is the interface through which the rest of the compiler asks about name resolution after +/// the whole AST has been indexed. impl<'a> hir::lowering::Resolver for Resolver<'a> { fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { self.resolve_hir_path_cb(path, is_value, @@ -1630,6 +1668,7 @@ impl<'a> Resolver<'a> { } } + /// Runs the function on each namespace. fn per_ns T>(&mut self, mut f: F) -> PerNS { PerNS { type_ns: f(self, TypeNS), From c685b57bf27d3ddecd83ab77e1973d36dff755b4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 12 Mar 2018 17:16:21 -0500 Subject: [PATCH 024/546] add page to the Rustdoc Book about unstable features --- src/doc/rustdoc/src/SUMMARY.md | 1 + src/doc/rustdoc/src/unstable-features.md | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/doc/rustdoc/src/unstable-features.md diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md index 6315cb81a8495..46528187c1175 100644 --- a/src/doc/rustdoc/src/SUMMARY.md +++ b/src/doc/rustdoc/src/SUMMARY.md @@ -5,3 +5,4 @@ - [The `#[doc]` attribute](the-doc-attribute.md) - [Documentation tests](documentation-tests.md) - [Passes](passes.md) +- [Unstable features](unstable-features.md) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md new file mode 100644 index 0000000000000..35380cdf069ed --- /dev/null +++ b/src/doc/rustdoc/src/unstable-features.md @@ -0,0 +1,10 @@ +# Unstable features + +Rustdoc is under active developement, and like the Rust compiler, some features are only available +on the nightly releases. Some of these are new and need some more testing before they're able to get +released to the world at large, and some of them are tied to features in the Rust compiler that are +themselves unstable. Several features here require a matching `#![feature(...)]` attribute to +enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over +there as necessary. + +[Unstable Book]: ../unstable-book/ From 373b2cdcd13788249e27d7f06f5c36f37bc8684e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 12 Mar 2018 17:26:20 -0500 Subject: [PATCH 025/546] talk about error numbers for compile_fail doctests --- src/doc/rustdoc/src/unstable-features.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 35380cdf069ed..8dbd0aa9a9a1f 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -8,3 +8,26 @@ enable, and thus are more fully documented in the [Unstable Book]. Those section there as necessary. [Unstable Book]: ../unstable-book/ + +## Error numbers for `compile-fail` doctests + +As detailed in [the chapter on documentation tests][doctest-attributes], you can add a +`compile_fail` attribute to a doctest to state that the test should fail to compile. However, on +nightly, you can optionally add an error number to state that a doctest should emit a specific error +number: + +[doctest-attributes]: documentation-tests.html#attributes + +``````markdown +```compile_fail,E0044 +extern { fn some_func(x: T); } +``` +`````` + +This is used by the error index to ensure that the samples that correspond to a given error number +properly emit that error code. However, these error codes aren't guaranteed to be the only thing +that a piece of code emits from version to version, so this in unlikely to be stabilized in the +future. + +Attempting to use these error numbers on stable will result in the code sample being interpreted as +plain text. From 30adb53f46628fa37042543359a269221350b6d7 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 13 Mar 2018 17:00:51 -0500 Subject: [PATCH 026/546] talk about intra-links --- src/doc/rustdoc/src/unstable-features.md | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 8dbd0aa9a9a1f..08cceff0e701f 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -31,3 +31,48 @@ future. Attempting to use these error numbers on stable will result in the code sample being interpreted as plain text. + +## Linking to items by type + +As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve +these type names, it uses the items currently in-scope, either by declaration or by `use` statement. +For modules, the "active scope" depends on whether the documentation is written outside the module +(as `///` comments on the `mod` statement) or inside the module (at `//!` comments inside the file +or block). For all other items, it uses the enclosing module's scope. + +[RFC 1946]: https://github.com/rust-lang/rfcs/pull/1946 + +For example, in the following code: + +```rust +/// Does the thing. +pub fn do_the_thing(_: SomeType) { + println!("Let's do the thing!"); +} + +/// Token you use to [`do_the_thing`]. +pub struct SomeType; +``` + +The link to ``[`do_the_thing`]`` in `SomeType`'s docs will properly link to the page for `fn +do_the_thing`. Note that here, rustdoc will insert the link target for you, but manually writing the +target out also works: + +```rust +pub mod some_module { + /// Token you use to do the thing. + pub struct SomeStruct; +} + +/// Does the thing. Requires one [`SomeStruct`] for the thing to work. +/// +/// [`SomeStruct`]: some_module::SomeStruct +pub fn do_the_thing(_: some_module::SomeStruct) { + println!("Let's do the thing!"); +} +``` + +For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43466] for more +information about what parts of the feature are available. + +[43466]: https://github.com/rust-lang/rust/issues/43466 From f83618b9dac3b92b554d3751dcdea9aeefc6e72a Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Wed, 14 Mar 2018 14:31:23 +0000 Subject: [PATCH 027/546] Update RELEASES.md --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 1b2097144d718..e6f6e0440839d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -60,6 +60,8 @@ Cargo Misc ---- +- [Rust by example is now shipped with new releases][46196] + Compatibility Notes ------------------- - [Deprecated `net::lookup_host`.][47510] @@ -90,6 +92,7 @@ Compatibility Notes [46830]: https://github.com/rust-lang/rust/pull/46830 [46095]: https://github.com/rust-lang/rust/pull/46095 [46666]: https://github.com/rust-lang/rust/pull/46666 +[46196]: https://github.com/rust-lang/rust/pull/46196 [cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 [cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 [RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 From 017bfc361170d43fb9f93e6fed535e1719a680b4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 5 Mar 2018 16:05:38 -0600 Subject: [PATCH 028/546] expose #[target_feature] attributes in rustdoc --- src/librustdoc/clean/cfg.rs | 40 +++++++++++++++++++++++++++++++++++-- src/librustdoc/clean/mod.rs | 13 ++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 5cac2d1bbe7ee..c228f54217d34 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -138,7 +138,7 @@ impl Cfg { /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { - let mut msg = Html(self).to_string(); + let mut msg = ShortHtml(self).to_string(); if self.should_capitalize_first_letter() { if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { msg[i .. i+1].make_ascii_uppercase(); @@ -149,7 +149,13 @@ impl Cfg { /// Renders the configuration for long display, as a long HTML description. pub(crate) fn render_long_html(&self) -> String { - let mut msg = format!("This is supported on {}", Html(self)); + let on = if self.should_use_with_in_description() { + "with" + } else { + "on" + }; + + let mut msg = format!("This is supported {} {}", on, Html(self)); if self.should_append_only_to_description() { msg.push_str(" only"); } @@ -180,6 +186,13 @@ impl Cfg { } } } + + fn should_use_with_in_description(&self) -> bool { + match *self { + Cfg::Cfg(ref name, _) if name == &"target_feature" => true, + _ => false, + } + } } impl ops::Not for Cfg { @@ -376,6 +389,8 @@ impl<'a> fmt::Display for Html<'a> { }, ("target_endian", Some(endian)) => return write!(fmt, "{}-endian", endian), ("target_pointer_width", Some(bits)) => return write!(fmt, "{}-bit", bits), + ("target_feature", Some(feat)) => + return write!(fmt, "target feature {}", feat), _ => "", }; if !human_readable.is_empty() { @@ -390,6 +405,19 @@ impl<'a> fmt::Display for Html<'a> { } } +struct ShortHtml<'a>(&'a Cfg); + +impl<'a> fmt::Display for ShortHtml<'a> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + Cfg::Cfg(ref name, Some(ref vendor)) if name == &"target_feature" => { + write!(fmt, "{}", vendor) + }, + ref cfg => write!(fmt, "{}", Html(cfg)), + } + } +} + #[cfg(test)] mod test { use super::Cfg; @@ -824,6 +852,10 @@ mod test { ).render_short_html(), "(Debug-assertions enabled or Windows) and Unix" ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_short_html(), + "sse2" + ); }) } @@ -898,6 +930,10 @@ mod test { "This is supported on (debug-assertions enabled or Windows) and Unix\ only." ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_long_html(), + "This is supported with target feature sse2 only." + ); }) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ff281a53ab7e4..d6897617d556e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -828,6 +828,19 @@ impl Attributes { }) }).collect(); + // treat #[target_feature(enable = "feat")] attributes as if they were + // #[doc(cfg(target_feature = "feat"))] attributes as well + for attr in attrs.lists("target_feature") { + if attr.check_name("enable") { + if let Some(feat) = attr.value_str() { + let meta = attr::mk_name_value_item_str("target_feature".into(), feat); + if let Ok(feat_cfg) = Cfg::parse(&meta) { + cfg &= feat_cfg; + } + } + } + } + Attributes { doc_strings, other_attrs, From 0f96e145fbe8c635e7a58fb17c8c46bc4e42d454 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 15:32:25 -0500 Subject: [PATCH 029/546] talk about doc(cfg) --- src/doc/rustdoc/src/unstable-features.md | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 08cceff0e701f..245d53e8b7964 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -76,3 +76,55 @@ For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43 information about what parts of the feature are available. [43466]: https://github.com/rust-lang/rust/issues/43466 + +## Documenting platform-/feature-specific information + +Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target +rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute +processing early in the compilation process. However, Rustdoc has a trick up its sleeve to handle +platform-specific code if it *does* receive it. + +Because Rustdoc doesn't need to fully compile a crate to binary, it replaces function bodies with +`loop {}` to prevent having to process more than necessary. This means that any code within a +function that requires platform-specific pieces is ignored. Combined with a special attribute, +`#[doc(cfg(...))]`, you can tell Rustdoc exactly which platform something is supposed to run on, +ensuring that doctests are only run on the appropriate platforms. + +The `#[doc(cfg(...))]` attribute has another effect: When Rustdoc renders documentation for that +item, it will be accompanied by a banner explaining that the item is only available on certain +platforms. + +As mentioned earlier, getting the items to Rustdoc requires some extra preparation. The standard +library adds a `--cfg dox` flag to every Rustdoc command, but the same thing can be accomplished by +adding a feature to your Cargo.toml and adding `--feature dox` (or whatever you choose to name the +feature) to your `cargo doc` calls. + +Either way, once you create an environment for the documentation, you can start to augment your +`#[cfg]` attributes to allow both the target platform *and* the documentation configuration to leave +the item in. For example, `#[cfg(any(windows, feature = "dox"))]` will preserve the item either on +Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` +will tell Rustdoc that the item is supposed to be used on Windows. For example: + +```rust +#![feature(doc_cfg)] + +/// Token struct that can only be used on Windows. +#[cfg(any(windows, feature = "dox"))] +#[doc(cfg(windows))] +pub struct WindowsToken; + +/// Token struct that can only be used on Unix. +#[cfg(any(unix, feature = "dox"))] +#[doc(cfg(unix))] +pub struct UnixToken; +``` + +In this sample, the tokens will only appear on their respective platforms, but they will both appear +in documentation. + +`#[doc(cfg(...))]` was introduced to be used by the standard library and is currently controlled by +a feature gate. For more information, see [its chapter in the Unstable Book][unstable-doc-cfg] and +[its tracking issue][issue-doc-cfg]. + +[unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html +[issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 From 23a1da4d637648ae37090f88be695de3a63cd507 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 16:06:53 -0500 Subject: [PATCH 030/546] talk about doc(spotlight) --- src/doc/rustdoc/src/unstable-features.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 245d53e8b7964..1670223952441 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -128,3 +128,23 @@ a feature gate. For more information, see [its chapter in the Unstable Book][uns [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 + +## Adding your trait to the "Important Traits" dialog + +Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when +implemented on it. These traits are intended to be the primary interface for their types, and are +often the only thing available to be documented on their types. For this reason, Rustdoc will track +when a given type implements one of these traits and call special attention to it when a function +returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next +to the function, which, when clicked, shows the dialog. + +In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and +`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a +special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this +attribute to your own trait to include it in the "Important Traits" dialog in documentation. + +The `#[doc(spotlight)]` attribute is controlled by a feature gate. For more information, see [its +chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue-spotlight]. + +[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html +[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 From 82bd146d60425c3cd0c99892742f1454f5eb8191 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 16:40:28 -0500 Subject: [PATCH 031/546] talk about doc(masked) --- src/doc/rustdoc/src/unstable-features.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 1670223952441..9f0476d4eef70 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -148,3 +148,23 @@ chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 + +## Exclude certain dependencies from documentation + +The standard library uses several dependencies which, in turn, use several types and traits from the +standard library. In addition, there are several compiler-internal crates that are not considered to +be part of the official standard library, and thus would be a distraction to include in +documentation. It's not enough to exclude their crate documentation, since information about trait +implementations appears on the pages for both the type and the trait, which can be in different +crates! + +To prevent internal types from being included in documentation, the standard library adds an +attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" +types from these crates when building lists of trait implementations. + +The `#[doc(masked)]` attribute is intended to be used internally, and is governed by a feature gate. +For more information, see [its chapter in the Unstable Book][unstable-masked] and [its tracking +issue][issue-masked]. + +[unstable-masked]: ../unstable-book/language-features/doc-masked.html +[issue-masked]: https://github.com/rust-lang/rust/issues/44027 From 067553d5a1d867c7f8404153ce37a4008489b82a Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 17:13:52 -0500 Subject: [PATCH 032/546] talk about doc(include) --- src/doc/rustdoc/src/unstable-features.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 9f0476d4eef70..62112fbf293c0 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -162,9 +162,25 @@ To prevent internal types from being included in documentation, the standard lib attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" types from these crates when building lists of trait implementations. -The `#[doc(masked)]` attribute is intended to be used internally, and is governed by a feature gate. -For more information, see [its chapter in the Unstable Book][unstable-masked] and [its tracking -issue][issue-masked]. +The `#[doc(masked)]` attribute is intended to be used internally, and is controlled by a feature +gate. For more information, see [its chapter in the Unstable Book][unstable-masked] and [its +tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 + +## Include external files as API documentation + +As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This +is useful if certain documentation is so long that it would break the flow of reading the source. +Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` (where `sometype.md` is +a file adjacent to the `lib.rs` for the crate) will ask Rustdoc to instead read that file and use it +as if it were written inline. + +[RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 + +`#[doc(include = "...")]` is currently controlled by a feature gate. For more information, see [its +chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-include]. + +[unstable-include]: ../unstable-book/language-features/external-doc.html +[issue-include]: https://github.com/rust-lang/rust/issues/44732 From 3d90b4d73880f7f7146a31544ac414e85014ca6f Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 17:22:15 -0500 Subject: [PATCH 033/546] add headings to categorize the features --- src/doc/rustdoc/src/unstable-features.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 62112fbf293c0..5f9978c61b6e4 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -9,7 +9,14 @@ there as necessary. [Unstable Book]: ../unstable-book/ -## Error numbers for `compile-fail` doctests +## Nightly-gated functionality + +These features just require a nightly build to operate. Unlike the other features on this page, +these don't need to be "turned on" with a command-line flag or a `#![feature(...)]` attribute in +your crate. This can give them some subtle fallback modes when used on a stable release, so be +careful! + +### Error numbers for `compile-fail` doctests As detailed in [the chapter on documentation tests][doctest-attributes], you can add a `compile_fail` attribute to a doctest to state that the test should fail to compile. However, on @@ -32,7 +39,7 @@ future. Attempting to use these error numbers on stable will result in the code sample being interpreted as plain text. -## Linking to items by type +### Linking to items by type As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve these type names, it uses the items currently in-scope, either by declaration or by `use` statement. @@ -77,7 +84,12 @@ information about what parts of the feature are available. [43466]: https://github.com/rust-lang/rust/issues/43466 -## Documenting platform-/feature-specific information +## Extensions to the `#[doc]` attribute + +These features operate by extending the `#[doc]` attribute, and thus can be caught by the compiler +and enabled with a `#![feature(...)]` attribute in your crate. + +### Documenting platform-/feature-specific information Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute @@ -129,7 +141,7 @@ a feature gate. For more information, see [its chapter in the Unstable Book][uns [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 -## Adding your trait to the "Important Traits" dialog +### Adding your trait to the "Important Traits" dialog Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when implemented on it. These traits are intended to be the primary interface for their types, and are @@ -149,7 +161,7 @@ chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 -## Exclude certain dependencies from documentation +### Exclude certain dependencies from documentation The standard library uses several dependencies which, in turn, use several types and traits from the standard library. In addition, there are several compiler-internal crates that are not considered to @@ -169,7 +181,7 @@ tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 -## Include external files as API documentation +### Include external files as API documentation As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This is useful if certain documentation is so long that it would break the flow of reading the source. From 4647156985404f07dc2e61eed6f2e24770b339a9 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 15 Mar 2018 12:35:56 +0800 Subject: [PATCH 034/546] replace `convert::Infallible` with `!` --- src/libcore/convert.rs | 21 +-------------------- src/libcore/num/mod.rs | 18 +++++------------- src/libstd/error.rs | 9 --------- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index d3a83dc795c85..a45f1ceab5ab2 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -48,25 +48,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use fmt; - -/// A type used as the error type for implementations of fallible conversion -/// traits in cases where conversions cannot actually fail. -/// -/// Because `Infallible` has no variants, a value of this type can never exist. -/// It is used only to satisfy trait signatures that expect an error type, and -/// signals to both the compiler and the user that the error case is impossible. -#[unstable(feature = "try_from", issue = "33417")] -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub enum Infallible {} - -#[unstable(feature = "try_from", issue = "33417")] -impl fmt::Display for Infallible { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - match *self { - } - } -} /// A cheap reference-to-reference conversion. Used to convert a value to a /// reference value within generic code. /// @@ -438,7 +419,7 @@ impl TryInto for T where U: TryFrom // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] impl TryFrom for T where T: From { - type Error = Infallible; + type Error = !; fn try_from(value: U) -> Result { Ok(T::from(value)) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ab7060d37db..faeb87cf944c9 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -12,7 +12,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use convert::{Infallible, TryFrom}; +use convert::TryFrom; use fmt; use intrinsics; use ops; @@ -3595,20 +3595,12 @@ impl fmt::Display for TryFromIntError { } } -#[unstable(feature = "try_from", issue = "33417")] -impl From for TryFromIntError { - fn from(infallible: Infallible) -> TryFromIntError { - match infallible { - } - } -} - // no possible bounds violation macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$source> for $target { - type Error = Infallible; + type Error = !; #[inline] fn try_from(value: $source) -> Result { @@ -3719,7 +3711,7 @@ try_from_lower_bounded!(isize, usize); #[cfg(target_pointer_width = "16")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8); try_from_unbounded!(usize, u16, u32, u64, u128); @@ -3745,7 +3737,7 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "32")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16); try_from_unbounded!(usize, u32, u64, u128); @@ -3771,7 +3763,7 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "64")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16, u32); try_from_unbounded!(usize, u64, u128); diff --git a/src/libstd/error.rs b/src/libstd/error.rs index f8dbe193fed27..79bb6af168fa0 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -56,7 +56,6 @@ use any::TypeId; use borrow::Cow; use cell; use char; -use convert; use core::array; use fmt::{self, Debug, Display}; use mem::transmute; @@ -371,14 +370,6 @@ impl Error for char::ParseCharError { } } -#[unstable(feature = "try_from", issue = "33417")] -impl Error for convert::Infallible { - fn description(&self) -> &str { - match *self { - } - } -} - // copied from any.rs impl Error + 'static { /// Returns true if the boxed type is the same as `T` From c24a58c87c41f17e341cb165f990ef2fd5ec3cb5 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 09:29:54 -0500 Subject: [PATCH 035/546] fix link --- src/doc/rustdoc/src/unstable-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 5f9978c61b6e4..243d607376783 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -7,7 +7,7 @@ themselves unstable. Several features here require a matching `#![feature(...)]` enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over there as necessary. -[Unstable Book]: ../unstable-book/ +[Unstable Book]: ../unstable-book/index.html ## Nightly-gated functionality From 43ed37711e98585178cc291283b9b3345448f311 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 09:33:57 -0500 Subject: [PATCH 036/546] add new section about CLI flags --- src/doc/rustdoc/src/unstable-features.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 243d607376783..837a55f371fb5 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -196,3 +196,10 @@ chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-i [unstable-include]: ../unstable-book/language-features/external-doc.html [issue-include]: https://github.com/rust-lang/rust/issues/44732 + +## Unstable command-line arguments + +These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are +themselves marked as unstable. To use any of these options, pass `-Z unstable-options` as well as +the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the +`RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. From bb328237fc68fcc9c0495b283da74f8ec361b371 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 12:47:26 -0500 Subject: [PATCH 037/546] talk about --markdown-(before|after)-content --- src/doc/rustdoc/src/unstable-features.md | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 837a55f371fb5..873aebfc77779 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -203,3 +203,31 @@ These features are enabled by passing a command-line flag to Rustdoc, but the fl themselves marked as unstable. To use any of these options, pass `-Z unstable-options` as well as the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the `RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. + +### `--markdown-before-content`: include rendered Markdown before the content + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --markdown-before-content extra.md +$ rustdoc README.md -Z unstable-options --markdown-before-content extra.md +``` + +Just like `--html-before-content`, this allows you to insert extra content inside the `` tag +but before the other content `rustdoc` would normally produce in the rendered documentation. +However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a +Markdown renderer before inserting the result into the file. + +### `--markdown-after-content`: include rendered Markdown after the content + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --markdown-after-content extra.md +$ rustdoc README.md -Z unstable-options --markdown-after-content extra.md +``` + +Just like `--html-after-content`, this allows you to insert extra content before the `` tag +but after the other content `rustdoc` would normally produce in the rendered documentation. +However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a +Markdown renderer before inserting the result into the file. From 5d8443aeb1bf441897efddfc1246377f0d51149d Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 14:44:17 -0500 Subject: [PATCH 038/546] talk about --playground-url --- src/doc/rustdoc/src/unstable-features.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 873aebfc77779..9cb5760ec3797 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -231,3 +231,26 @@ Just like `--html-after-content`, this allows you to insert extra content before but after the other content `rustdoc` would normally produce in the rendered documentation. However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a Markdown renderer before inserting the result into the file. + +### `--playground-url`: control the location of the playground + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --playground-url https://play.rust-lang.org/ +``` + +When rendering a crate's docs, this flag gives the base URL of the Rust Playground, to use for +generating `Run` buttons. Unlike `--markdown-playground-url`, this argument works for standalone +Markdown files *and* Rust crates. This works the same way as adding `#![doc(html_playground_url = +"url")]` to your crate root, as mentioned in [the chapter about the `#[doc]` +attribute][doc-playground]. Please be aware that the official Rust Playground at +https://play.rust-lang.org does not have every crate available, so if your examples require your +crate, make sure the playground you provide has your crate available. + +[doc-playground]: the-doc-attribute.html#html_playground_url + +If both `--playground-url` and `--markdown-playground-url` are present when rendering a standalone +Markdown file, the URL given to `--markdown-playground-url` will take precedence. If both +`--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, +the attribute will take precedence. From 450d35f582a100e25a394a188c34c283c837087e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 7 Mar 2018 19:37:18 -0500 Subject: [PATCH 039/546] Remove unused fields Related to #46753 --- src/librustc_typeck/check/wfcheck.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b94af0a1e0081..edb4ebb6284e9 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -28,7 +28,6 @@ use rustc::hir; pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - code: ObligationCauseCode<'tcx>, } /// Helper type of a temporary returned by .for_item(...). @@ -36,7 +35,6 @@ pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>, - code: ObligationCauseCode<'gcx>, id: ast::NodeId, span: Span, param_env: ty::ParamEnv<'tcx>, @@ -47,7 +45,6 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec> { - let code = self.code.clone(); let id = self.id; let span = self.span; let param_env = self.param_env; @@ -55,7 +52,6 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { let fcx = FnCtxt::new(&inh, param_env, id); let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { tcx: fcx.tcx.global_tcx(), - code, }); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); @@ -68,7 +64,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { -> CheckTypeWellFormedVisitor<'a, 'gcx> { CheckTypeWellFormedVisitor { tcx, - code: ObligationCauseCode::MiscObligation } } @@ -165,7 +160,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { item_id: ast::NodeId, span: Span, sig_if_method: Option<&hir::MethodSig>) { - let code = self.code.clone(); + let code = ObligationCauseCode::MiscObligation; self.for_id(item_id, span).with_fcx(|fcx, this| { let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); @@ -213,7 +208,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let def_id = self.tcx.hir.local_def_id(id); CheckWfFcxBuilder { inherited: Inherited::build(self.tcx, def_id), - code: self.code.clone(), id, span, param_env: self.tcx.param_env(def_id), @@ -265,7 +259,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // All field types must be well-formed. for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, this.code.clone()) + fcx.register_wf_obligation(field.ty, field.span, ObligationCauseCode::MiscObligation) } } @@ -300,11 +294,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { { debug!("check_item_type: {:?}", item); - self.for_item(item).with_fcx(|fcx, this| { + self.for_item(item).with_fcx(|fcx, _this| { let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); let item_ty = fcx.normalize_associated_types_in(item.span, &ty); - fcx.register_wf_obligation(item_ty, item.span, this.code.clone()); + fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); vec![] // no implied bounds in a const etc }); @@ -339,7 +333,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { None => { let self_ty = fcx.tcx.type_of(item_def_id); let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, this.code.clone()); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, ObligationCauseCode::MiscObligation); } } @@ -374,7 +368,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // parameter includes another (e.g., ). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), self.code.clone()); + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), ObligationCauseCode::MiscObligation); } } @@ -458,11 +452,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); for input_ty in sig.inputs() { - fcx.register_wf_obligation(&input_ty, span, self.code.clone()); + fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output(), span, self.code.clone()); + fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); From 86a123c2fd018905fca7af94a352227fe97e1623 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 9 Mar 2018 22:35:15 -0500 Subject: [PATCH 040/546] Queryify check_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 2 ++ src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++ src/librustc_typeck/check/wfcheck.rs | 50 ++++++++++++++++++++-------- 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 8d7fef90b754e..20c3fb501572c 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -579,6 +579,7 @@ define_dep_nodes!( <'tcx> [] GetPanicStrategy(CrateNum), [] IsNoBuiltins(CrateNum), [] ImplDefaultness(DefId), + [] CheckItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index c1783654effef..8f4100ad5f703 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -298,6 +298,8 @@ define_maps! { <'tcx> [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, + [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), + // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. // diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index bc7186f781a82..732c91ea98aa6 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -871,6 +871,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); } DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); } DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } + DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc9455487ede7..a6b307b841490 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -718,6 +718,10 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum })?) } +fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -725,6 +729,7 @@ pub fn provide(providers: &mut Providers) { has_typeck_tables, adt_destructor, used_trait_imports, + check_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index edb4ebb6284e9..d665e55898d4a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -26,7 +26,7 @@ use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { +pub struct CheckTypeWellFormed<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } @@ -43,14 +43,14 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { fn with_fcx(&'tcx mut self, f: F) where F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, - &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec> + &mut CheckTypeWellFormed<'b, 'gcx>) -> Vec> { let id = self.id; let span = self.span; let param_env = self.param_env; self.inherited.enter(|inh| { let fcx = FnCtxt::new(&inh, param_env, id); - let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { + let wf_tys = f(&fcx, &mut CheckTypeWellFormed { tcx: fcx.tcx.global_tcx(), }); fcx.select_all_obligations_or_error(); @@ -59,10 +59,10 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { +impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) - -> CheckTypeWellFormedVisitor<'a, 'gcx> { - CheckTypeWellFormedVisitor { + -> CheckTypeWellFormed<'a, 'gcx> { + CheckTypeWellFormed { tcx, } } @@ -78,11 +78,14 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { /// We do this check as a pre-pass before checking fn bodies because if these constraints are /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. - fn check_item_well_formed(&mut self, item: &hir::Item) { + pub fn check_item_well_formed(&mut self, def_id: DefId) { let tcx = self.tcx; + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let item = tcx.hir.expect_item(node_id); + debug!("check_item_well_formed(it.id={}, it.name={})", item.id, - tcx.item_path_str(tcx.hir.local_def_id(item.id))); + tcx.item_path_str(def_id)); match item.node { // Right now we check that every default trait implementation @@ -259,7 +262,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // All field types must be well-formed. for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, ObligationCauseCode::MiscObligation) + fcx.register_wf_obligation(field.ty, field.span, + ObligationCauseCode::MiscObligation) } } @@ -333,7 +337,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { None => { let self_ty = fcx.tcx.type_of(item_def_id); let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, + ObligationCauseCode::MiscObligation); } } @@ -368,7 +373,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // parameter includes another (e.g., ). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), + ObligationCauseCode::MiscObligation); } } @@ -642,6 +648,19 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { } } +pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, +} + +impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) + -> CheckTypeWellFormedVisitor<'a, 'gcx> { + CheckTypeWellFormedVisitor { + tcx, + } + } +} + impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { NestedVisitorMap::None @@ -649,7 +668,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { debug!("visit_item: {:?}", i); - self.check_item_well_formed(i); + let def_id = self.tcx.hir.local_def_id(i.id); + ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_item(self, i); } @@ -659,7 +679,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None }; - self.check_associated_item(trait_item.id, trait_item.span, method_sig); + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(trait_item.id, trait_item.span, method_sig); intravisit::walk_trait_item(self, trait_item) } @@ -669,7 +690,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { hir::ImplItemKind::Method(ref sig, _) => Some(sig), _ => None }; - self.check_associated_item(impl_item.id, impl_item.span, method_sig); + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(impl_item.id, impl_item.span, method_sig); intravisit::walk_impl_item(self, impl_item) } } From edbd02fd35ffd3724a415c05c21e4e4fc5575e1e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 10 Mar 2018 11:25:03 -0500 Subject: [PATCH 041/546] Queryify check_trait_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++++ src/librustc_typeck/check/wfcheck.rs | 20 ++++++++++++++------ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 20c3fb501572c..9cb59da47bd9f 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -580,6 +580,7 @@ define_dep_nodes!( <'tcx> [] IsNoBuiltins(CrateNum), [] ImplDefaultness(DefId), [] CheckItemWellFormed(DefId), + [] CheckTraitItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 8f4100ad5f703..3e20156047447 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -299,6 +299,7 @@ define_maps! { <'tcx> [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), + [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (), // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 732c91ea98aa6..2eba72a590e3a 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -872,6 +872,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); } DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } + DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a6b307b841490..9ffe029468d3e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -722,6 +722,10 @@ fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); } +fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -730,6 +734,7 @@ pub fn provide(providers: &mut Providers) { adt_destructor, used_trait_imports, check_item_well_formed, + check_trait_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d665e55898d4a..c80e0b8bba066 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -159,6 +159,18 @@ impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { } } + pub fn check_trait_item(&mut self, def_id: DefId) { + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let trait_item = self.tcx.hir.expect_trait_item(node_id); + + let method_sig = match trait_item.node { + hir::TraitItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(trait_item.id, trait_item.span, method_sig); + } + fn check_associated_item(&mut self, item_id: ast::NodeId, span: Span, @@ -675,12 +687,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); - let method_sig = match trait_item.node { - hir::TraitItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(trait_item.id, trait_item.span, method_sig); + let def_id = self.tcx.hir.local_def_id(trait_item.id); + ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_trait_item(self, trait_item) } From 4f1f389d06a32bc64e1f75b11a2a84c8e8ae9af5 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 10 Mar 2018 17:17:30 -0500 Subject: [PATCH 042/546] Queryify check_impl_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++++ src/librustc_typeck/check/wfcheck.rs | 19 +++++++++++++------ 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 9cb59da47bd9f..13cf7a9ec8f1e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -581,6 +581,7 @@ define_dep_nodes!( <'tcx> [] ImplDefaultness(DefId), [] CheckItemWellFormed(DefId), [] CheckTraitItemWellFormed(DefId), + [] CheckImplItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 3e20156047447..4dcd7c20c33d5 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -300,6 +300,7 @@ define_maps! { <'tcx> [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (), + [] fn check_impl_item_well_formed: CheckImplItemWellFormed(DefId) -> (), // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 2eba72a590e3a..267d7da5e0c25 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -873,6 +873,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); } + DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9ffe029468d3e..5b3a4529f1a09 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -726,6 +726,10 @@ fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); } +fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_impl_item(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -735,6 +739,7 @@ pub fn provide(providers: &mut Providers) { used_trait_imports, check_item_well_formed, check_trait_item_well_formed, + check_impl_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index c80e0b8bba066..72f40627b831a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -171,6 +171,17 @@ impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { .check_associated_item(trait_item.id, trait_item.span, method_sig); } + pub fn check_impl_item(&mut self, def_id: DefId) { + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let impl_item = self.tcx.hir.expect_impl_item(node_id); + + let method_sig = match impl_item.node { + hir::ImplItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + self.check_associated_item(impl_item.id, impl_item.span, method_sig); + } + fn check_associated_item(&mut self, item_id: ast::NodeId, span: Span, @@ -694,12 +705,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); - let method_sig = match impl_item.node { - hir::ImplItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(impl_item.id, impl_item.span, method_sig); + let def_id = self.tcx.hir.local_def_id(impl_item.id); + ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_impl_item(self, impl_item) } } From b418b7ba0f7393d789860f96a718a4fba2729271 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 12 Mar 2018 22:18:51 -0400 Subject: [PATCH 043/546] Remove CheckTypeWellFormed struct and convert to free functions Related to #48939 --- src/librustc_typeck/check/mod.rs | 6 +- src/librustc_typeck/check/wfcheck.rs | 1011 +++++++++++++------------- 2 files changed, 500 insertions(+), 517 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5b3a4529f1a09..8b5d45d6aa118 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -719,15 +719,15 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum } fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); + wfcheck::check_item_well_formed(tcx, def_id); } fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); + wfcheck::check_trait_item(tcx, def_id); } fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_impl_item(def_id); + wfcheck::check_impl_item(tcx, def_id); } pub fn provide(providers: &mut Providers) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 72f40627b831a..406ff9463a03c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -26,10 +26,6 @@ use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -pub struct CheckTypeWellFormed<'a, 'tcx:'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, -} - /// Helper type of a temporary returned by .for_item(...). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). @@ -43,610 +39,597 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { fn with_fcx(&'tcx mut self, f: F) where F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, - &mut CheckTypeWellFormed<'b, 'gcx>) -> Vec> + TyCtxt<'b, 'gcx, 'gcx>) -> Vec> { let id = self.id; let span = self.span; let param_env = self.param_env; self.inherited.enter(|inh| { let fcx = FnCtxt::new(&inh, param_env, id); - let wf_tys = f(&fcx, &mut CheckTypeWellFormed { - tcx: fcx.tcx.global_tcx(), - }); + let wf_tys = f(&fcx, fcx.tcx.global_tcx()); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); }); } } -impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) - -> CheckTypeWellFormed<'a, 'gcx> { - CheckTypeWellFormed { - tcx, - } - } - - /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are - /// well-formed, meaning that they do not require any constraints not declared in the struct - /// definition itself. For example, this definition would be illegal: - /// - /// struct Ref<'a, T> { x: &'a T } - /// - /// because the type did not declare that `T:'a`. - /// - /// We do this check as a pre-pass before checking fn bodies because if these constraints are - /// not included it frequently leads to confusing errors in fn bodies. So it's better to check - /// the types first. - pub fn check_item_well_formed(&mut self, def_id: DefId) { - let tcx = self.tcx; - let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let item = tcx.hir.expect_item(node_id); - - debug!("check_item_well_formed(it.id={}, it.name={})", - item.id, - tcx.item_path_str(def_id)); - - match item.node { - // Right now we check that every default trait implementation - // has an implementation of itself. Basically, a case like: - // - // `impl Trait for T {}` - // - // has a requirement of `T: Trait` which was required for default - // method implementations. Although this could be improved now that - // there's a better infrastructure in place for this, it's being left - // for a follow-up work. - // - // Since there's such a requirement, we need to check *just* positive - // implementations, otherwise things like: - // - // impl !Send for T {} - // - // won't be allowed unless there's an *explicit* implementation of `Send` - // for `T` - hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { - let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)) - .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); - if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { - tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); - } - if polarity == hir::ImplPolarity::Positive { - self.check_impl(item, self_ty, trait_ref); - } else { - // FIXME(#27579) what amount of WF checking do we need for neg impls? - if trait_ref.is_some() && !is_auto { - span_err!(tcx.sess, item.span, E0192, - "negative impls are only allowed for \ - auto traits (e.g., `Send` and `Sync`)") - } - } - } - hir::ItemFn(..) => { - self.check_item_fn(item); - } - hir::ItemStatic(..) => { - self.check_item_type(item); +/// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are +/// well-formed, meaning that they do not require any constraints not declared in the struct +/// definition itself. For example, this definition would be illegal: +/// +/// struct Ref<'a, T> { x: &'a T } +/// +/// because the type did not declare that `T:'a`. +/// +/// We do this check as a pre-pass before checking fn bodies because if these constraints are +/// not included it frequently leads to confusing errors in fn bodies. So it's better to check +/// the types first. +pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let item = tcx.hir.expect_item(node_id); + + debug!("check_item_well_formed(it.id={}, it.name={})", + item.id, + tcx.item_path_str(def_id)); + + match item.node { + // Right now we check that every default trait implementation + // has an implementation of itself. Basically, a case like: + // + // `impl Trait for T {}` + // + // has a requirement of `T: Trait` which was required for default + // method implementations. Although this could be improved now that + // there's a better infrastructure in place for this, it's being left + // for a follow-up work. + // + // Since there's such a requirement, we need to check *just* positive + // implementations, otherwise things like: + // + // impl !Send for T {} + // + // won't be allowed unless there's an *explicit* implementation of `Send` + // for `T` + hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { + let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)) + .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); + if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { + tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); } - hir::ItemConst(..) => { - self.check_item_type(item); + if polarity == hir::ImplPolarity::Positive { + check_impl(tcx, item, self_ty, trait_ref); + } else { + // FIXME(#27579) what amount of WF checking do we need for neg impls? + if trait_ref.is_some() && !is_auto { + span_err!(tcx.sess, item.span, E0192, + "negative impls are only allowed for \ + auto traits (e.g., `Send` and `Sync`)") + } } - hir::ItemStruct(ref struct_def, ref ast_generics) => { - self.check_type_defn(item, false, |fcx| { - vec![fcx.non_enum_variant(struct_def)] - }); + } + hir::ItemFn(..) => { + check_item_fn(tcx, item); + } + hir::ItemStatic(..) => { + check_item_type(tcx, item); + } + hir::ItemConst(..) => { + check_item_type(tcx, item); + } + hir::ItemStruct(ref struct_def, ref ast_generics) => { + check_type_defn(tcx, item, false, |fcx| { + vec![fcx.non_enum_variant(struct_def)] + }); - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemUnion(ref struct_def, ref ast_generics) => { - self.check_type_defn(item, true, |fcx| { - vec![fcx.non_enum_variant(struct_def)] - }); + check_variances_for_type_defn(tcx, item, ast_generics); + } + hir::ItemUnion(ref struct_def, ref ast_generics) => { + check_type_defn(tcx, item, true, |fcx| { + vec![fcx.non_enum_variant(struct_def)] + }); - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemEnum(ref enum_def, ref ast_generics) => { - self.check_type_defn(item, true, |fcx| { - fcx.enum_variants(enum_def) - }); + check_variances_for_type_defn(tcx, item, ast_generics); + } + hir::ItemEnum(ref enum_def, ref ast_generics) => { + check_type_defn(tcx, item, true, |fcx| { + fcx.enum_variants(enum_def) + }); - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemTrait(..) => { - self.check_trait(item); - } - _ => {} + check_variances_for_type_defn(tcx, item, ast_generics); } + hir::ItemTrait(..) => { + check_trait(tcx, item); + } + _ => {} } +} - pub fn check_trait_item(&mut self, def_id: DefId) { - let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let trait_item = self.tcx.hir.expect_trait_item(node_id); +pub fn check_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let trait_item = tcx.hir.expect_trait_item(node_id); - let method_sig = match trait_item.node { - hir::TraitItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(trait_item.id, trait_item.span, method_sig); - } + let method_sig = match trait_item.node { + hir::TraitItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + check_associated_item(tcx, trait_item.id, trait_item.span, method_sig); +} - pub fn check_impl_item(&mut self, def_id: DefId) { - let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let impl_item = self.tcx.hir.expect_impl_item(node_id); +pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let impl_item = tcx.hir.expect_impl_item(node_id); - let method_sig = match impl_item.node { - hir::ImplItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - self.check_associated_item(impl_item.id, impl_item.span, method_sig); - } + let method_sig = match impl_item.node { + hir::ImplItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + check_associated_item(tcx, impl_item.id, impl_item.span, method_sig); +} - fn check_associated_item(&mut self, - item_id: ast::NodeId, - span: Span, - sig_if_method: Option<&hir::MethodSig>) { - let code = ObligationCauseCode::MiscObligation; - self.for_id(item_id, span).with_fcx(|fcx, this| { - let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); - - let (mut implied_bounds, self_ty) = match item.container { - ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()), - ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span), - fcx.tcx.type_of(def_id)) - }; +fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: ast::NodeId, + span: Span, + sig_if_method: Option<&hir::MethodSig>) { + let code = ObligationCauseCode::MiscObligation; + for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { + let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); + + let (mut implied_bounds, self_ty) = match item.container { + ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()), + ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span), + fcx.tcx.type_of(def_id)) + }; - match item.kind { - ty::AssociatedKind::Const => { + match item.kind { + ty::AssociatedKind::Const => { + let ty = fcx.tcx.type_of(item.def_id); + let ty = fcx.normalize_associated_types_in(span, &ty); + fcx.register_wf_obligation(ty, span, code.clone()); + } + ty::AssociatedKind::Method => { + reject_shadowing_type_parameters(fcx.tcx, item.def_id); + let sig = fcx.tcx.fn_sig(item.def_id); + let sig = fcx.normalize_associated_types_in(span, &sig); + check_fn_or_method(tcx, fcx, span, sig, + item.def_id, &mut implied_bounds); + let sig_if_method = sig_if_method.expect("bad signature for method"); + check_method_receiver(fcx, sig_if_method, &item, self_ty); + } + ty::AssociatedKind::Type => { + if item.defaultness.has_value() { let ty = fcx.tcx.type_of(item.def_id); let ty = fcx.normalize_associated_types_in(span, &ty); fcx.register_wf_obligation(ty, span, code.clone()); } - ty::AssociatedKind::Method => { - reject_shadowing_type_parameters(fcx.tcx, item.def_id); - let sig = fcx.tcx.fn_sig(item.def_id); - let sig = fcx.normalize_associated_types_in(span, &sig); - this.check_fn_or_method(fcx, span, sig, - item.def_id, &mut implied_bounds); - let sig_if_method = sig_if_method.expect("bad signature for method"); - this.check_method_receiver(fcx, sig_if_method, &item, self_ty); - } - ty::AssociatedKind::Type => { - if item.defaultness.has_value() { - let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in(span, &ty); - fcx.register_wf_obligation(ty, span, code.clone()); - } - } } + } - implied_bounds - }) - } - - fn for_item<'tcx>(&self, item: &hir::Item) - -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - self.for_id(item.id, item.span) - } + implied_bounds + }) +} - fn for_id<'tcx>(&self, id: ast::NodeId, span: Span) +fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item) -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - let def_id = self.tcx.hir.local_def_id(id); - CheckWfFcxBuilder { - inherited: Inherited::build(self.tcx, def_id), - id, - span, - param_env: self.tcx.param_env(def_id), - } + for_id(tcx, item.id, item.span) +} + +fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span) + -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { + let def_id = tcx.hir.local_def_id(id); + CheckWfFcxBuilder { + inherited: Inherited::build(tcx, def_id), + id, + span, + param_env: tcx.param_env(def_id), } +} - /// In a type definition, we check that to ensure that the types of the fields are well-formed. - fn check_type_defn(&mut self, item: &hir::Item, all_sized: bool, mut lookup_fields: F) - where F: for<'fcx, 'tcx> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx>) -> Vec> - { - self.for_item(item).with_fcx(|fcx, this| { - let variants = lookup_fields(fcx); - let def_id = fcx.tcx.hir.local_def_id(item.id); - let packed = fcx.tcx.adt_def(def_id).repr.packed(); - - for variant in &variants { - // For DST, or when drop needs to copy things around, all - // intermediate types must be sized. - let needs_drop_copy = || { - packed && { - let ty = variant.fields.last().unwrap().ty; - let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(this.tcx) - .unwrap_or_else(|| { - span_bug!(item.span, "inference variables in {:?}", ty) - }); - ty.needs_drop(this.tcx, this.tcx.param_env(def_id)) - } - }; - let unsized_len = if - all_sized || - variant.fields.is_empty() || - needs_drop_copy() - { - 0 - } else { - 1 - }; - for field in &variant.fields[..variant.fields.len() - unsized_len] { - fcx.register_bound( - field.ty, - fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem), - traits::ObligationCause::new(field.span, - fcx.body_id, - traits::FieldSized(match item.node.adt_kind() { - Some(i) => i, - None => bug!(), - }))); +/// In a type definition, we check that to ensure that the types of the fields are well-formed. +fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, all_sized: bool, mut lookup_fields: F) + where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec> +{ + for_item(tcx, item).with_fcx(|fcx, fcx_tcx| { + let variants = lookup_fields(fcx); + let def_id = fcx.tcx.hir.local_def_id(item.id); + let packed = fcx.tcx.adt_def(def_id).repr.packed(); + + for variant in &variants { + // For DST, or when drop needs to copy things around, all + // intermediate types must be sized. + let needs_drop_copy = || { + packed && { + let ty = variant.fields.last().unwrap().ty; + let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) + .unwrap_or_else(|| { + span_bug!(item.span, "inference variables in {:?}", ty) + }); + ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) } + }; + let unsized_len = if + all_sized || + variant.fields.is_empty() || + needs_drop_copy() + { + 0 + } else { + 1 + }; + for field in &variant.fields[..variant.fields.len() - unsized_len] { + fcx.register_bound( + field.ty, + fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem), + traits::ObligationCause::new(field.span, + fcx.body_id, + traits::FieldSized(match item.node.adt_kind() { + Some(i) => i, + None => bug!(), + }))); + } - // All field types must be well-formed. - for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, - ObligationCauseCode::MiscObligation) - } + // All field types must be well-formed. + for field in &variant.fields { + fcx.register_wf_obligation(field.ty, field.span, + ObligationCauseCode::MiscObligation) } + } - self.check_where_clauses(fcx, item.span, def_id); + check_where_clauses(tcx, fcx, item.span, def_id); - vec![] // no implied bounds in a struct def'n - }); - } + vec![] // no implied bounds in a struct def'n + }); +} - fn check_trait(&mut self, item: &hir::Item) { - let trait_def_id = self.tcx.hir.local_def_id(item.id); - self.for_item(item).with_fcx(|fcx, _| { - self.check_where_clauses(fcx, item.span, trait_def_id); - vec![] - }); - } +fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { + let trait_def_id = tcx.hir.local_def_id(item.id); + for_item(tcx, item).with_fcx(|fcx, _| { + check_where_clauses(tcx, fcx, item.span, trait_def_id); + vec![] + }); +} - fn check_item_fn(&mut self, item: &hir::Item) { - self.for_item(item).with_fcx(|fcx, this| { - let def_id = fcx.tcx.hir.local_def_id(item.id); - let sig = fcx.tcx.fn_sig(def_id); - let sig = fcx.normalize_associated_types_in(item.span, &sig); - let mut implied_bounds = vec![]; - this.check_fn_or_method(fcx, item.span, sig, - def_id, &mut implied_bounds); - implied_bounds - }) - } +fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { + for_item(tcx, item).with_fcx(|fcx, tcx| { + let def_id = fcx.tcx.hir.local_def_id(item.id); + let sig = fcx.tcx.fn_sig(def_id); + let sig = fcx.normalize_associated_types_in(item.span, &sig); + let mut implied_bounds = vec![]; + check_fn_or_method(tcx, fcx, item.span, sig, + def_id, &mut implied_bounds); + implied_bounds + }) +} - fn check_item_type(&mut self, - item: &hir::Item) - { - debug!("check_item_type: {:?}", item); +fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item) +{ + debug!("check_item_type: {:?}", item); - self.for_item(item).with_fcx(|fcx, _this| { - let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); - let item_ty = fcx.normalize_associated_types_in(item.span, &ty); + for_item(tcx, item).with_fcx(|fcx, _this| { + let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); + let item_ty = fcx.normalize_associated_types_in(item.span, &ty); - fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); - vec![] // no implied bounds in a const etc - }); - } + vec![] // no implied bounds in a const etc + }); +} - fn check_impl(&mut self, - item: &hir::Item, - ast_self_ty: &hir::Ty, - ast_trait_ref: &Option) - { - debug!("check_impl: {:?}", item); - - self.for_item(item).with_fcx(|fcx, this| { - let item_def_id = fcx.tcx.hir.local_def_id(item.id); - - match *ast_trait_ref { - Some(ref ast_trait_ref) => { - let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap(); - let trait_ref = - fcx.normalize_associated_types_in( - ast_trait_ref.path.span, &trait_ref); - let obligations = - ty::wf::trait_obligations(fcx, - fcx.param_env, - fcx.body_id, - &trait_ref, - ast_trait_ref.path.span); - for obligation in obligations { - fcx.register_predicate(obligation); - } - } - None => { - let self_ty = fcx.tcx.type_of(item_def_id); - let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, - ObligationCauseCode::MiscObligation); +fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, + ast_self_ty: &hir::Ty, + ast_trait_ref: &Option) +{ + debug!("check_impl: {:?}", item); + + for_item(tcx, item).with_fcx(|fcx, tcx| { + let item_def_id = fcx.tcx.hir.local_def_id(item.id); + + match *ast_trait_ref { + Some(ref ast_trait_ref) => { + let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap(); + let trait_ref = + fcx.normalize_associated_types_in( + ast_trait_ref.path.span, &trait_ref); + let obligations = + ty::wf::trait_obligations(fcx, + fcx.param_env, + fcx.body_id, + &trait_ref, + ast_trait_ref.path.span); + for obligation in obligations { + fcx.register_predicate(obligation); } } + None => { + let self_ty = fcx.tcx.type_of(item_def_id); + let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, + ObligationCauseCode::MiscObligation); + } + } - this.check_where_clauses(fcx, item.span, item_def_id); + check_where_clauses(tcx, fcx, item.span, item_def_id); - fcx.impl_implied_bounds(item_def_id, item.span) - }); - } + fcx.impl_implied_bounds(item_def_id, item.span) + }); +} - /// Checks where clauses and inline bounds that are declared on def_id. - fn check_where_clauses<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - span: Span, - def_id: DefId) { - use ty::subst::Subst; - use rustc::ty::TypeFoldable; - - let mut predicates = fcx.tcx.predicates_of(def_id); - let mut substituted_predicates = Vec::new(); - - let generics = self.tcx.generics_of(def_id); - let is_our_default = |def: &ty::TypeParameterDef| - def.has_default && def.index >= generics.parent_count() as u32; - - // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. - // For example this forbids the declaration: - // struct Foo> { .. } - // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. - for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) { - let ty = fcx.tcx.type_of(d); - // ignore dependent defaults -- that is, where the default of one type - // parameter includes another (e.g., ). In those cases, we can't - // be sure if it will error or not as user might always specify the other. - if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), - ObligationCauseCode::MiscObligation); - } +/// Checks where clauses and inline bounds that are declared on def_id. +fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, + fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + span: Span, + def_id: DefId) { + use ty::subst::Subst; + use rustc::ty::TypeFoldable; + + let mut predicates = fcx.tcx.predicates_of(def_id); + let mut substituted_predicates = Vec::new(); + + let generics = tcx.generics_of(def_id); + let is_our_default = |def: &ty::TypeParameterDef| + def.has_default && def.index >= generics.parent_count() as u32; + + // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. + // For example this forbids the declaration: + // struct Foo> { .. } + // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. + for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) { + let ty = fcx.tcx.type_of(d); + // ignore dependent defaults -- that is, where the default of one type + // parameter includes another (e.g., ). In those cases, we can't + // be sure if it will error or not as user might always specify the other. + if !ty.needs_subst() { + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), + ObligationCauseCode::MiscObligation); } + } - // Check that trait predicates are WF when params are substituted by their defaults. - // We don't want to overly constrain the predicates that may be written but we want to - // catch cases where a default my never be applied such as `struct Foo`. - // Therefore we check if a predicate which contains a single type param - // with a concrete default is WF with that default substituted. - // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. - // - // First we build the defaulted substitution. - let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| { - // All regions are identity. - fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data())) - }, |def, _| { - // If the param has a default, - if is_our_default(def) { - let default_ty = fcx.tcx.type_of(def.def_id); - // and it's not a dependent default - if !default_ty.needs_subst() { - // then substitute with the default. - return default_ty; - } + // Check that trait predicates are WF when params are substituted by their defaults. + // We don't want to overly constrain the predicates that may be written but we want to + // catch cases where a default my never be applied such as `struct Foo`. + // Therefore we check if a predicate which contains a single type param + // with a concrete default is WF with that default substituted. + // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. + // + // First we build the defaulted substitution. + let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| { + // All regions are identity. + fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data())) + }, |def, _| { + // If the param has a default, + if is_our_default(def) { + let default_ty = fcx.tcx.type_of(def.def_id); + // and it's not a dependent default + if !default_ty.needs_subst() { + // then substitute with the default. + return default_ty; } - // Mark unwanted params as err. - fcx.tcx.types.err - }); - // Now we build the substituted predicates. - for &pred in predicates.predicates.iter() { - struct CountParams { params: FxHashSet } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - match t.sty { - ty::TyParam(p) => { - self.params.insert(p.idx); - t.super_visit_with(self) - } - _ => t.super_visit_with(self) + } + // Mark unwanted params as err. + fcx.tcx.types.err + }); + // Now we build the substituted predicates. + for &pred in predicates.predicates.iter() { + struct CountParams { params: FxHashSet } + impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + match t.sty { + ty::TyParam(p) => { + self.params.insert(p.idx); + t.super_visit_with(self) } + _ => t.super_visit_with(self) } } - let mut param_count = CountParams { params: FxHashSet() }; - pred.visit_with(&mut param_count); - let substituted_pred = pred.subst(fcx.tcx, substs); - // Don't check non-defaulted params, dependent defaults or preds with multiple params. - if substituted_pred.references_error() || param_count.params.len() > 1 { - continue; - } - // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.contains(&substituted_pred) { - substituted_predicates.push(substituted_pred); - } } - - predicates.predicates.extend(substituted_predicates); - let predicates = predicates.instantiate_identity(fcx.tcx); - let predicates = fcx.normalize_associated_types_in(span, &predicates); - - let obligations = - predicates.predicates - .iter() - .flat_map(|p| ty::wf::predicate_obligations(fcx, - fcx.param_env, - fcx.body_id, - p, - span)); - - for obligation in obligations { - fcx.register_predicate(obligation); + let mut param_count = CountParams { params: FxHashSet() }; + pred.visit_with(&mut param_count); + let substituted_pred = pred.subst(fcx.tcx, substs); + // Don't check non-defaulted params, dependent defaults or preds with multiple params. + if substituted_pred.references_error() || param_count.params.len() > 1 { + continue; + } + // Avoid duplication of predicates that contain no parameters, for example. + if !predicates.predicates.contains(&substituted_pred) { + substituted_predicates.push(substituted_pred); } } - fn check_fn_or_method<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - span: Span, - sig: ty::PolyFnSig<'tcx>, - def_id: DefId, - implied_bounds: &mut Vec>) - { - let sig = fcx.normalize_associated_types_in(span, &sig); - let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - - for input_ty in sig.inputs() { - fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); - } - implied_bounds.extend(sig.inputs()); + predicates.predicates.extend(substituted_predicates); + let predicates = predicates.instantiate_identity(fcx.tcx); + let predicates = fcx.normalize_associated_types_in(span, &predicates); + + let obligations = + predicates.predicates + .iter() + .flat_map(|p| ty::wf::predicate_obligations(fcx, + fcx.param_env, + fcx.body_id, + p, + span)); + + for obligation in obligations { + fcx.register_predicate(obligation); + } +} - fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); +fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, + fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + span: Span, + sig: ty::PolyFnSig<'tcx>, + def_id: DefId, + implied_bounds: &mut Vec>) +{ + let sig = fcx.normalize_associated_types_in(span, &sig); + let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); + + for input_ty in sig.inputs() { + fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); + } + implied_bounds.extend(sig.inputs()); - // FIXME(#25759) return types should not be implied bounds - implied_bounds.push(sig.output()); + fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); - self.check_where_clauses(fcx, span, def_id); - } + // FIXME(#25759) return types should not be implied bounds + implied_bounds.push(sig.output()); - fn check_method_receiver<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - method_sig: &hir::MethodSig, - method: &ty::AssociatedItem, - self_ty: Ty<'tcx>) - { - // check that the method has a valid receiver type, given the type `Self` - debug!("check_method_receiver({:?}, self_ty={:?})", - method, self_ty); + check_where_clauses(tcx, fcx, span, def_id); +} - if !method.method_has_self_argument { - return; - } +fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + method_sig: &hir::MethodSig, + method: &ty::AssociatedItem, + self_ty: Ty<'tcx>) +{ + // check that the method has a valid receiver type, given the type `Self` + debug!("check_method_receiver({:?}, self_ty={:?})", + method, self_ty); + + if !method.method_has_self_argument { + return; + } - let span = method_sig.decl.inputs[0].span; + let span = method_sig.decl.inputs[0].span; - let sig = fcx.tcx.fn_sig(method.def_id); - let sig = fcx.normalize_associated_types_in(span, &sig); - let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig); + let sig = fcx.tcx.fn_sig(method.def_id); + let sig = fcx.normalize_associated_types_in(span, &sig); + let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig); - debug!("check_method_receiver: sig={:?}", sig); + debug!("check_method_receiver: sig={:?}", sig); - let self_ty = fcx.normalize_associated_types_in(span, &self_ty); - let self_ty = fcx.tcx.liberate_late_bound_regions( - method.def_id, - &ty::Binder(self_ty) - ); + let self_ty = fcx.normalize_associated_types_in(span, &self_ty); + let self_ty = fcx.tcx.liberate_late_bound_regions( + method.def_id, + &ty::Binder(self_ty) + ); - let self_arg_ty = sig.inputs()[0]; + let self_arg_ty = sig.inputs()[0]; - let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver); - let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty); - let self_arg_ty = fcx.tcx.liberate_late_bound_regions( - method.def_id, - &ty::Binder(self_arg_ty) - ); + let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver); + let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty); + let self_arg_ty = fcx.tcx.liberate_late_bound_regions( + method.def_id, + &ty::Binder(self_arg_ty) + ); - let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers(); + let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers(); - loop { - if let Some((potential_self_ty, _)) = autoderef.next() { - debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", - potential_self_ty, self_ty); + loop { + if let Some((potential_self_ty, _)) = autoderef.next() { + debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", + potential_self_ty, self_ty); - if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() { - autoderef.finalize(); - if let Some(mut err) = fcx.demand_eqtype_with_origin( - &cause, self_ty, potential_self_ty) { - err.emit(); - } - break + if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() { + autoderef.finalize(); + if let Some(mut err) = fcx.demand_eqtype_with_origin( + &cause, self_ty, potential_self_ty) { + err.emit(); } - } else { - fcx.tcx.sess.diagnostic().mut_span_err( - span, &format!("invalid `self` type: {:?}", self_arg_ty)) - .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty)) - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .code(DiagnosticId::Error("E0307".into())) - .emit(); - return + break } + } else { + fcx.tcx.sess.diagnostic().mut_span_err( + span, &format!("invalid `self` type: {:?}", self_arg_ty)) + .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty)) + .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .code(DiagnosticId::Error("E0307".into())) + .emit(); + return } + } - let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok(); - let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty); - - if !fcx.tcx.features().arbitrary_self_types { - match self_kind { - ExplicitSelf::ByValue | - ExplicitSelf::ByReference(_, _) | - ExplicitSelf::ByBox => (), - - ExplicitSelf::ByRawPointer(_) => { - feature_gate::feature_err( - &fcx.tcx.sess.parse_sess, - "arbitrary_self_types", - span, - GateIssue::Language, - "raw pointer `self` is unstable") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .emit(); - } + let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok(); + let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty); + + if !fcx.tcx.features().arbitrary_self_types { + match self_kind { + ExplicitSelf::ByValue | + ExplicitSelf::ByReference(_, _) | + ExplicitSelf::ByBox => (), + + ExplicitSelf::ByRawPointer(_) => { + feature_gate::feature_err( + &fcx.tcx.sess.parse_sess, + "arbitrary_self_types", + span, + GateIssue::Language, + "raw pointer `self` is unstable") + .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .emit(); + } - ExplicitSelf::Other => { - feature_gate::feature_err( - &fcx.tcx.sess.parse_sess, - "arbitrary_self_types", - span, - GateIssue::Language,"arbitrary `self` types are unstable") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .emit(); - } + ExplicitSelf::Other => { + feature_gate::feature_err( + &fcx.tcx.sess.parse_sess, + "arbitrary_self_types", + span, + GateIssue::Language,"arbitrary `self` types are unstable") + .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .emit(); } } } +} - fn check_variances_for_type_defn(&self, - item: &hir::Item, - ast_generics: &hir::Generics) - { - let item_def_id = self.tcx.hir.local_def_id(item.id); - let ty = self.tcx.type_of(item_def_id); - if self.tcx.has_error_field(ty) { - return; - } - - let ty_predicates = self.tcx.predicates_of(item_def_id); - assert_eq!(ty_predicates.parent, None); - let variances = self.tcx.variances_of(item_def_id); +fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, + ast_generics: &hir::Generics) +{ + let item_def_id = tcx.hir.local_def_id(item.id); + let ty = tcx.type_of(item_def_id); + if tcx.has_error_field(ty) { + return; + } - let mut constrained_parameters: FxHashSet<_> = - variances.iter().enumerate() - .filter(|&(_, &variance)| variance != ty::Bivariant) - .map(|(index, _)| Parameter(index as u32)) - .collect(); + let ty_predicates = tcx.predicates_of(item_def_id); + assert_eq!(ty_predicates.parent, None); + let variances = tcx.variances_of(item_def_id); - identify_constrained_type_params(self.tcx, - ty_predicates.predicates.as_slice(), - None, - &mut constrained_parameters); + let mut constrained_parameters: FxHashSet<_> = + variances.iter().enumerate() + .filter(|&(_, &variance)| variance != ty::Bivariant) + .map(|(index, _)| Parameter(index as u32)) + .collect(); - for (index, _) in variances.iter().enumerate() { - if constrained_parameters.contains(&Parameter(index as u32)) { - continue; - } + identify_constrained_type_params(tcx, + ty_predicates.predicates.as_slice(), + None, + &mut constrained_parameters); - let (span, name) = match ast_generics.params[index] { - hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()), - hir::GenericParam::Type(ref tp) => (tp.span, tp.name), - }; - self.report_bivariance(span, name); + for (index, _) in variances.iter().enumerate() { + if constrained_parameters.contains(&Parameter(index as u32)) { + continue; } + + let (span, name) = match ast_generics.params[index] { + hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()), + hir::GenericParam::Type(ref tp) => (tp.span, tp.name), + }; + report_bivariance(tcx, span, name); } +} - fn report_bivariance(&self, - span: Span, - param_name: ast::Name) - { - let mut err = error_392(self.tcx, span, param_name); - - let suggested_marker_id = self.tcx.lang_items().phantom_data(); - match suggested_marker_id { - Some(def_id) => { - err.help( - &format!("consider removing `{}` or using a marker such as `{}`", - param_name, - self.tcx.item_path_str(def_id))); - } - None => { - // no lang items, no help! - } +fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + span: Span, + param_name: ast::Name) +{ + let mut err = error_392(tcx, span, param_name); + + let suggested_marker_id = tcx.lang_items().phantom_data(); + match suggested_marker_id { + Some(def_id) => { + err.help( + &format!("consider removing `{}` or using a marker such as `{}`", + param_name, + tcx.item_path_str(def_id))); + } + None => { + // no lang items, no help! } - err.emit(); } + err.emit(); } fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { From aaac69f78e6a9f0ee52b41969d81f4bb79da6418 Mon Sep 17 00:00:00 2001 From: Maxwell Powlison Date: Fri, 16 Mar 2018 03:41:53 -0400 Subject: [PATCH 044/546] Fix Issue #48345, is_file, is_dir, and is_symlink note mutual exclusion The methods on the structures `fs::FileType` and `fs::Metadata` of (respectively) `is_file`, `is_dir`, and `is_symlink` had some ambiguity in documentation, where it was not noted whether files will pass those tests exclusively or not. It is now written that the tests are mutually exclusive. Fixes #48345. --- src/libstd/fs.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index db52ed67d3a85..5caa703ee97e3 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -906,7 +906,13 @@ impl Metadata { FileType(self.0.file_type()) } - /// Returns whether this metadata is for a directory. + /// Returns whether this metadata is for a directory. The + /// result is mutually exclusive to the result of + /// [`is_file`], and will be false for symlink metadata + /// obtained from [`symlink_metadata`]. + /// + /// [`is_file`]: struct.Metadata.html#method.is_file + /// [`symlink_metadata`]: fn.symlink_metadata.html /// /// # Examples /// @@ -923,7 +929,13 @@ impl Metadata { #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.file_type().is_dir() } - /// Returns whether this metadata is for a regular file. + /// Returns whether this metadata is for a regular file. The + /// result is mutually exclusive to the result of + /// [`is_dir`], and will be false for symlink metadata + /// obtained from [`symlink_metadata`]. + /// + /// [`is_dir`]: struct.Metadata.html#method.is_dir + /// [`symlink_metadata`]: fn.symlink_metadata.html /// /// # Examples /// @@ -1148,7 +1160,13 @@ impl Permissions { } impl FileType { - /// Test whether this file type represents a directory. + /// Test whether this file type represents a directory. The + /// result is mutually exclusive to the results of + /// [`is_file`] and [`is_symlink`]; only zero or one of these + /// tests may pass. + /// + /// [`is_file`]: struct.FileType.html#method.is_file + /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples /// @@ -1167,6 +1185,12 @@ impl FileType { pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Test whether this file type represents a regular file. + /// The result is mutually exclusive to the results of + /// [`is_dir`] and [`is_symlink`]; only zero or one of these + /// tests may pass. + /// + /// [`is_dir`]: struct.FileType.html#method.is_dir + /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples /// @@ -1185,6 +1209,9 @@ impl FileType { pub fn is_file(&self) -> bool { self.0.is_file() } /// Test whether this file type represents a symbolic link. + /// The result is mutually exclusive to the results of + /// [`is_dir`] and [`is_file`]; only zero or one of these + /// tests may pass. /// /// The underlying [`Metadata`] struct needs to be retrieved /// with the [`fs::symlink_metadata`] function and not the @@ -1195,6 +1222,8 @@ impl FileType { /// [`Metadata`]: struct.Metadata.html /// [`fs::metadata`]: fn.metadata.html /// [`fs::symlink_metadata`]: fn.symlink_metadata.html + /// [`is_dir`]: struct.FileType.html#method.is_dir + /// [`is_file`]: struct.FileType.html#method.is_file /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples From 683ad942966c427be773b412d9314baa55a6e188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:38:12 +0100 Subject: [PATCH 045/546] Add OnDrop --- src/librustc_data_structures/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 81246aea1b56e..bf0b3726bb301 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -76,6 +76,14 @@ pub mod flock; pub mod sync; pub mod owning_ref; +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { + (self.0)(); + } +} + // See comments in src/librustc/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} From 3b43dcbb4c62a36b68afd7f9a1bf12aed1b53d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:11:23 +0100 Subject: [PATCH 046/546] Replace Rc with Lrc --- src/librustc/middle/const_val.rs | 4 ++-- src/librustc/traits/query/dropck_outlives.rs | 6 +++--- src/librustc/traits/query/normalize.rs | 6 +++--- src/librustc/ty/structural_impls.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 6 +++--- src/librustc_traits/dropck_outlives.rs | 4 ++-- src/librustc_traits/normalize_projection_ty.rs | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8c3dfd0bce752..19a7576b7ceac 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -19,7 +19,7 @@ use graphviz::IntoCow; use syntax_pos::Span; use std::borrow::Cow; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; @@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> { #[derive(Clone, Debug)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub kind: Rc>, + pub kind: Lrc>, } #[derive(Clone, Debug)] diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef9..e16a1082214f7 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -15,7 +15,7 @@ use std::iter::FromIterator; use traits::query::CanonicalTyGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Kind; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -182,13 +182,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 70c5cf5f39029..63f50cff4c2ad 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -17,7 +17,7 @@ use infer::at::At; use infer::canonical::{Canonical, Canonicalize, QueryResult}; use middle::const_val::ConstVal; use mir::interpret::GlobalId; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::query::CanonicalProjectionGoal; use traits::project::Normalized; @@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c9a69d5405c9a..3fc20508ad7ee 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; @@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { tcx.lift(&*self.kind).map(|kind| { ConstEvalErr { span: self.span, - kind: Rc::new(kind), + kind: Lrc::new(kind), } }) } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b033..50997089a5764 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory}; use std::fmt; use std::error::Error; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -477,7 +477,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do match-check before building MIR if tcx.check_match(def_id).is_err() { return Err(ConstEvalErr { - kind: Rc::new(CheckMatchError), + kind: Lrc::new(CheckMatchError), span, }); } @@ -489,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Rc::new(TypeckError), + kind: Lrc::new(TypeckError), span, }); } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2a8cfe5cc06b3..1fe2f87128abd 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::FxHashSet; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::codemap::{Span, DUMMY_SP}; use util; crate fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", goal); tcx.infer_ctxt().enter(|ref infcx| { diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc3..62d5ef11551c0 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; use rustc::ty::{ParamEnvAnd, TyCtxt}; use rustc::util::common::CellUsizeExt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::DUMMY_SP; use util; @@ -22,7 +22,7 @@ use util; crate fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess.perf_stats.normalize_projection_ty.increment(); From 910bf840cce1da57b96f7ac15f8b803675bb8a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:09:20 +0100 Subject: [PATCH 047/546] Always print `aborting due to n previous error(s)` and only print it once for multi-threaded code --- src/librustc_driver/lib.rs | 54 +++++++++++++++++++--------------- src/librustc_errors/lib.rs | 34 +++++++++++---------- src/librustc_typeck/astconv.rs | 3 +- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5a1983bfec64f..2a15d57a262e1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -63,6 +63,7 @@ use rustc_resolve as resolve; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::OnDrop; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::CompileIncomplete; use rustc::session::config::{Input, PrintRequest, ErrorOutputType}; @@ -515,30 +516,35 @@ fn run_compiler_impl<'a>(args: &[String], target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; - let plugins = sess.opts.debugging_opts.extra_plugins.clone(); - - let cstore = CStore::new(trans.metadata_loader()); - - do_or_return!(callbacks.late_callback(&*trans, - &matches, - &sess, - &cstore, - &input, - &odir, - &ofile), Some(sess)); - - let control = callbacks.build_controller(&sess, &matches); - - (driver::compile_input(trans, - &sess, - &cstore, - &input_file_path, - &input, - &odir, - &ofile, - Some(plugins), - &control), - Some(sess)) + let result = { + let plugins = sess.opts.debugging_opts.extra_plugins.clone(); + + let cstore = CStore::new(trans.metadata_loader()); + + do_or_return!(callbacks.late_callback(&*trans, + &matches, + &sess, + &cstore, + &input, + &odir, + &ofile), Some(sess)); + + let _sess_abort_error = OnDrop(|| sess.diagnostic().print_error_count()); + + let control = callbacks.build_controller(&sess, &matches); + + driver::compile_input(trans, + &sess, + &cstore, + &input_file_path, + &input, + &odir, + &ofile, + Some(plugins), + &control) + }; + + (result, Some(sess)) } // Extract output directory and file from matches. diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7148969191f2b..b3265c21884be 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -555,21 +555,15 @@ impl Handler { pub fn has_errors(&self) -> bool { self.err_count() > 0 } - pub fn abort_if_errors(&self) { - let s; - match self.err_count() { - 0 => { - if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { - DiagnosticBuilder::new_diagnostic(self, bug).emit(); - } - return; - } - 1 => s = "aborting due to previous error".to_string(), - _ => { - s = format!("aborting due to {} previous errors", self.err_count()); - } - } - let err = self.fatal(&s); + + pub fn print_error_count(&self) { + let s = match self.err_count() { + 0 => return, + 1 => "aborting due to previous error".to_string(), + _ => format!("aborting due to {} previous errors", self.err_count()) + }; + + let _ = self.fatal(&s); let can_show_explain = self.emitter.borrow().should_show_explain(); let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty(); @@ -600,8 +594,16 @@ impl Handler { } } } + } - err.raise(); + pub fn abort_if_errors(&self) { + if self.err_count() == 0 { + if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { + DiagnosticBuilder::new_diagnostic(self, bug).emit(); + } + return; + } + FatalError.raise(); } pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { if lvl == Warning && !self.flags.can_emit_warnings { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 827ca79334cbe..bc69fbdb77837 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -27,6 +27,7 @@ use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; use util::nodemap::FxHashSet; +use errors::FatalError; use std::iter; use syntax::{abi, ast}; @@ -337,7 +338,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::Trait(trait_def_id) => trait_def_id, Def::TraitAlias(alias_def_id) => alias_def_id, Def::Err => { - self.tcx().sess.fatal("cannot continue compilation due to previous error"); + FatalError.raise(); } _ => unreachable!(), } From b1d872b38eaacefbef73faa6a4a0c07622a8c941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 16:13:47 +0100 Subject: [PATCH 048/546] Update tests --- src/test/ui-fulldeps/custom-derive/issue-36935.stderr | 2 ++ src/test/ui-fulldeps/proc-macro/load-panic.stderr | 2 ++ src/test/ui/codemap_tests/two_files.stderr | 3 ++- src/test/ui/cross-file-errors/main.stderr | 2 ++ src/test/ui/did_you_mean/recursion_limit_macro.stderr | 2 ++ src/test/ui/error-codes/E0404.stderr | 3 ++- src/test/ui/error-codes/E0405.stderr | 3 ++- src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr | 2 ++ src/test/ui/feature-gate-fn_must_use.stderr | 2 ++ .../feature-gate/issue-43106-gating-of-builtin-attrs.stderr | 2 ++ .../ui/feature-gate/issue-43106-gating-of-deprecated.stderr | 2 ++ src/test/ui/impl-trait/universal_wrong_bounds.stderr | 4 +++- src/test/ui/issue-22644.stderr | 2 ++ src/test/ui/issue-44406.stderr | 2 ++ src/test/ui/lint-output-format-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels.stderr | 2 ++ src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr | 2 ++ src/test/ui/loops-reject-lifetime-shadowing-label.stderr | 2 ++ src/test/ui/macro-context.stderr | 2 ++ src/test/ui/macros/macro_path_as_generic_bound.stderr | 3 ++- src/test/ui/macros/trace_faulty_macros.stderr | 2 ++ src/test/ui/raw_string.stderr | 2 ++ src/test/ui/resolve/issue-21221-1.stderr | 4 +++- src/test/ui/resolve/issue-21221-2.stderr | 3 ++- src/test/ui/resolve/issue-21221-3.stderr | 3 ++- src/test/ui/resolve/issue-21221-4.stderr | 3 ++- src/test/ui/resolve/issue-3907.stderr | 3 ++- src/test/ui/resolve/issue-5035.stderr | 4 +++- .../ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr | 4 +++- .../generic-associated-types-where.stderr | 2 -- src/test/ui/span/issue-24690.stderr | 2 ++ src/test/ui/span/issue-35987.stderr | 3 ++- 33 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr index b082999a8978d..0278256994120 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr @@ -6,3 +6,5 @@ LL | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked | = help: message: lolnope +error: aborting due to previous error + diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui-fulldeps/proc-macro/load-panic.stderr index edfd134469cda..30ad53f9041f0 100644 --- a/src/test/ui-fulldeps/proc-macro/load-panic.stderr +++ b/src/test/ui-fulldeps/proc-macro/load-panic.stderr @@ -6,3 +6,5 @@ LL | #[derive(A)] | = help: message: nope! +error: aborting due to previous error + diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 614531c982128..e247e86fbcb22 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -4,5 +4,6 @@ error[E0404]: expected trait, found type alias `Bar` LL | 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 +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr index a9db5214e6a2e..8fe795f7f1d8a 100644 --- a/src/test/ui/cross-file-errors/main.stderr +++ b/src/test/ui/cross-file-errors/main.stderr @@ -9,3 +9,5 @@ LL | _ LL | underscore!(); | -------------- in this macro invocation +error: aborting due to previous error + 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 f6bce55528c7d..265a688df9910 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -9,3 +9,5 @@ LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr index 9f705da586167..afb748bedbe0f 100644 --- a/src/test/ui/error-codes/E0404.stderr +++ b/src/test/ui/error-codes/E0404.stderr @@ -10,5 +10,6 @@ error[E0404]: expected trait, found struct `Foo` LL | fn baz(_: T) {} //~ ERROR E0404 | ^^^ not a trait -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/error-codes/E0405.stderr b/src/test/ui/error-codes/E0405.stderr index b5901dd9c848b..27190af1c6c11 100644 --- a/src/test/ui/error-codes/E0405.stderr +++ b/src/test/ui/error-codes/E0405.stderr @@ -4,5 +4,6 @@ error[E0405]: cannot find trait `SomeTrait` in this scope LL | impl SomeTrait for Foo {} //~ ERROR E0405 | ^^^^^^^^^ not found in this scope -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr index a9952ff4fac13..a2c1dedff385a 100644 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr +++ b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr @@ -4,3 +4,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr index 4772cf28f6c12..431c57abd2653 100644 --- a/src/test/ui/feature-gate-fn_must_use.stderr +++ b/src/test/ui/feature-gate-fn_must_use.stderr @@ -20,3 +20,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 9c4fb79f6f1aa..0beed62798710 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1316,3 +1316,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr index 83f6e016370bb..802c5d9384d75 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr @@ -6,3 +6,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index a02fc1f748faa..3cc0bebe81655 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -24,5 +24,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::fmt::Debug; | -error: cannot continue compilation due to previous error +error: aborting due to 3 previous errors +Some errors occurred: E0405, E0425. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 257b9bd235d76..aeb465b2ab233 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -89,3 +89,5 @@ error: expected type, found `4` LL | println!("{}", a: &mut 4); //~ ERROR expected type, found `4` | ^ expecting a type here because of type ascription +error: aborting due to 9 previous errors + diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr index 443b28cf09968..de7c11732e4a3 100644 --- a/src/test/ui/issue-44406.stderr +++ b/src/test/ui/issue-44406.stderr @@ -13,3 +13,5 @@ LL | bar(baz: $rest) LL | 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/lint-output-format-2.stderr b/src/test/ui/lint-output-format-2.stderr index b2d1e1ac05822..d484061ef9661 100644 --- a/src/test/ui/lint-output-format-2.stderr +++ b/src/test/ui/lint-output-format-2.stderr @@ -22,3 +22,5 @@ LL | | let _y = bar(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops-reject-duplicate-labels-2.stderr index d35ed4ff88a67..830270a99d112 100644 --- a/src/test/ui/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops-reject-duplicate-labels-2.stderr @@ -70,3 +70,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels.stderr b/src/test/ui/loops-reject-duplicate-labels.stderr index d1b874ea99729..a71f98b812a8c 100644 --- a/src/test/ui/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops-reject-duplicate-labels.stderr @@ -73,3 +73,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr index 0cdd58fdbd75d..af524d5b01766 100644 --- a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr +++ b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr @@ -108,3 +108,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr index a050aec50c72b..999cfb9cc3c6b 100644 --- a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr +++ b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr @@ -14,3 +14,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/macro-context.stderr b/src/test/ui/macro-context.stderr index 4dc6bbe4d656c..b3e67fb2607cd 100644 --- a/src/test/ui/macro-context.stderr +++ b/src/test/ui/macro-context.stderr @@ -43,3 +43,5 @@ LL | () => ( i ; typeof ); //~ ERROR expected expression, found reserved k LL | m!(); | ----- in this macro invocation +error: aborting due to 4 previous errors + 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 06d22714dd8b6..0f9f0607c5bf2 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.stderr +++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr @@ -4,5 +4,6 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m` LL | foo!(m::m2::A); //~ ERROR failed to resolve | ^ Use of undeclared type or module `m` -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 9fb5b17a3114b..a9ffef8ef8090 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -45,3 +45,5 @@ LL | my_recursive_macro!(); = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro ! ( ) ;` +error: aborting due to 2 previous errors + diff --git a/src/test/ui/raw_string.stderr b/src/test/ui/raw_string.stderr index b8aa596ef953a..ddf1cfe406f7c 100644 --- a/src/test/ui/raw_string.stderr +++ b/src/test/ui/raw_string.stderr @@ -6,3 +6,5 @@ LL | let x = r##"lol"#; | = note: this raw string should be terminated with `"##` +error: aborting due to previous error + diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index a9d2aeee2d151..3edfa33d80a02 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -45,5 +45,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Div; | -error: cannot continue compilation due to previous error +error: aborting due to 4 previous errors +Some errors occurred: E0405, E0412. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index c61ffe3b33e8a..e11fe9ac4cf11 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use foo::bar::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index 7725f74cb49fc..f406cd6e35fcf 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_3::outer::OuterTrait; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index b0a4d5ba4d898..c0a7f1734f49c 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_4::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 2b8b2b20685f8..3627c09b28fd9 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use issue_3907::Foo; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 6597f05889af8..353a0b1c3d9d0 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -13,5 +13,7 @@ LL | impl K for isize {} //~ ERROR expected trait, found type alias `K` | did you mean `I`? | type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0432. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 6e7bd28d16fc3..f32c5e9b2c6bd 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -10,5 +10,7 @@ error[E0404]: expected trait, found type alias `Typedef` LL | fn g isize>(x: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0405. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr index bb55d86f620b7..e69de29bb2d1d 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr @@ -1,2 +0,0 @@ -error: cannot continue compilation due to previous error - diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 6a4ec73b27a66..b496a1a76c017 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -36,3 +36,5 @@ LL | | println!("{}", theTwo); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 2d4a7cc72f5f6..1dd45bb1e5efe 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. From ea6a1bdf6ba754f3b96e3a46f9173b17ff18ed07 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 10:46:06 +0000 Subject: [PATCH 049/546] Compute each key only one during slice::sort_by_key --- src/liballoc/slice.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index dc40062ef13df..c57f1e7f57297 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1328,10 +1328,18 @@ impl [T] { /// ``` #[stable(feature = "slice_sort_by_key", since = "1.7.0")] #[inline] - pub fn sort_by_key(&mut self, mut f: F) + pub fn sort_by_key(&mut self, f: F) where F: FnMut(&T) -> B, B: Ord { - merge_sort(self, |a, b| f(a).lt(&f(b))); + let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); + indices.sort(); + for i in 0..self.len() { + let mut index = indices[i].1; + while index < i { + index = indices[index].1; + } + self.swap(i, index); + } } /// Sorts the slice, but may not preserve the order of equal elements. From 670e69e20753e2ef33ee61b0515092cace3fd716 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 12:15:05 +0000 Subject: [PATCH 050/546] Update documentation for sort_by_key --- src/liballoc/slice.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index c57f1e7f57297..db3b14859dddb 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1302,11 +1302,9 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. - /// - /// When applicable, unstable sorting is preferred because it is generally faster than stable - /// sorting and it doesn't allocate auxiliary memory. - /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key). + /// During sorting, the key function is called only once per element. + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` + /// worst-case, where the key function is `O(m)`. /// /// # Current implementation /// @@ -1315,8 +1313,7 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// Also, it allocates temporary storage half the size of `self`, but for short slices a - /// non-allocating insertion sort is used instead. + /// The algorithm allocates temporary storage the size of `self`. /// /// # Examples /// From b8452cc3266f2d9567b5c07ca3044b3960e10ebf Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 12:22:11 +0000 Subject: [PATCH 051/546] Clarify behaviour of sort_unstable_by_key with respect to sort_by_key --- src/liballoc/slice.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db3b14859dddb..63b22bd0f6d87 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1303,6 +1303,7 @@ impl [T] { /// Sorts the slice with a key extraction function. /// /// During sorting, the key function is called only once per element. + /// /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` /// worst-case, where the key function is `O(m)`. /// @@ -1329,7 +1330,10 @@ impl [T] { where F: FnMut(&T) -> B, B: Ord { let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); - indices.sort(); + // The elements of `indices` are unique, as they are indexed, so any sort will be stable + // with respect to the original slice. We use `sort_unstable` here because it requires less + // memory allocation. + indices.sort_unstable(); for i in 0..self.len() { let mut index = indices[i].1; while index < i { @@ -1414,8 +1418,11 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// + /// Note that, currently, the key function for `sort_unstable_by_key` is called multiple times + /// per element, unlike `sort_stable_by_key`. + /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), - /// and `O(n log n)` worst-case. + /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. /// /// # Current implementation /// @@ -1425,8 +1432,8 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// It is typically faster than stable sorting, except in a few special cases, e.g. when the - /// slice consists of several concatenated sorted sequences. + /// Due to its key calling strategy, `sort_unstable_by_key` is likely to be slower than + /// `sort_by_key` in cases where the key function is expensive. /// /// # Examples /// From 9fbee359d7eb3a621604bc2067a375f6d4b757e5 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 13:39:52 +0000 Subject: [PATCH 052/546] Add a test for sort_by_key --- src/liballoc/tests/slice.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index d9e9d91cea88a..300f6abaa7f1b 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -425,6 +425,11 @@ fn test_sort() { v.sort_by(|a, b| b.cmp(a)); assert!(v.windows(2).all(|w| w[0] >= w[1])); + // Sort in lexicographic order. + let mut v = orig.clone(); + v.sort_by_key(|x| x.to_string()); + assert!(v.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + // Sort with many pre-sorted runs. let mut v = orig.clone(); v.sort(); From 21fde0903b394ca4765b17321a736983c43886cb Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 16:07:58 +0000 Subject: [PATCH 053/546] Update documentation --- src/liballoc/slice.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 63b22bd0f6d87..32ade0b017833 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1314,7 +1314,7 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// The algorithm allocates temporary storage the size of `self`. + /// The algorithm allocates temporary storage in a `Vec<(K, usize)` the length of the slice. /// /// # Examples /// @@ -1326,8 +1326,8 @@ impl [T] { /// ``` #[stable(feature = "slice_sort_by_key", since = "1.7.0")] #[inline] - pub fn sort_by_key(&mut self, f: F) - where F: FnMut(&T) -> B, B: Ord + pub fn sort_by_key(&mut self, f: F) + where F: FnMut(&T) -> K, K: Ord { let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); // The elements of `indices` are unique, as they are indexed, so any sort will be stable @@ -1418,8 +1418,8 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// - /// Note that, currently, the key function for `sort_unstable_by_key` is called multiple times - /// per element, unlike `sort_stable_by_key`. + /// Note that, currently, the key function for [`sort_unstable_by_key`] is called multiple times + /// per element, unlike [`sort_by_key`]. /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. @@ -1432,8 +1432,8 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// Due to its key calling strategy, `sort_unstable_by_key` is likely to be slower than - /// `sort_by_key` in cases where the key function is expensive. + /// Due to its key calling strategy, [`sort_unstable_by_key`] is likely to be slower than + /// [`sort_by_key`] in cases where the key function is expensive. /// /// # Examples /// @@ -1444,12 +1444,13 @@ impl [T] { /// assert!(v == [1, 2, -3, 4, -5]); /// ``` /// + /// [`sort_by_key`]: #method.sort_by_key + /// [`sort_unstable_by_key`]: #method.sort_unstable_by_key /// [pdqsort]: https://github.com/orlp/pdqsort #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] - pub fn sort_unstable_by_key(&mut self, f: F) - where F: FnMut(&T) -> B, - B: Ord + pub fn sort_unstable_by_key(&mut self, f: F) + where F: FnMut(&T) -> K, K: Ord { core_slice::SliceExt::sort_unstable_by_key(self, f); } From 7dcfc07d2c441e6e18c34dfe844c7bdc1c0137fe Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 2 Mar 2018 15:51:20 +0000 Subject: [PATCH 054/546] Cull the quadratic --- src/liballoc/slice.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 32ade0b017833..3fa5e78c04f4e 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1339,6 +1339,7 @@ impl [T] { while index < i { index = indices[index].1; } + indices[i].1 = index; self.swap(i, index); } } From bdcc6f939a10bc23a434b2ef301238650841dec9 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 2 Mar 2018 16:28:55 +0000 Subject: [PATCH 055/546] Index enumeration by minimally sized type --- src/liballoc/slice.rs | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 3fa5e78c04f4e..fbd8d87930842 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -102,6 +102,7 @@ use core::mem::size_of; use core::mem; use core::ptr; use core::slice as core_slice; +use core::{u8, u16, u32}; use borrow::{Borrow, BorrowMut, ToOwned}; use boxed::Box; @@ -1329,19 +1330,31 @@ impl [T] { pub fn sort_by_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord { - let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); - // The elements of `indices` are unique, as they are indexed, so any sort will be stable - // with respect to the original slice. We use `sort_unstable` here because it requires less - // memory allocation. - indices.sort_unstable(); - for i in 0..self.len() { - let mut index = indices[i].1; - while index < i { - index = indices[index].1; - } - indices[i].1 = index; - self.swap(i, index); + // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. + macro_rules! sort_by_key { + ($t:ty, $slice:ident, $f:ident) => ({ + let mut indices: Vec<_> = + $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect(); + // The elements of `indices` are unique, as they are indexed, so any sort will be + // stable with respect to the original slice. We use `sort_unstable` here because it + // requires less memory allocation. + indices.sort_unstable(); + for i in 0..$slice.len() { + let mut index = indices[i].1; + while (index as usize) < i { + index = indices[index as usize].1; + } + indices[i].1 = index; + $slice.swap(i, index as usize); + } + }) } + + let len = self.len(); + if len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } + if len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } + if len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } + sort_by_key!(usize, self, f) } /// Sorts the slice, but may not preserve the order of equal elements. From f41a26f2040dfa752825a7d1fdfbd5a8ae3310cf Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 16 Mar 2018 14:37:17 +0000 Subject: [PATCH 056/546] Add sort_by_cached_key method --- src/liballoc/slice.rs | 61 ++++++++++++++++++++++++++++++------- src/liballoc/tests/slice.rs | 9 ++++-- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index fbd8d87930842..306c467f048cb 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1301,6 +1301,45 @@ impl [T] { merge_sort(self, |a, b| compare(a, b) == Less); } + /// Sorts the slice with a key extraction function. + /// + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log m n)` + /// worst-case, where the key function is `O(m)`. + /// + /// For expensive key functions (e.g. functions that are not simple property accesses or + /// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be + /// significantly faster, as it does not recompute element keys. + /// + /// When applicable, unstable sorting is preferred because it is generally faster than stable + /// sorting and it doesn't allocate auxiliary memory. + /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key). + /// + /// # Current implementation + /// + /// The current algorithm is an adaptive, iterative merge sort inspired by + /// [timsort](https://en.wikipedia.org/wiki/Timsort). + /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of + /// two or more sorted sequences concatenated one after another. + /// + /// Also, it allocates temporary storage half the size of `self`, but for short slices a + /// non-allocating insertion sort is used instead. + /// + /// # Examples + /// + /// ``` + /// let mut v = [-5i32, 4, 1, -3, 2]; + /// + /// v.sort_by_key(|k| k.abs()); + /// assert!(v == [1, 2, -3, 4, -5]); + /// ``` + #[stable(feature = "slice_sort_by_key", since = "1.7.0")] + #[inline] + pub fn sort_by_key(&mut self, mut f: F) + where F: FnMut(&T) -> K, K: Ord + { + merge_sort(self, |a, b| f(a).lt(&f(b))); + } + /// Sorts the slice with a key extraction function. /// /// During sorting, the key function is called only once per element. @@ -1308,6 +1347,10 @@ impl [T] { /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` /// worst-case, where the key function is `O(m)`. /// + /// For simple key functions (e.g. functions that are property accesses or + /// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be + /// faster. + /// /// # Current implementation /// /// The current algorithm is an adaptive, iterative merge sort inspired by @@ -1315,19 +1358,19 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// The algorithm allocates temporary storage in a `Vec<(K, usize)` the length of the slice. + /// The algorithm allocates temporary storage in a `Vec<(K, usize)>` the length of the slice. /// /// # Examples /// /// ``` /// let mut v = [-5i32, 4, 1, -3, 2]; /// - /// v.sort_by_key(|k| k.abs()); + /// v.sort_by_cached_key(|k| k.abs()); /// assert!(v == [1, 2, -3, 4, -5]); /// ``` - #[stable(feature = "slice_sort_by_key", since = "1.7.0")] + #[unstable(feature = "slice_sort_by_uncached_key", issue = "34447")] #[inline] - pub fn sort_by_key(&mut self, f: F) + pub fn sort_by_cached_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord { // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. @@ -1432,9 +1475,6 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// - /// Note that, currently, the key function for [`sort_unstable_by_key`] is called multiple times - /// per element, unlike [`sort_by_key`]. - /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. /// @@ -1446,8 +1486,9 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// Due to its key calling strategy, [`sort_unstable_by_key`] is likely to be slower than - /// [`sort_by_key`] in cases where the key function is expensive. + /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key) + /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_uncached_key) in + /// cases where the key function is expensive. /// /// # Examples /// @@ -1458,8 +1499,6 @@ impl [T] { /// assert!(v == [1, 2, -3, 4, -5]); /// ``` /// - /// [`sort_by_key`]: #method.sort_by_key - /// [`sort_unstable_by_key`]: #method.sort_unstable_by_key /// [pdqsort]: https://github.com/orlp/pdqsort #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 300f6abaa7f1b..7d4dac1c5ec99 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -426,9 +426,12 @@ fn test_sort() { assert!(v.windows(2).all(|w| w[0] >= w[1])); // Sort in lexicographic order. - let mut v = orig.clone(); - v.sort_by_key(|x| x.to_string()); - assert!(v.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + let mut v1 = orig.clone(); + let mut v2 = orig.clone(); + v1.sort_by_key(|x| x.to_string()); + v2.sort_by_cached_key(|x| x.to_string()); + assert!(v1.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + assert!(v1 == v2); // Sort with many pre-sorted runs. let mut v = orig.clone(); From 15bab452f30ce6cb67a849f13e9de80586a8b180 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 15 Mar 2018 14:14:48 +0800 Subject: [PATCH 057/546] Add From for TryFromIntError --- src/libcore/num/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index faeb87cf944c9..4583e45bb12eb 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3595,6 +3595,13 @@ impl fmt::Display for TryFromIntError { } } +#[unstable(feature = "try_from", issue = "33417")] +impl From for TryFromIntError { + fn from(never: !) -> TryFromIntError { + never + } +} + // no possible bounds violation macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( From f9d38451382017a6cd053e25011e4c096d545d17 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 13:38:06 -0500 Subject: [PATCH 058/546] talk about --crate-version --- src/doc/rustdoc/src/unstable-features.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 9cb5760ec3797..867e4585d9c1e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -254,3 +254,15 @@ If both `--playground-url` and `--markdown-playground-url` are present when rend Markdown file, the URL given to `--markdown-playground-url` will take precedence. If both `--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, the attribute will take precedence. + +### `--crate-version`: control the crate version + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --crate-version 1.3.37 +``` + +When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of +the crate root's docs. You can use this flag to differentiate between different versions of your +library's documentation. From 33ed787b495477f2cc859b275a1deb6dc1a396a0 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 13:46:10 -0500 Subject: [PATCH 059/546] talk about --linker --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 867e4585d9c1e..870d77895fd6e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -266,3 +266,16 @@ $ rustdoc src/lib.rs -Z unstable-options --crate-version 1.3.37 When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of the crate root's docs. You can use this flag to differentiate between different versions of your library's documentation. + +### `--linker`: control the linker used for documentation tests + +Using this flag looks like this: + +```bash +$ rustdoc --test src/lib.rs -Z unstable-options --linker foo +$ rustdoc --test README.md -Z unstable-options --linker foo +``` + +When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables +before running them. This flag can be used to change the linker used on these executables. It's +equivalent to passing `-C linker=foo` to `rustc`. From cc4f97e88354bea5d07c3ae762ac0466e5c9888c Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 14:30:56 -0500 Subject: [PATCH 060/546] talk about --sort-modules-by-appearance --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 870d77895fd6e..80b59166503fa 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -279,3 +279,16 @@ $ rustdoc --test README.md -Z unstable-options --linker foo When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables before running them. This flag can be used to change the linker used on these executables. It's equivalent to passing `-C linker=foo` to `rustc`. + +### `--sort-modules-by-appearance`: control how items on module pages are sorted + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --sort-modules-by-appearance +``` + +Ordinarily, when `rustdoc` prints items in module pages, it will sort them alphabetically (taking +some consideration for their stability, and names that end in a number). Giving this flag to +`rustdoc` will disable this sorting and instead make it print the items in the order they appear in +the source. From 6b2906018f93a9813392056da4c3de855d92f619 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 14:41:51 -0500 Subject: [PATCH 061/546] talk about --themes and --theme-checker --- src/doc/rustdoc/src/unstable-features.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 80b59166503fa..3ebc2fa466cb6 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -292,3 +292,27 @@ Ordinarily, when `rustdoc` prints items in module pages, it will sort them alpha some consideration for their stability, and names that end in a number). Giving this flag to `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. + +### `--themes`: provide additional themes + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --themes theme.css +``` + +Giving this flag to `rustdoc` will make it copy your theme into the generated crate docs and enable +it in the theme selector. Note that `rustdoc` will reject your theme file if it doesn't style +everything the "main" theme does. See `--theme-checker` below for details. + +### `--theme-checker`: verify theme CSS for validity + +Using this flag looks like this: + +```bash +$ rustdoc -Z unstable-options --theme-checker theme.css +``` + +Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains +against the "main" theme included by default. Using this flag will allow you to see which rules are +missing if `rustdoc` rejects your theme. From b5ab5ceb4b2aa733366ed9453c0e714d6f0cd9f0 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 15:06:36 -0500 Subject: [PATCH 062/546] talk about --resource-suffix --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3ebc2fa466cb6..93489f89626fe 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -316,3 +316,16 @@ $ rustdoc -Z unstable-options --theme-checker theme.css Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains against the "main" theme included by default. Using this flag will allow you to see which rules are missing if `rustdoc` rejects your theme. + +### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --resource-suffix suf +``` + +When rendering docs, `rustdoc` creates several CSS and JavaScript files as part of the output. Since +all these files are linked from every page, changing where they are can be cumbersome if you need to +specially cache them. This flag will rename all these files in the output to include the suffix in +the filename. For example, `main.css` would become `main-suf.css` with the above command. From 9e6268191205c42bc7958d949fa48811d60857f9 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 10:32:29 +0900 Subject: [PATCH 063/546] Remove core::fmt::num::Decimal Before ebf9e1aaf6, it was used for Display::fmt, but ebf9e1aaf6 replaced that with a faster implementation, and nothing else uses it. --- src/libcore/fmt/num.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db34..57e3b849ae1e3 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -107,10 +107,6 @@ struct Binary; #[derive(Clone, PartialEq)] struct Octal; -/// A decimal (base 10) radix -#[derive(Clone, PartialEq)] -struct Decimal; - /// A hexadecimal (base 16) radix, formatted with lower-case characters #[derive(Clone, PartialEq)] struct LowerHex; @@ -136,7 +132,6 @@ macro_rules! radix { radix! { Binary, 2, "0b", x @ 0 ... 1 => b'0' + x } radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x } -radix! { Decimal, 10, "", x @ 0 ... 9 => b'0' + x } radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x, x @ 10 ... 15 => b'a' + (x - 10) } radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, From 38cbdcd0b1791e68c9485d8db6e81cf2d6765572 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 10:42:32 +0900 Subject: [PATCH 064/546] Use an uninitialized buffer in GenericRadix::fmt_int, like in Display::fmt for numeric types The code using a slice of that buffer is only ever going to use bytes that are subsequently initialized. --- src/libcore/fmt/num.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db34..c3843cae27af5 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -65,7 +65,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf = [0; 128]; + let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; let mut curr = buf.len(); let base = T::from_u8(self.base()); if is_nonnegative { From e09dbbc39eeecbf6a8122d86297a1e8701aca26b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 10:05:23 +0100 Subject: [PATCH 065/546] Add an example of lossy decoding to str::Utf8Error docs --- src/libcore/str/mod.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 9cf862bd93625..1185b7acaae1f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -165,6 +165,37 @@ Section: Creating a string /// /// [`String`]: ../../std/string/struct.String.html#method.from_utf8 /// [`&str`]: ../../std/str/fn.from_utf8.html +/// +/// # Examples +/// +/// This error type’s methods can be used to create functionality +/// similar to `String::from_utf8_lossy` without allocating heap memory: +/// +/// ``` +/// fn from_utf8_lossy(mut input: &[u8], mut push: F) where F: FnMut(&str) { +/// loop { +/// match ::std::str::from_utf8(input) { +/// Ok(valid) => { +/// push(valid); +/// break +/// } +/// Err(error) => { +/// let (valid, after_valid) = input.split_at(error.valid_up_to()); +/// unsafe { +/// push(::std::str::from_utf8_unchecked(valid)) +/// } +/// push("\u{FFFD}"); +/// +/// if let Some(invalid_sequence_length) = error.error_len() { +/// input = &after_valid[invalid_sequence_length..] +/// } else { +/// break +/// } +/// } +/// } +/// } +/// } +/// ``` #[derive(Copy, Eq, PartialEq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Utf8Error { From f53d4af223a5301daa6123c7b1e4cba108700db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Feb 2018 10:40:02 +0100 Subject: [PATCH 066/546] Remove unused imports --- src/test/run-pass-fulldeps/issue-35829.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs index c420243325038..798c214bc4715 100644 --- a/src/test/run-pass-fulldeps/issue-35829.rs +++ b/src/test/run-pass-fulldeps/issue-35829.rs @@ -20,8 +20,7 @@ use syntax::ext::expand::ExpansionConfig; use syntax::parse::ParseSess; use syntax::codemap::{FilePathMapping, dummy_spanned}; use syntax::print::pprust::expr_to_string; -use syntax::ast::{Expr, ExprKind, LitKind, StrStyle, RangeLimits}; -use syntax::symbol::Symbol; +use syntax::ast::{ExprKind, LitKind, RangeLimits}; use syntax::ptr::P; use rustc_data_structures::sync::Lrc; From b430cba343743783cee517bf93c7f255827cccc5 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 16 Mar 2018 16:35:27 +0000 Subject: [PATCH 067/546] Fix use of unstable feature in test --- src/liballoc/lib.rs | 1 + src/liballoc/slice.rs | 4 ++-- src/liballoc/tests/lib.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b93e128d50819..253b8acc16c42 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,6 +113,7 @@ #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] +#![feature(slice_sort_by_cached_key)] #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 306c467f048cb..db8900664476e 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1368,7 +1368,7 @@ impl [T] { /// v.sort_by_cached_key(|k| k.abs()); /// assert!(v == [1, 2, -3, 4, -5]); /// ``` - #[unstable(feature = "slice_sort_by_uncached_key", issue = "34447")] + #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")] #[inline] pub fn sort_by_cached_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord @@ -1487,7 +1487,7 @@ impl [T] { /// deterministic behavior. /// /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key) - /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_uncached_key) in + /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_cached_key) in /// cases where the key function is expensive. /// /// # Examples diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 285cba0270c03..27f3028a51343 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -23,6 +23,7 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(rand)] +#![feature(slice_sort_by_cached_key)] #![feature(splice)] #![feature(str_escape)] #![feature(string_retain)] From 6fd4d67819a6eb8273768b6c3789ca70582cd703 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 08:35:03 -0700 Subject: [PATCH 068/546] rustbuild: Tweak where timing information goes This commit tweaks where timing and step information is printed out as part of the build, ensuring that we do it as close to the location where work happens as possible. In rustbuild various functions may perform long blocking work as dependencies are assembled, so if we print out timing information early on we may accidentally time more than just the step we were intending to time! --- src/bootstrap/check.rs | 20 +++++++++------ src/bootstrap/compile.rs | 27 ++++++++++---------- src/bootstrap/test.rs | 55 ++++++++++++++++++++-------------------- src/bootstrap/tool.rs | 12 ++++----- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 33bcfaa80ca31..a9dccea827b6e 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -40,17 +40,18 @@ impl Step for Std { let target = self.target; let compiler = builder.compiler(0, build.build); - let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); - println!("Checking std artifacts ({} -> {})", &compiler.host, target); - let out_dir = build.stage_out(compiler, Mode::Libstd); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check"); std_cargo(builder, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); + println!("Checking std artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &libstd_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target)); } @@ -86,19 +87,20 @@ impl Step for Rustc { let compiler = builder.compiler(0, build.build); let target = self.target; - let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); - println!("Checking compiler artifacts ({} -> {})", &compiler.host, target); - let stage_out = builder.stage_out(compiler, Mode::Librustc); build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target)); build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check"); rustc_cargo(build, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); + println!("Checking compiler artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &librustc_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &librustc_stamp(build, compiler, target)); } @@ -128,16 +130,18 @@ impl Step for Test { let target = self.target; let compiler = builder.compiler(0, build.build); - let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); - println!("Checking test artifacts ({} -> {})", &compiler.host, target); let out_dir = build.stage_out(compiler, Mode::Libtest); build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check"); test_cargo(build, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); + println!("Checking test artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &libtest_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &libtest_stamp(build, compiler, target)); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 86263c8fa0733..d697403180c18 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -93,10 +93,6 @@ impl Step for Std { return; } - let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); - println!("Building stage{} std artifacts ({} -> {})", compiler.stage, - &compiler.host, target); - if target.contains("musl") { let libdir = builder.sysroot_libdir(compiler, target); copy_musl_third_party_objects(build, target, &libdir); @@ -106,6 +102,10 @@ impl Step for Std { build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); + println!("Building stage{} std artifacts ({} -> {})", compiler.stage, + &compiler.host, target); run_cargo(build, &mut cargo, &libstd_stamp(build, compiler, target), @@ -360,13 +360,14 @@ impl Step for Test { return; } - let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); - println!("Building stage{} test artifacts ({} -> {})", compiler.stage, - &compiler.host, target); let out_dir = build.stage_out(compiler, Mode::Libtest); build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build"); test_cargo(build, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); + println!("Building stage{} test artifacts ({} -> {})", compiler.stage, + &compiler.host, target); run_cargo(build, &mut cargo, &libtest_stamp(build, compiler, target), @@ -482,16 +483,16 @@ impl Step for Rustc { target: build.build, }); - let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); - println!("Building stage{} compiler artifacts ({} -> {})", - compiler.stage, &compiler.host, target); - let stage_out = builder.stage_out(compiler, Mode::Librustc); build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target)); build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build"); rustc_cargo(build, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); + println!("Building stage{} compiler artifacts ({} -> {})", + compiler.stage, &compiler.host, target); run_cargo(build, &mut cargo, &librustc_stamp(build, compiler, target), @@ -634,8 +635,6 @@ impl Step for CodegenBackend { .arg(build.src.join("src/librustc_trans/Cargo.toml")); rustc_cargo_env(build, &mut cargo); - let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); - match &*self.backend { "llvm" | "emscripten" => { // Build LLVM for our target. This will implicitly build the @@ -685,6 +684,8 @@ impl Step for CodegenBackend { let tmp_stamp = build.cargo_out(compiler, Mode::Librustc, target) .join(".tmp.stamp"); + + let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); let files = run_cargo(build, cargo.arg("--features").arg(features), &tmp_stamp, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de938ec8e8306..e129ae8c52105 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -530,8 +530,6 @@ impl Step for Tidy { fn run(self, builder: &Builder) { let build = builder.build; - let _folder = build.fold_output(|| "tidy"); - println!("tidy check"); let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(build.src.join("src")); cmd.arg(&build.initial_cargo); @@ -541,6 +539,9 @@ impl Step for Tidy { if build.config.quiet_tests { cmd.arg("--quiet"); } + + let _folder = build.fold_output(|| "tidy"); + println!("tidy check"); try_run(build, &mut cmd); } @@ -836,9 +837,6 @@ impl Step for Compiletest { builder.ensure(native::TestHelpers { target }); builder.ensure(RemoteCopyLibs { compiler, target }); - let _folder = build.fold_output(|| format!("test_{}", suite)); - println!("Check compiletest suite={} mode={} ({} -> {})", - suite, mode, &compiler.host, target); let mut cmd = builder.tool_cmd(Tool::Compiletest); // compiletest currently has... a lot of arguments, so let's just pass all @@ -998,6 +996,9 @@ impl Step for Compiletest { build.ci_env.force_coloring_in_ci(&mut cmd); + let _folder = build.fold_output(|| format!("test_{}", suite)); + println!("Check compiletest suite={} mode={} ({} -> {})", + suite, mode, &compiler.host, target); let _time = util::timeit(); try_run(build, &mut cmd); } @@ -1142,20 +1143,21 @@ impl Step for ErrorIndex { builder.ensure(compile::Std { compiler, target: compiler.host }); - let _folder = build.fold_output(|| "test_error_index"); - println!("Testing error-index stage{}", compiler.stage); - let dir = testdir(build, compiler.host); t!(fs::create_dir_all(&dir)); let output = dir.join("error-index.md"); - let _time = util::timeit(); - build.run(builder.tool_cmd(Tool::ErrorIndex) - .arg("markdown") - .arg(&output) - .env("CFG_BUILD", &build.build) - .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir())); + let mut tool = builder.tool_cmd(Tool::ErrorIndex); + tool.arg("markdown") + .arg(&output) + .env("CFG_BUILD", &build.build) + .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir()); + + let _folder = build.fold_output(|| "test_error_index"); + println!("Testing error-index stage{}", compiler.stage); + let _time = util::timeit(); + build.run(&mut tool); markdown_test(builder, compiler, &output); } } @@ -1400,11 +1402,6 @@ impl Step for Crate { } _ => panic!("can only test libraries"), }; - let _folder = build.fold_output(|| { - format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate) - }); - println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage, - &compiler.host, target); // Build up the base `cargo test` command. // @@ -1436,8 +1433,6 @@ impl Step for Crate { cargo.arg("--quiet"); } - let _time = util::timeit(); - if target.contains("emscripten") { cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)), build.config.nodejs.as_ref().expect("nodejs not configured")); @@ -1465,6 +1460,13 @@ impl Step for Crate { format!("{} run", builder.tool_exe(Tool::RemoteTestClient).display())); } + + let _folder = build.fold_output(|| { + format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate) + }); + println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage, + &compiler.host, target); + let _time = util::timeit(); try_run(build, &mut cargo); } } @@ -1513,12 +1515,6 @@ impl Step for CrateRustdoc { target, test_kind.subcommand(), "src/tools/rustdoc"); - let _folder = build.fold_output(|| { - format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage) - }); - println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage, - &compiler.host, target); - if test_kind.subcommand() == "test" && !build.fail_fast { cargo.arg("--no-fail-fast"); } @@ -1532,6 +1528,11 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } + let _folder = build.fold_output(|| { + format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage) + }); + println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage, + &compiler.host, target); let _time = util::timeit(); try_run(build, &mut cargo); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 5f5b10a07b865..d308cecb27521 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -112,11 +112,11 @@ impl Step for ToolBuild { Mode::Tool => panic!("unexpected Mode::Tool for tool build") } - let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); - println!("Building stage{} tool {} ({})", compiler.stage, tool, target); - let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path); cargo.arg("--features").arg(self.extra_features.join(" ")); + + let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); + println!("Building stage{} tool {} ({})", compiler.stage, tool, target); let is_expected = build.try_run(&mut cargo); build.save_toolstate(tool, if is_expected { ToolState::TestFail @@ -339,9 +339,6 @@ impl Step for Rustdoc { builder.ensure(compile::Rustc { compiler: build_compiler, target }); - let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); - println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host); - let mut cargo = prepare_tool_cargo(builder, build_compiler, target, @@ -352,7 +349,10 @@ impl Step for Rustdoc { cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string()) .env("RUSTC_DEBUGINFO_LINES", builder.config.rust_debuginfo_lines.to_string()); + let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); + println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host); build.run(&mut cargo); + // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" // rustdoc a different name. From 7278e37d38226734dabf07b4453580868847edf6 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 9 Dec 2017 22:16:54 +0200 Subject: [PATCH 069/546] update FIXME(#6393) to point to issue 43234 (tracking issue for non-lexical lifetimes) --- src/libcore/iter/mod.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index b1b783b47c72b..1e8476d3880c8 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1872,7 +1872,7 @@ impl Iterator for Peekable { #[inline] fn nth(&mut self, n: usize) -> Option { - // FIXME(#6393): merge these when borrow-checking gets better. + // FIXME(#43234): merge these when borrow-checking gets better. if n == 0 { match self.peeked.take() { Some(v) => v, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index e95126c8a1a0f..19f33ef5d45a8 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -177,7 +177,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }); } DropStyle::Conditional => { - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind); self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto { @@ -268,7 +268,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> // Clear the "master" drop flag at the end. This is needed // because the "master" drop protects the ADT's discriminant, // which is invalidated after the ADT is dropped. - let (succ, unwind) = (self.succ, self.unwind); // FIXME(#6393) + let (succ, unwind) = (self.succ, self.unwind); // FIXME(#43234) ( self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind), unwind.map(|unwind| { @@ -344,7 +344,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let interior = self.place.clone().deref(); let interior_path = self.elaborator.deref_subpath(self.path); - let succ = self.succ; // FIXME(#6393) + let succ = self.succ; // FIXME(#43234) let unwind = self.unwind; let succ = self.box_free_block(ty, succ, unwind); let unwind_succ = self.unwind.map(|unwind| { @@ -717,7 +717,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> ptr_based) }); - let succ = self.succ; // FIXME(#6393) + let succ = self.succ; // FIXME(#43234) let loop_block = self.drop_loop( succ, cur, @@ -798,7 +798,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> self.open_drop_for_adt(def, substs) } ty::TyDynamic(..) => { - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; self.complete_drop(Some(DropFlagMode::Deep), succ, unwind) } @@ -849,7 +849,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> fn elaborated_drop_block<'a>(&mut self) -> BasicBlock { debug!("elaborated_drop_block({:?})", self); - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; let blk = self.drop_block(succ, unwind); self.elaborate_drop(blk); @@ -882,7 +882,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> args: vec![Operand::Move(self.place.clone())], destination: Some((unit_temp, target)), cleanup: None - }; // FIXME(#6393) + }; // FIXME(#43234) let free_block = self.new_block(unwind, call); let block_start = Location { block: free_block, statement_index: 0 }; From ba836f4b5fedf09418a6dbe9fb1f59b0ef7bd587 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 00:44:58 +0200 Subject: [PATCH 070/546] update FIXME(#15760) to point to issue 27336 (tracking issue for Default Type Parameter Fallback) --- src/librustc_typeck/check/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc9455487ede7..f0f1064752d4a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2869,7 +2869,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let origin = self.misc(call_span); let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret); - // FIXME(#15760) can't use try! here, FromError doesn't default + // FIXME(#27336) can't use ? here, Try::from_error doesn't default // to identity so the resulting type is not constrained. match ures { Ok(ok) => { @@ -2877,19 +2877,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // we can. We don't care if some things turn // out unconstrained or ambiguous, as we're // just trying to get hints here. - let result = self.save_and_restore_in_snapshot_flag(|_| { + self.save_and_restore_in_snapshot_flag(|_| { let mut fulfill = FulfillmentContext::new(); let ok = ok; // FIXME(#30046) for obligation in ok.obligations { fulfill.register_predicate_obligation(self, obligation); } fulfill.select_where_possible(self) - }); - - match result { - Ok(()) => { } - Err(_) => return Err(()), - } + }).map_err(|_| ())?; } Err(_) => return Err(()), } From d1dacddfc7e1b0d897b8d6a4153c2fb8758eaee1 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 02:08:09 +0200 Subject: [PATCH 071/546] update FIXME(#7622) to point to issue 44580 (tracking issue for const generics) --- src/test/run-pass/issue-28561.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/issue-28561.rs b/src/test/run-pass/issue-28561.rs index 8c73830f4d778..e21e487fedd1c 100644 --- a/src/test/run-pass/issue-28561.rs +++ b/src/test/run-pass/issue-28561.rs @@ -45,7 +45,7 @@ struct Array { f32: [T; 32], } -// FIXME(#7622): merge with `Array` once `[T; N]: Clone` where `T: Clone` +// FIXME(#44580): merge with `Array` once `[T; N]: Clone` where `T: Clone` #[derive(Clone, Copy)] struct CopyArray { f00: [T; 00], From e1b9bf07022d18fb44aeb3dd3870952f1bc17619 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 11:04:33 +0200 Subject: [PATCH 072/546] update FIXME(#23442) to point to issue 45742 (Blanket impl of AsRef for Deref) --- src/libcore/convert.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index d3a83dc795c85..2206910c93f61 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -382,7 +382,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a mut T where T: AsRef } } -// FIXME (#23442): replace the above impls for &/&mut with the following more general one: +// FIXME (#45742): replace the above impls for &/&mut with the following more general one: // // As lifts over Deref // impl AsRef for D where D::Target: AsRef { // fn as_ref(&self) -> &U { @@ -399,7 +399,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsMut for &'a mut T where T: AsMut } } -// FIXME (#23442): replace the above impl for &mut with the following more general one: +// FIXME (#45742): replace the above impl for &mut with the following more general one: // // AsMut lifts over DerefMut // impl AsMut for D where D::Target: AsMut { // fn as_mut(&mut self) -> &mut U { From 3753e1a55a2ed118121779e05f77164da3269a86 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:09:36 +0200 Subject: [PATCH 073/546] update FIXME(#5244) to point to RFC 1109 (Non-Copy array creation ergonomics) --- src/liballoc/tests/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index d9e9d91cea88a..3f679d81f08de 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1351,7 +1351,7 @@ fn test_copy_from_slice_dst_shorter() { const MAX_LEN: usize = 80; static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ - // FIXME #5244: AtomicUsize is not Copy. + // FIXME(RFC 1109): AtomicUsize is not Copy. AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), From 4a06708d30cc744583a3bce5508347977de6ac8c Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 9 Dec 2017 21:46:25 +0200 Subject: [PATCH 074/546] remove FIXME(#39119) and allow running test on emscripten --- src/libstd/num.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/num.rs b/src/libstd/num.rs index a2c133954a327..33d7053852246 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -169,7 +169,6 @@ mod tests { macro_rules! test_checked_next_power_of_two { ($test_name:ident, $T:ident) => ( - #[cfg_attr(target_os = "emscripten", ignore)] // FIXME(#39119) fn $test_name() { #![test] assert_eq!((0 as $T).checked_next_power_of_two(), Some(1)); From 622c44510fcc65ad4038beb1714cf8950f96a2a0 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sun, 10 Dec 2017 00:10:43 +0200 Subject: [PATCH 075/546] remove FIXME(#37712) and implement ItemLikeVisitor instead of Visitor --- src/librustc_trans_utils/symbol_names_test.rs | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/librustc_trans_utils/symbol_names_test.rs b/src/librustc_trans_utils/symbol_names_test.rs index 267c8d2bd03c8..47bbd67fb5c70 100644 --- a/src/librustc_trans_utils/symbol_names_test.rs +++ b/src/librustc_trans_utils/symbol_names_test.rs @@ -15,7 +15,6 @@ //! paths etc in all kinds of annoying scenarios. use rustc::hir; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::ty::TyCtxt; use syntax::ast; @@ -34,8 +33,7 @@ pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { let mut visitor = SymbolNamesTest { tcx: tcx }; - // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like - tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + tcx.hir.krate().visit_all_item_likes(&mut visitor); }) } @@ -66,23 +64,16 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { } } -impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::None - } - +impl<'a, 'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { self.process_attrs(item.id); - intravisit::walk_item(self, item); } - fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { - self.process_attrs(ti.id); - intravisit::walk_trait_item(self, ti) + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { + self.process_attrs(trait_item.id); } - fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { - self.process_attrs(ii.id); - intravisit::walk_impl_item(self, ii) + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + self.process_attrs(impl_item.id); } } From 69d12a2b97f4f09dba2e09542c74da48ea88ba08 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:00:40 +0200 Subject: [PATCH 076/546] remove FIXME(#30046) and infer moves on pattern matching --- src/librustc_mir/build/block.rs | 5 ++--- src/librustc_typeck/check/mod.rs | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index ef30b1e452230..7281fb5966388 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -117,10 +117,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Evaluate the initializer, if present. if let Some(init) = initializer { unpack!(block = this.in_opt_scope( - opt_destruction_scope.map(|de|(de, source_info)), block, move |this| { + opt_destruction_scope.map(|de|(de, source_info)), block, |this| { let scope = (init_scope, source_info); - this.in_scope(scope, lint_level, block, move |this| { - // FIXME #30046 ^~~~ + this.in_scope(scope, lint_level, block, |this| { this.expr_into_pattern(block, pattern, init) }) })); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f0f1064752d4a..c99e49256faa0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2879,7 +2879,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // just trying to get hints here. self.save_and_restore_in_snapshot_flag(|_| { let mut fulfill = FulfillmentContext::new(); - let ok = ok; // FIXME(#30046) for obligation in ok.obligations { fulfill.register_predicate_obligation(self, obligation); } From fd007559dbb9b149244cfb1184002971ea04a6cd Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 03:26:35 +0200 Subject: [PATCH 077/546] remove FIXME(#11094) and allow make tests to run on targets besides host --- src/tools/compiletest/src/runtest.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 953a13a3f5820..ee348cddb3cfc 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2358,11 +2358,6 @@ impl<'test> TestCx<'test> { } fn run_rmake_test(&self) { - // FIXME(#11094): we should fix these tests - if self.config.host != self.config.target { - return; - } - let cwd = env::current_dir().unwrap(); let src_root = self.config .src_base From 2c6b7b93230d4dcc99608538b43530e9e520215b Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 17:28:44 +0200 Subject: [PATCH 078/546] remove FIXME(#2543) and avoid bad copies --- src/libsyntax/test.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 39306229c82b2..69213f236e1dd 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -627,8 +627,15 @@ fn path_node(ids: Vec) -> ast::Path { } fn path_name_i(idents: &[Ident]) -> String { - // FIXME: Bad copies (#2543 -- same for everything else that says "bad") - idents.iter().map(|i| i.to_string()).collect::>().join("::") + let mut path_name = "".to_string(); + let mut idents_iter = idents.iter().peekable(); + while let Some(ident) = idents_iter.next() { + path_name.push_str(&ident.name.as_str()); + if let Some(_) = idents_iter.peek() { + path_name.push_str("::") + } + } + path_name } fn mk_tests(cx: &TestCtxt) -> P { @@ -681,7 +688,6 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // gensym information. let span = ignored_span(cx, test.span); - let path = test.path.clone(); let ecx = &cx.ext_cx; let self_id = ecx.ident_of("self"); let test_id = ecx.ident_of("test"); @@ -693,10 +699,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // creates $name: $expr let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr); - debug!("encoding {}", path_name_i(&path[..])); - // path to the #[test] function: "foo::bar::baz" - let path_string = path_name_i(&path[..]); + let path_string = path_name_i(&test.path[..]); + + debug!("encoding {}", path_string); + let name_expr = ecx.expr_str(span, Symbol::intern(&path_string)); // self::test::StaticTestName($name_expr) @@ -743,7 +750,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { diag.bug("expected to find top-level re-export name, but found None"); } }; - visible_path.extend(path); + visible_path.extend_from_slice(&test.path[..]); // Rather than directly give the test function to the test // harness, we create a wrapper like one of the following: From 0d8fa82eab070481d7ac82da4735dd651dfa9a00 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:28:55 +0200 Subject: [PATCH 079/546] remove FIXME(#48116) and remove the logic to debug the issue --- src/librustc_resolve/resolve_imports.rs | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 01c1ded94578e..a73f660c4059a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1026,28 +1026,9 @@ fn import_path_to_string(names: &[SpannedIdent], if names.is_empty() { import_directive_subclass_to_string(subclass) } else { - // FIXME: Remove this entire logic after #48116 is fixed. - // - // Note that this code looks a little wonky, it's currently here to - // hopefully help debug #48116, but otherwise isn't intended to - // cause any problems. - let x = format!( - "{}::{}", - names_to_string(names), - import_directive_subclass_to_string(subclass), - ); - if names.is_empty() || x.starts_with("::") { - span_bug!( - span, - "invalid name `{}` at {:?}; global = {}, names = {:?}, subclass = {:?}", - x, - span, - global, - names, - subclass - ); - } - return x + format!("{}::{}", + names_to_string(names), + import_directive_subclass_to_string(subclass)) } } } From be73a1f963e7830de2dbfbea6b362673ab7e6ded Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 02:19:01 +0200 Subject: [PATCH 080/546] remove FIXME(#33435) and remove the spurious failures counter measure --- src/tools/compiletest/src/main.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index e65c03a6e571c..cf87062f6bee2 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -452,11 +452,6 @@ pub fn run_tests(config: &Config) { _ => { /* proceed */ } } - // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests. - if let Mode::CodegenUnits = config.mode { - let _ = fs::remove_dir_all("tmp/partitioning-tests"); - } - let opts = test_opts(config); let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in From c8be5c3174f3cf2856a19db23cba1b7313068690 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 14:49:40 +0200 Subject: [PATCH 081/546] remove FIXME(#8372) since for-loops wont support borrowing iterators --- src/libsyntax/parse/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ff097c362fe61..fdb3b91fbbf04 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -298,7 +298,6 @@ pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String { debug!("parse_str_lit: given {}", escape_default(lit)); let mut res = String::with_capacity(lit.len()); - // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace @@ -503,7 +502,6 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { pub fn byte_str_lit(lit: &str) -> Lrc> { let mut res = Vec::with_capacity(lit.len()); - // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace From d5b55c1159c57cee0118df23626cb786e19ca1e5 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 18:24:11 +0200 Subject: [PATCH 082/546] remove FIXME(#27889) since the issue is already fixed --- src/test/run-pass/issue-27889.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/run-pass/issue-27889.rs b/src/test/run-pass/issue-27889.rs index 3f7d0400c884e..29a5f6dd24bd0 100644 --- a/src/test/run-pass/issue-27889.rs +++ b/src/test/run-pass/issue-27889.rs @@ -10,7 +10,6 @@ // Test that a field can have the same name in different variants // of an enum -// FIXME #27889 pub enum Foo { X { foo: u32 }, From ca3bed0c66d27fbf30eb48ae3eb5af235669364d Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 20:18:08 +0000 Subject: [PATCH 083/546] Improve and fix documentation for sort_by_cached_key --- src/liballoc/slice.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db8900664476e..bef50a733cc76 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1353,21 +1353,25 @@ impl [T] { /// /// # Current implementation /// - /// The current algorithm is an adaptive, iterative merge sort inspired by - /// [timsort](https://en.wikipedia.org/wiki/Timsort). - /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of - /// two or more sorted sequences concatenated one after another. + /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, + /// which combines the fast average case of randomized quicksort with the fast worst case of + /// heapsort, while achieving linear time on slices with certain patterns. It uses some + /// randomization to avoid degenerate cases, but with a fixed seed to always provide + /// deterministic behavior. /// - /// The algorithm allocates temporary storage in a `Vec<(K, usize)>` the length of the slice. + /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the + /// length of the slice. /// /// # Examples /// /// ``` - /// let mut v = [-5i32, 4, 1, -3, 2]; + /// let mut v = [-5i32, 4, 32, -3, 2]; /// - /// v.sort_by_cached_key(|k| k.abs()); - /// assert!(v == [1, 2, -3, 4, -5]); + /// v.sort_by_cached_key(|k| k.to_string()); + /// assert!(v == [-3, -5, 2, 32, 4]); /// ``` + /// + /// [pdqsort]: https://github.com/orlp/pdqsort #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")] #[inline] pub fn sort_by_cached_key(&mut self, f: F) From b57ea5615921609815752c2d2133956b8a4fded6 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 21:41:14 +0000 Subject: [PATCH 084/546] Stabilise FromUtf8Error::as_bytes Closes #40895. --- src/liballoc/string.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 9fec90914985d..e253122ffd6b6 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1576,7 +1576,6 @@ impl FromUtf8Error { /// Basic usage: /// /// ``` - /// #![feature(from_utf8_error_as_bytes)] /// // some invalid bytes, in a vector /// let bytes = vec![0, 159]; /// @@ -1584,7 +1583,7 @@ impl FromUtf8Error { /// /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes()); /// ``` - #[unstable(feature = "from_utf8_error_as_bytes", reason = "recently added", issue = "40895")] + #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")] pub fn as_bytes(&self) -> &[u8] { &self.bytes[..] } From 3fa69c935d2dc28207908987a3a3cb518ab7f62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 3 Dec 2017 14:37:23 +0100 Subject: [PATCH 085/546] Make Span and Symbol implement Send and Sync --- src/libsyntax_pos/lib.rs | 6 +++++- src/libsyntax_pos/symbol.rs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bec46ff3d797c..51da9a755ec4f 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -184,8 +184,12 @@ impl SpanData { } } -// The interner in thread-local, so `Span` shouldn't move between threads. +// The interner is pointed to by a thread local value which is only set on the main thread +// with parallelization is disabled. So we don't allow Span to transfer between threads +// to avoid panics and other errors, even though it would be memory safe to do so. +#[cfg(not(parallel_queries))] impl !Send for Span {} +#[cfg(not(parallel_queries))] impl !Sync for Span {} impl PartialOrd for Span { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e95079f7c88dd..34716e6eeec89 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -83,8 +83,12 @@ impl Decodable for Ident { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(u32); -// The interner in thread-local, so `Symbol` shouldn't move between threads. +// The interner is pointed to by a thread local value which is only set on the main thread +// with parallelization is disabled. So we don't allow Symbol to transfer between threads +// to avoid panics and other errors, even though it would be memory safe to do so. +#[cfg(not(parallel_queries))] impl !Send for Symbol { } +#[cfg(not(parallel_queries))] impl !Sync for Symbol { } impl Symbol { From 1dbc84d0066c4689a1e3de21f5a22d87e74a2ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 7 Mar 2018 02:43:50 +0100 Subject: [PATCH 086/546] Remove rustc_global! --- src/librustc_data_structures/sync.rs | 30 ---------------------------- 1 file changed, 30 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index d7cd459e5771c..f066ea98f91f5 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -26,11 +26,6 @@ //! //! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false. //! -//! `rustc_global!` gives us a way to declare variables which are intended to be -//! global for the current rustc session. This currently maps to thread-locals, -//! since rustdoc uses the rustc libraries in multiple threads. -//! These globals should eventually be moved into the `Session` structure. -//! //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync //! depending on the value of cfg!(parallel_queries). @@ -228,31 +223,6 @@ pub fn assert_sync() {} pub fn assert_send_val(_t: &T) {} pub fn assert_send_sync_val(_t: &T) {} -#[macro_export] -#[allow_internal_unstable] -macro_rules! rustc_global { - // empty (base case for the recursion) - () => {}; - - // process multiple declarations - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => ( - thread_local!($(#[$attr])* $vis static $name: $t = $init); - rustc_global!($($rest)*); - ); - - // handle a single declaration - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => ( - thread_local!($(#[$attr])* $vis static $name: $t = $init); - ); -} - -#[macro_export] -macro_rules! rustc_access_global { - ($name:path, $callback:expr) => { - $name.with($callback) - } -} - impl Debug for LockCell { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.debug_struct("LockCell") From 1551ef181267ea1e5db534b247148aba6bd14970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 23:23:46 +0100 Subject: [PATCH 087/546] Don't get the global lock in the fast case --- src/librustc/ty/context.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fd3465f59ebf2..37a539cfff463 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -161,12 +161,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { -> Ty<'tcx> { let ty = { let mut interner = self.type_.borrow_mut(); - let global_interner = global_interners.map(|interners| { - interners.type_.borrow_mut() - }); if let Some(&Interned(ty)) = interner.get(&st) { return ty; } + let global_interner = global_interners.map(|interners| { + interners.type_.borrow_mut() + }); if let Some(ref interner) = global_interner { if let Some(&Interned(ty)) = interner.get(&st) { return ty; From 697d3bee96c8e385cea9cf2a01325f033ae160fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:11:23 +0100 Subject: [PATCH 088/546] Replace Rc with Lrc --- src/librustc/middle/const_val.rs | 4 ++-- src/librustc/traits/query/dropck_outlives.rs | 6 +++--- src/librustc/traits/query/normalize.rs | 6 +++--- src/librustc/ty/structural_impls.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 6 +++--- src/librustc_traits/dropck_outlives.rs | 4 ++-- src/librustc_traits/normalize_projection_ty.rs | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8c3dfd0bce752..19a7576b7ceac 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -19,7 +19,7 @@ use graphviz::IntoCow; use syntax_pos::Span; use std::borrow::Cow; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; @@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> { #[derive(Clone, Debug)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub kind: Rc>, + pub kind: Lrc>, } #[derive(Clone, Debug)] diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef9..e16a1082214f7 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -15,7 +15,7 @@ use std::iter::FromIterator; use traits::query::CanonicalTyGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Kind; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -182,13 +182,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 70c5cf5f39029..63f50cff4c2ad 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -17,7 +17,7 @@ use infer::at::At; use infer::canonical::{Canonical, Canonicalize, QueryResult}; use middle::const_val::ConstVal; use mir::interpret::GlobalId; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::query::CanonicalProjectionGoal; use traits::project::Normalized; @@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c9a69d5405c9a..3fc20508ad7ee 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; @@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { tcx.lift(&*self.kind).map(|kind| { ConstEvalErr { span: self.span, - kind: Rc::new(kind), + kind: Lrc::new(kind), } }) } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b033..50997089a5764 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory}; use std::fmt; use std::error::Error; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -477,7 +477,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do match-check before building MIR if tcx.check_match(def_id).is_err() { return Err(ConstEvalErr { - kind: Rc::new(CheckMatchError), + kind: Lrc::new(CheckMatchError), span, }); } @@ -489,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Rc::new(TypeckError), + kind: Lrc::new(TypeckError), span, }); } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2a8cfe5cc06b3..1fe2f87128abd 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::FxHashSet; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::codemap::{Span, DUMMY_SP}; use util; crate fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", goal); tcx.infer_ctxt().enter(|ref infcx| { diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc3..62d5ef11551c0 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; use rustc::ty::{ParamEnvAnd, TyCtxt}; use rustc::util::common::CellUsizeExt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::DUMMY_SP; use util; @@ -22,7 +22,7 @@ use util; crate fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess.perf_stats.normalize_projection_ty.increment(); From 8e5eb025a2b438eaaf609894ed910458078cc899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:13:42 +0100 Subject: [PATCH 089/546] Add an Default impl for Lock --- src/librustc_data_structures/sync.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f066ea98f91f5..184ef1369761c 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -333,6 +333,13 @@ impl Lock { } } +impl Default for Lock { + #[inline] + fn default() -> Self { + Lock::new(T::default()) + } +} + // FIXME: Probably a bad idea impl Clone for Lock { #[inline] From 37f9c7ff8281696545c72fc4f24e61d72b9e8df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:38:12 +0100 Subject: [PATCH 090/546] Add OnDrop --- src/librustc_data_structures/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 81246aea1b56e..bf0b3726bb301 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -76,6 +76,14 @@ pub mod flock; pub mod sync; pub mod owning_ref; +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { + (self.0)(); + } +} + // See comments in src/librustc/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} From ec4a9c6b2fb188ffd5eeee00e635061fb784af5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:01:17 +0100 Subject: [PATCH 091/546] Minor cleanup --- src/librustc/ty/context.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 37a539cfff463..fbee9a0ec5c5c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1010,17 +1010,16 @@ impl<'tcx> InterpretInterner<'tcx> { } } -impl<'tcx> GlobalCtxt<'tcx> { +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Get the global TyCtxt. - pub fn global_tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + #[inline] + pub fn global_tcx(self) -> TyCtxt<'a, 'gcx, 'gcx> { TyCtxt { - gcx: self, - interners: &self.global_interners + gcx: self.gcx, + interners: &self.gcx.global_interners, } } -} -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics { self.global_arenas.generics.alloc(generics) } From e09c2ff3f85b428cd8283a7f7d9b38843bbc95a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 17 Mar 2018 23:02:27 +0100 Subject: [PATCH 092/546] Make interners thread-safe --- src/librustc/ty/context.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fbee9a0ec5c5c..966c96e594fc4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1080,12 +1080,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, alloc: interpret::Allocation, ) -> &'gcx interpret::Allocation { - if let Some(alloc) = self.interpret_interner.inner.borrow().allocs.get(&alloc) { + let allocs = &mut self.interpret_interner.inner.borrow_mut().allocs; + if let Some(alloc) = allocs.get(&alloc) { return alloc; } let interned = self.global_arenas.const_allocs.alloc(alloc); - if let Some(prev) = self.interpret_interner.inner.borrow_mut().allocs.replace(interned) { + if let Some(prev) = allocs.replace(interned) { bug!("Tried to overwrite interned Allocation: {:#?}", prev) } interned @@ -1112,24 +1113,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability { - if let Some(st) = self.stability_interner.borrow().get(&stab) { + let mut stability_interner = self.stability_interner.borrow_mut(); + if let Some(st) = stability_interner.get(&stab) { return st; } let interned = self.global_interners.arena.alloc(stab); - if let Some(prev) = self.stability_interner.borrow_mut().replace(interned) { + if let Some(prev) = stability_interner.replace(interned) { bug!("Tried to overwrite interned Stability: {:?}", prev) } interned } pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails { - if let Some(layout) = self.layout_interner.borrow().get(&layout) { + let mut layout_interner = self.layout_interner.borrow_mut(); + if let Some(layout) = layout_interner.get(&layout) { return layout; } let interned = self.global_arenas.layout.alloc(layout); - if let Some(prev) = self.layout_interner.borrow_mut().replace(interned) { + if let Some(prev) = layout_interner.replace(interned) { bug!("Tried to overwrite interned Layout: {:?}", prev) } interned From f40877feeb17c538a73fe6294d48af123251a8c5 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:39:24 +0100 Subject: [PATCH 093/546] Add 12 num::NonZero* types for each primitive integer RFC: https://github.com/rust-lang/rfcs/pull/2307 --- src/libcore/nonzero.rs | 2 +- src/libcore/num/mod.rs | 87 ++++++++++++++++++++++++++++++++++++++++++ src/libstd/lib.rs | 1 + src/libstd/num.rs | 11 ++++++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 2c966eb3b5794..c6a1dab561757 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -62,7 +62,7 @@ impl_zeroable_for_integer_types! { /// NULL or 0 that might allow certain optimizations. #[lang = "non_zero"] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] -pub struct NonZero(T); +pub struct NonZero(pub(crate) T); impl NonZero { /// Creates an instance of NonZero with the provided value. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ab7060d37db..d3556ef742b53 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,9 +15,96 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; +use nonzero::NonZero; use ops; use str::FromStr; +macro_rules! impl_nonzero_fmt { + ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { + $( + #[$stability] + impl fmt::$Trait for $Ty { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.get().fmt(f) + } + } + )+ + } +} + +macro_rules! nonzero_integers { + ( #[$stability: meta] $( $Ty: ident($Int: ty); )+ ) => { + $( + /// An integer that is known not to equal zero. + /// + /// This may enable some memory layout optimization such as: + /// + /// ```rust + /// # #![feature(nonzero)] + /// use std::mem::size_of; + /// assert_eq!(size_of::>(), size_of::()); + /// ``` + #[$stability] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] + pub struct $Ty(NonZero<$Int>); + + impl $Ty { + /// Create a non-zero without checking the value. + /// + /// # Safety + /// + /// The value must not be zero. + #[$stability] + #[inline] + pub const unsafe fn new_unchecked(n: $Int) -> Self { + $Ty(NonZero(n)) + } + + /// Create a non-zero if the given value is not zero. + #[$stability] + #[inline] + pub fn new(n: $Int) -> Option { + if n != 0 { + Some($Ty(NonZero(n))) + } else { + None + } + } + + /// Returns the value as a primitive type. + #[$stability] + #[inline] + pub fn get(self) -> $Int { + self.0 .0 + } + + } + + impl_nonzero_fmt! { + #[$stability] + (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty + } + )+ + } +} + +nonzero_integers! { + #[unstable(feature = "nonzero", issue = "27730")] + NonZeroU8(u8); NonZeroI8(i8); + NonZeroU16(u16); NonZeroI16(i16); + NonZeroU32(u32); NonZeroI32(i32); + NonZeroU64(u64); NonZeroI64(i64); + NonZeroUsize(usize); NonZeroIsize(isize); +} + +nonzero_integers! { + // Change this to `#[unstable(feature = "i128", issue = "35118")]` + // if other NonZero* integer types are stabilizied before 128-bit integers + #[unstable(feature = "nonzero", issue = "27730")] + NonZeroU128(u128); NonZeroI128(i128); +} + /// Provides intentionally-wrapped arithmetic on `T`. /// /// Operations like `+` on `u32` values is intended to never overflow, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a159..5c0a83fde102f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -282,6 +282,7 @@ #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] #![feature(exhaustive_patterns)] +#![feature(nonzero)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] diff --git a/src/libstd/num.rs b/src/libstd/num.rs index a2c133954a327..5e0406ca2202c 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,6 +21,17 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{ + NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, + NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, +}; + +// Change this to `#[unstable(feature = "i128", issue = "35118")]` +// if other NonZero* integer types are stabilizied before 128-bit integers +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{NonZeroU128, NonZeroI128}; + #[cfg(test)] use fmt; #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; From 2d13ddb6e14322edcd07135a436d0d848d127fb2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:58:48 +0100 Subject: [PATCH 094/546] Use NonNull<_> instead of NonZero<*const _> in btree internals --- src/liballoc/btree/node.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index c1618043ce66f..464f8f2f4eced 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -43,8 +43,7 @@ use core::marker::PhantomData; use core::mem; -use core::nonzero::NonZero; -use core::ptr::{self, Unique}; +use core::ptr::{self, Unique, NonNull}; use core::slice; use boxed::Box; @@ -149,14 +148,12 @@ impl BoxedNode { } } - unsafe fn from_ptr(ptr: NonZero<*const LeafNode>) -> Self { - BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode) } + unsafe fn from_ptr(ptr: NonNull>) -> Self { + BoxedNode { ptr: Unique::from(ptr) } } - fn as_ptr(&self) -> NonZero<*const LeafNode> { - unsafe { - NonZero::from(self.ptr.as_ref()) - } + fn as_ptr(&self) -> NonNull> { + NonNull::from(self.ptr) } } @@ -276,7 +273,7 @@ impl Root { /// `NodeRef` could be pointing to either type of node. pub struct NodeRef { height: usize, - node: NonZero<*const LeafNode>, + node: NonNull>, // This is null unless the borrow type is `Mut` root: *const Root, _marker: PhantomData<(BorrowType, Type)> @@ -302,7 +299,7 @@ unsafe impl Send impl NodeRef { fn as_internal(&self) -> &InternalNode { unsafe { - &*(self.node.get() as *const InternalNode) + &*(self.node.as_ptr() as *mut InternalNode) } } } @@ -310,7 +307,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::Internal> { fn as_internal_mut(&mut self) -> &mut InternalNode { unsafe { - &mut *(self.node.get() as *mut InternalNode) + &mut *(self.node.as_ptr() as *mut InternalNode) } } } @@ -352,7 +349,7 @@ impl NodeRef { fn as_leaf(&self) -> &LeafNode { unsafe { - &*self.node.get() + self.node.as_ref() } } @@ -382,7 +379,8 @@ impl NodeRef { >, Self > { - if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode) { + let parent_as_leaf = self.as_leaf().parent as *const LeafNode; + if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { Ok(Handle { node: NodeRef { height: self.height + 1, @@ -498,7 +496,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { fn as_leaf_mut(&mut self) -> &mut LeafNode { unsafe { - &mut *(self.node.get() as *mut LeafNode) + self.node.as_mut() } } @@ -1241,12 +1239,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } else { Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } From 67f46ce1122121849890ad51c35f0eb6ded14b6f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:02:06 +0100 Subject: [PATCH 095/546] Use num::NonZero* instead of NonZero<_> in rustc and tests --- src/libcore/tests/nonzero.rs | 14 ++++----- src/librustc/ty/subst.rs | 6 ++-- .../obligation_forest/node_index.rs | 6 ++-- src/librustc_mir/dataflow/move_paths/mod.rs | 6 ++-- src/test/run-pass/enum-null-pointer-opt.rs | 9 +++--- src/test/run-pass/issue-23433.rs | 2 +- src/test/ui/print_type_sizes/niche-filling.rs | 31 +++++++------------ .../ui/print_type_sizes/niche-filling.stdout | 10 +++--- 8 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index a795dd575043d..9eaf7529dd3cf 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use core::num::NonZeroU32; use core::option::Option; use core::option::Option::{Some, None}; use std::mem::size_of; @@ -16,28 +16,28 @@ use std::mem::size_of; #[test] fn test_create_nonzero_instance() { let _a = unsafe { - NonZero::new_unchecked(21) + NonZeroU32::new_unchecked(21) }; } #[test] fn test_size_nonzero_in_option() { - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); } #[test] fn test_match_on_nonzero_option() { let a = Some(unsafe { - NonZero::new_unchecked(42) + NonZeroU32::new_unchecked(42) }); match a { Some(val) => assert_eq!(val.get(), 42), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } - match unsafe { Some(NonZero::new_unchecked(43)) } { + match unsafe { Some(NonZeroU32::new_unchecked(43)) } { Some(val) => assert_eq!(val.get(), 43), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index a301049fe1c40..e7b58ae1564aa 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -19,11 +19,11 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc_data_structures::accumulate_vec::AccumulateVec; use core::intrinsics; -use core::nonzero::NonZero; use std::fmt; use std::iter; use std::marker::PhantomData; use std::mem; +use std::num::NonZeroUsize; /// An entity in the Rust typesystem, which can be one of /// several kinds (only types and lifetimes for now). @@ -32,7 +32,7 @@ use std::mem; /// indicate the type (`Ty` or `Region`) it points to. #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Kind<'tcx> { - ptr: NonZero, + ptr: NonZeroUsize, marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)> } @@ -63,7 +63,7 @@ impl<'tcx> UnpackedKind<'tcx> { Kind { ptr: unsafe { - NonZero::new_unchecked(ptr | tag) + NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs index a72cc6b57eade..37512e4bcd57f 100644 --- a/src/librustc_data_structures/obligation_forest/node_index.rs +++ b/src/librustc_data_structures/obligation_forest/node_index.rs @@ -8,18 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use std::num::NonZeroU32; use std::u32; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct NodeIndex { - index: NonZero, + index: NonZeroU32, } impl NodeIndex { pub fn new(value: usize) -> NodeIndex { assert!(value < (u32::MAX as usize)); - NodeIndex { index: NonZero::new((value as u32) + 1).unwrap() } + NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() } } pub fn get(self) -> usize { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7b6ebc6fba872..9f6cf8c036e19 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -29,17 +29,17 @@ mod abs_domain; // (which is likely to yield a subtle off-by-one error). pub(crate) mod indexes { use std::fmt; - use core::nonzero::NonZero; + use std::num::NonZeroUsize; use rustc_data_structures::indexed_vec::Idx; macro_rules! new_index { ($Index:ident, $debug_name:expr) => { #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub struct $Index(NonZero); + pub struct $Index(NonZeroUsize); impl Idx for $Index { fn new(idx: usize) -> Self { - $Index(NonZero::new(idx + 1).unwrap()) + $Index(NonZeroUsize::new(idx + 1).unwrap()) } fn index(self) -> usize { self.0.get() - 1 diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index e296aff2782c5..12f17a1575e82 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -10,10 +10,9 @@ #![feature(nonzero, core)] -extern crate core; - -use core::nonzero::NonZero; use std::mem::size_of; +use std::num::NonZeroUsize; +use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; @@ -59,8 +58,8 @@ fn main() { assert_eq!(size_of::<[Box; 1]>(), size_of::; 1]>>()); // Should apply to NonZero - assert_eq!(size_of::>(), size_of::>>()); - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::>(), size_of::>>()); // Should apply to types that use NonZero internally assert_eq!(size_of::>(), size_of::>>()); diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs index 7af732f561deb..9547b2f08a6bc 100644 --- a/src/test/run-pass/issue-23433.rs +++ b/src/test/run-pass/issue-23433.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Don't fail if we encounter a NonZero<*T> where T is an unsized type +// Don't fail if we encounter a NonNull where T is an unsized type use std::ptr::NonNull; diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 7f234e243e926..875883a2cca7f 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -14,7 +14,7 @@ // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. // -// It uses NonZero directly, rather than `&_` or `Unique<_>`, because +// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because // the test is not set up to deal with target-dependent pointer width. // // It avoids using u64/i64 because on some targets that is only 4-byte @@ -25,8 +25,7 @@ #![feature(nonzero)] #![allow(dead_code)] -extern crate core; -use core::nonzero::{NonZero, Zeroable}; +use std::num::NonZeroU32; pub enum MyOption { None, Some(T) } @@ -36,7 +35,7 @@ impl Default for MyOption { pub enum EmbeddedDiscr { None, - Record { pre: u8, val: NonZero, post: u16 }, + Record { pre: u8, val: NonZeroU32, post: u16 }, } impl Default for EmbeddedDiscr { @@ -44,32 +43,24 @@ impl Default for EmbeddedDiscr { } #[derive(Default)] -pub struct IndirectNonZero { +pub struct IndirectNonZero { pre: u8, - nested: NestedNonZero, + nested: NestedNonZero, post: u16, } -pub struct NestedNonZero { +pub struct NestedNonZero { pre: u8, - val: NonZero, + val: NonZeroU32, post: u16, } -impl Default for NestedNonZero { +impl Default for NestedNonZero { fn default() -> Self { - NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 } + NestedNonZero { pre: 0, val: NonZeroU32::new(1).unwrap(), post: 0 } } } -pub trait One { - fn one() -> Self; -} - -impl One for u32 { - fn one() -> Self { 1 } -} - pub enum Enum4 { One(A), Two(B), @@ -79,9 +70,9 @@ pub enum Enum4 { #[start] fn start(_: isize, _: *const *const u8) -> isize { - let _x: MyOption> = Default::default(); + let _x: MyOption = Default::default(); let _y: EmbeddedDiscr = Default::default(); - let _z: MyOption> = Default::default(); + let _z: MyOption = Default::default(); let _a: MyOption = Default::default(); let _b: MyOption = Default::default(); let _c: MyOption = Default::default(); diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 0f53e7722dd51..79f9ef5a231d3 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -1,9 +1,9 @@ -print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes +print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes print-type-size field `.nested`: 8 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `MyOption>`: 12 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 12 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 12 bytes print-type-size field `.0`: 12 bytes @@ -14,7 +14,7 @@ print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes +print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes @@ -32,12 +32,14 @@ print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes -print-type-size type: `MyOption>`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `core::nonzero::NonZero`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes print-type-size variant `One`: 0 bytes print-type-size field `.0`: 0 bytes From 22f7a0295828c0d75b5487d89343e722b406dd5f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:14:35 +0100 Subject: [PATCH 096/546] Deprecate core::nonzero in favor of ptr::NonNull and num::NonZero* --- src/libcore/nonzero.rs | 5 ++++- src/libcore/num/mod.rs | 4 +++- src/libcore/ptr.rs | 11 +++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index c6a1dab561757..59aaef9d66a00 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,8 +10,11 @@ //! Exposes the NonZero lang item which provides optimization hints. #![unstable(feature = "nonzero", - reason = "needs an RFC to flesh out the design", + reason = "deprecated", issue = "27730")] +#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead", + since = "1.26.0")] +#![allow(deprecated)] use ops::CoerceUnsized; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d3556ef742b53..84f6ab9b76498 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,7 +15,7 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; -use nonzero::NonZero; +#[allow(deprecated)] use nonzero::NonZero; use ops; use str::FromStr; @@ -46,9 +46,11 @@ macro_rules! nonzero_integers { /// assert_eq!(size_of::>(), size_of::()); /// ``` #[$stability] + #[allow(deprecated)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct $Ty(NonZero<$Int>); + #[allow(deprecated)] impl $Ty { /// Create a non-zero without checking the value. /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 6270e5892b3a0..834a2ed09f77a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -23,7 +23,7 @@ use fmt; use hash; use marker::{PhantomData, Unsize}; use mem; -use nonzero::NonZero; +#[allow(deprecated)] use nonzero::NonZero; use cmp::Ordering::{self, Less, Equal, Greater}; @@ -2285,6 +2285,7 @@ impl PartialOrd for *mut T { #[unstable(feature = "ptr_internals", issue = "0", reason = "use NonNull instead and consider PhantomData \ (if you also use #[may_dangle]), Send, and/or Sync")] +#[allow(deprecated)] pub struct Unique { pointer: NonZero<*const T>, // NOTE: this marker has no consequences for variance, but is necessary @@ -2332,6 +2333,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl Unique { /// Creates a new `Unique`. /// @@ -2392,6 +2394,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2399,6 +2402,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2436,7 +2440,7 @@ pub type Shared = NonNull; /// provide a public API that follows the normal shared XOR mutable rules of Rust. #[stable(feature = "nonnull", since = "1.25.0")] pub struct NonNull { - pointer: NonZero<*const T>, + #[allow(deprecated)] pointer: NonZero<*const T>, } /// `NonNull` pointers are not `Send` because the data they reference may be aliased. @@ -2463,6 +2467,7 @@ impl NonNull { } } +#[allow(deprecated)] impl NonNull { /// Creates a new `NonNull`. /// @@ -2581,6 +2586,7 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { NonNull { pointer: NonZero::from(reference) } @@ -2588,6 +2594,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { NonNull { pointer: NonZero::from(reference) } From 6d682c9adc12c5aee1bac37afa15f01b420be8ee Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:45:44 +0100 Subject: [PATCH 097/546] Stop using deprecated NonZero APIs These will eventually be removed (though the NonZero lang item will likely stay). --- src/libcore/ptr.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 834a2ed09f77a..4ab0ceb796773 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2341,17 +2341,21 @@ impl Unique { /// /// `ptr` must be non-null. pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } + Unique { pointer: NonZero(ptr as _), _marker: PhantomData } } /// Creates a new `Unique` if `ptr` is non-null. pub fn new(ptr: *mut T) -> Option { - NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData }) + if !ptr.is_null() { + Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData }) + } else { + None + } } /// Acquires the underlying `*mut` pointer. pub fn as_ptr(self) -> *mut T { - self.pointer.get() as *mut T + self.pointer.0 as *mut T } /// Dereferences the content. @@ -2397,7 +2401,7 @@ impl fmt::Pointer for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2405,7 +2409,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2476,19 +2480,23 @@ impl NonNull { /// `ptr` must be non-null. #[stable(feature = "nonnull", since = "1.25.0")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - NonNull { pointer: NonZero::new_unchecked(ptr) } + NonNull { pointer: NonZero(ptr as _) } } /// Creates a new `NonNull` if `ptr` is non-null. #[stable(feature = "nonnull", since = "1.25.0")] pub fn new(ptr: *mut T) -> Option { - NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz }) + if !ptr.is_null() { + Some(NonNull { pointer: NonZero(ptr as _) }) + } else { + None + } } /// Acquires the underlying `*mut` pointer. #[stable(feature = "nonnull", since = "1.25.0")] pub fn as_ptr(self) -> *mut T { - self.pointer.get() as *mut T + self.pointer.0 as *mut T } /// Dereferences the content. @@ -2589,7 +2597,7 @@ impl From> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } @@ -2597,6 +2605,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } From 7cf1f18cb9209156108e3871e11cb5d63f7f1cf1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 19:28:13 +0100 Subject: [PATCH 098/546] Test NonZero in a const item in a pattern. (This was buggy before https://github.com/rust-lang/rust/pull/46882) --- src/libcore/tests/nonzero.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 9eaf7529dd3cf..8d39298bac3d1 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -98,3 +98,26 @@ fn test_match_option_string() { None => panic!("unexpected None while matching on Some(String { ... })") } } + +mod atom { + use core::num::NonZeroU32; + + #[derive(PartialEq, Eq)] + pub struct Atom { + index: NonZeroU32, // private + } + pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } }; +} + +macro_rules! atom { + ("foo") => { atom::FOO_ATOM } +} + +#[test] +fn test_match_nonzero_const_pattern() { + match atom!("foo") { + // Using as a pattern is supported by the compiler: + atom!("foo") => {} + _ => panic!("Expected the const item as a pattern to match.") + } +} From b4981923a05869ea2c50f1893acf433b1b67f79a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 17 Mar 2018 15:34:12 -0700 Subject: [PATCH 099/546] Add a -Z flag for LLVM align attributes on arguments LLVM seems to still put the assume calls in when inlining, so this probably isn't in a place where it can be turned on by default, but it's interesting to experiment with. For example, this makes `swap::` be 8x `vmovaps ymm` instead of 16x `vmovups xmm`, on my cpu. --- src/librustc/session/config.rs | 2 ++ src/librustc_trans/abi.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1c5cfa87ef46f..a5eae35c5567a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1208,6 +1208,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "set the MIR optimization level (0-3, default: 1)"), mutable_noalias: bool = (false, parse_bool, [UNTRACKED], "emit noalias metadata for mutable references"), + arg_align_attributes: bool = (false, parse_bool, [UNTRACKED], + "emit align metadata for reference arguments"), dump_mir: Option = (None, parse_opt_string, [UNTRACKED], "dump MIR state at various points in translation"), dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED], diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index ee0f2415bd808..c8c9147766983 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -778,7 +778,7 @@ impl<'a, 'tcx> FnType<'tcx> { // HACK(eddyb) LLVM inserts `llvm.assume` calls when inlining functions // with align attributes, and those calls later block optimizations. - if !is_return { + if !is_return && !cx.tcx.sess.opts.debugging_opts.arg_align_attributes { attrs.pointee_align = None; } From 73c053786dde55059932b9ebcd4a40edf89eae15 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 8 Mar 2018 16:55:51 +0100 Subject: [PATCH 100/546] Remove deprecated unstable ptr::Shared type alias. It has been deprecated for about one release cycle. --- src/libcore/cell.rs | 5 ++--- src/libcore/ptr.rs | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 36618e86968b5..c8ee166fee3e9 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -146,13 +146,12 @@ //! //! ``` //! #![feature(core_intrinsics)] -//! #![feature(shared)] //! use std::cell::Cell; -//! use std::ptr::Shared; +//! use std::ptr::NonNull; //! use std::intrinsics::abort; //! //! struct Rc { -//! ptr: Shared> +//! ptr: NonNull> //! } //! //! struct RcBox { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 4ab0ceb796773..cebd5989e96cd 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2420,11 +2420,6 @@ impl<'a, T: ?Sized> From> for Unique { } } -/// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")] -#[unstable(feature = "shared", issue = "27730")] -pub type Shared = NonNull; - /// `*mut T` but non-zero and covariant. /// /// This is often the correct thing to use when building data structures using From 9896b38f01c068abfe7170cb9ae2bfadb4aebbc4 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 20:43:46 +0000 Subject: [PATCH 101/546] Clarify time complexity --- src/liballoc/lib.rs | 1 - src/liballoc/slice.rs | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 253b8acc16c42..b93e128d50819 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,7 +113,6 @@ #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] -#![feature(slice_sort_by_cached_key)] #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index bef50a733cc76..cd212aa15baeb 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1303,7 +1303,7 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log m n)` + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log(m n))` /// worst-case, where the key function is `O(m)`. /// /// For expensive key functions (e.g. functions that are not simple property accesses or @@ -1365,6 +1365,7 @@ impl [T] { /// # Examples /// /// ``` + /// #![feature(slice_sort_by_cached_key)] /// let mut v = [-5i32, 4, 32, -3, 2]; /// /// v.sort_by_cached_key(|k| k.to_string()); @@ -1480,7 +1481,7 @@ impl [T] { /// elements. /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), - /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. + /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`. /// /// # Current implementation /// From 81edd1796b463776d111cd4fe48e866dd716dfab Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 18 Mar 2018 11:11:17 +0000 Subject: [PATCH 102/546] Check that the size optimisation is not redundant --- src/liballoc/slice.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index cd212aa15baeb..2b4ce9fe49c8e 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1384,8 +1384,8 @@ impl [T] { let mut indices: Vec<_> = $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect(); // The elements of `indices` are unique, as they are indexed, so any sort will be - // stable with respect to the original slice. We use `sort_unstable` here because it - // requires less memory allocation. + // stable with respect to the original slice. We use `sort_unstable` here because + // it requires less memory allocation. indices.sort_unstable(); for i in 0..$slice.len() { let mut index = indices[i].1; @@ -1398,10 +1398,15 @@ impl [T] { }) } + let sz_u8 = mem::size_of::<(K, u8)>(); + let sz_u16 = mem::size_of::<(K, u16)>(); + let sz_u32 = mem::size_of::<(K, u32)>(); + let sz_usize = mem::size_of::<(K, usize)>(); + let len = self.len(); - if len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } - if len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } - if len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } + if sz_u8 < sz_u16 && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } + if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } + if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } sort_by_key!(usize, self, f) } From 785e3c38fe6c49e39aec145c81e463ceb60d179e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 18 Mar 2018 12:37:06 +0000 Subject: [PATCH 103/546] Add lexicographic sorting benchmark --- src/liballoc/benches/lib.rs | 1 + src/liballoc/benches/slice.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs index 2de0ffb4b2611..9cb5f558574c1 100644 --- a/src/liballoc/benches/lib.rs +++ b/src/liballoc/benches/lib.rs @@ -13,6 +13,7 @@ #![feature(i128_type)] #![feature(rand)] #![feature(repr_simd)] +#![feature(slice_sort_by_cached_key)] #![feature(test)] extern crate rand; diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index ee5182a1d4663..a699ff9c0a76e 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -284,6 +284,17 @@ macro_rules! sort_expensive { } } +macro_rules! sort_lexicographic { + ($f:ident, $name:ident, $gen:expr, $len:expr) => { + #[bench] + fn $name(b: &mut Bencher) { + let v = $gen($len); + b.iter(|| v.clone().$f(|x| x.to_string())); + b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64; + } + } +} + sort!(sort, sort_small_ascending, gen_ascending, 10); sort!(sort, sort_small_descending, gen_descending, 10); sort!(sort, sort_small_random, gen_random, 10); @@ -312,6 +323,10 @@ sort!(sort_unstable, sort_unstable_large_big, gen_big_random, 10000); sort_strings!(sort_unstable, sort_unstable_large_strings, gen_strings, 10000); sort_expensive!(sort_unstable_by, sort_unstable_large_expensive, gen_random, 10000); +sort_lexicographic!(sort_by_key, sort_by_key_lexicographic, gen_random, 10000); +sort_lexicographic!(sort_unstable_by_key, sort_unstable_by_key_lexicographic, gen_random, 10000); +sort_lexicographic!(sort_by_cached_key, sort_by_cached_key_lexicographic, gen_random, 10000); + macro_rules! reverse { ($name:ident, $ty:ty, $f:expr) => { #[bench] From e85c9227c2e913b71f0d7b6cc2322d7897f28554 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 27 Feb 2018 16:51:12 +0900 Subject: [PATCH 104/546] rustc_driver: get rid of extra thread on Unix --- src/librustc_driver/lib.rs | 51 +++++++++++++++++++++++----- src/libstd/sys_common/thread_info.rs | 4 +++ src/libstd/thread/mod.rs | 8 +++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f1f3a0519bbcb..8605764497a16 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -24,6 +24,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#![feature(rustc_stack_internals)] extern crate arena; extern crate getopts; @@ -1461,16 +1462,50 @@ pub fn in_rustc_thread(f: F) -> Result> // Temporarily have stack size set to 16MB to deal with nom-using crates failing const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB - let mut cfg = thread::Builder::new().name("rustc".to_string()); + #[cfg(unix)] + let spawn_thread = unsafe { + // Fetch the current resource limits + let mut rlim = libc::rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling getrlimit: {}", err); + true + } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { + true + } else { + rlim.rlim_cur = STACK_SIZE as libc::rlim_t; + if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling setrlimit: {}", err); + true + } else { + std::thread::update_stack_guard(); + false + } + } + }; - // FIXME: Hacks on hacks. If the env is trying to override the stack size - // then *don't* set it explicitly. - if env::var_os("RUST_MIN_STACK").is_none() { - cfg = cfg.stack_size(STACK_SIZE); - } + #[cfg(not(unix))] + let spawn_thread = true; + + // The or condition is added from backward compatibility. + if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() { + let mut cfg = thread::Builder::new().name("rustc".to_string()); + + // FIXME: Hacks on hacks. If the env is trying to override the stack size + // then *don't* set it explicitly. + if env::var_os("RUST_MIN_STACK").is_none() { + cfg = cfg.stack_size(STACK_SIZE); + } - let thread = cfg.spawn(f); - thread.unwrap().join() + let thread = cfg.spawn(f); + thread.unwrap().join() + } else { + Ok(f()) + } } /// Get a list of extra command-line flags provided by the user, as strings. diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs index 6a2b6742367a5..d75cbded7347b 100644 --- a/src/libstd/sys_common/thread_info.rs +++ b/src/libstd/sys_common/thread_info.rs @@ -50,3 +50,7 @@ pub fn set(stack_guard: Option, thread: Thread) { thread, })); } + +pub fn reset_guard(stack_guard: Option) { + THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard); +} diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 71aee673cfe3e..b686ddc205ea7 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,6 +208,14 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = imp::guard::init(); + thread_info::reset_guard(main_guard); +} + //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From 1bb89f1b3cf1e4b5fa83391872136251c0030c1e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 6 Mar 2018 13:33:36 +0900 Subject: [PATCH 105/546] rustc_driver: get rid of extra thread on Windows --- src/librustc_driver/lib.rs | 6 +++++- src/rustc/rustc.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8605764497a16..761797239412e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1488,7 +1488,11 @@ pub fn in_rustc_thread(f: F) -> Result> } }; - #[cfg(not(unix))] + // We set the stack size at link time. See src/rustc/rustc.rs. + #[cfg(windows)] + let spawn_thread = false; + + #[cfg(not(any(windows,unix)))] let spawn_thread = true; // The or condition is added from backward compatibility. diff --git a/src/rustc/rustc.rs b/src/rustc/rustc.rs index bfd01146d2c46..bd36aaf01f860 100644 --- a/src/rustc/rustc.rs +++ b/src/rustc/rustc.rs @@ -9,6 +9,15 @@ // except according to those terms. #![feature(rustc_private)] +#![feature(link_args)] + +// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread +// for the rationale. +#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")] +// We only build for msvc and gnu now, but we use a exhaustive condition here +// so we can expect either the stack size to be set or the build fails. +#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")] +extern {} extern crate rustc_driver; From fad1648e0f8299a8b108f85c2b1055eb37bdab9e Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Fri, 9 Mar 2018 23:56:40 -0600 Subject: [PATCH 106/546] Initial implementation of RFC 2151, Raw Identifiers --- src/libproc_macro/lib.rs | 11 +- src/librustc/ich/impls_syntax.rs | 5 +- src/librustc_passes/ast_validation.rs | 4 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 4 +- src/librustdoc/html/highlight.rs | 8 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/attr.rs | 13 ++- src/libsyntax/diagnostics/plugin.rs | 10 +- src/libsyntax/ext/base.rs | 5 +- src/libsyntax/ext/quote.rs | 11 +- src/libsyntax/ext/tt/macro_parser.rs | 19 +-- src/libsyntax/ext/tt/macro_rules.rs | 6 +- src/libsyntax/ext/tt/quoted.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/fold.rs | 5 +- src/libsyntax/parse/lexer/mod.rs | 69 +++++++---- src/libsyntax/parse/mod.rs | 20 ++-- src/libsyntax/parse/parser.rs | 29 +++-- src/libsyntax/parse/token.rs | 108 +++++++++++++----- src/libsyntax/print/pprust.rs | 40 ++++--- src/libsyntax/tokenstream.rs | 2 +- src/libsyntax_ext/concat_idents.rs | 3 +- src/libsyntax_ext/format.rs | 2 +- src/test/parse-fail/raw-str-delim.rs | 2 +- .../auxiliary/roman_numerals.rs | 2 +- .../run-pass/rfc-2151-raw-identifiers/attr.rs | 24 ++++ .../rfc-2151-raw-identifiers/basic.rs | 29 +++++ .../rfc-2151-raw-identifiers/items.rs | 41 +++++++ .../rfc-2151-raw-identifiers/macros.rs | 47 ++++++++ src/test/ui/raw-literal-keywords.rs | 25 ++++ src/test/ui/raw-literal-keywords.stderr | 20 ++++ src/test/ui/raw-literal-self.rs | 15 +++ src/test/ui/raw-literal-self.stderr | 8 ++ src/test/ui/raw-literal-underscore.rs | 15 +++ src/test/ui/raw-literal-underscore.stderr | 8 ++ 37 files changed, 475 insertions(+), 145 deletions(-) create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/attr.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/basic.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/items.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/macros.rs create mode 100644 src/test/ui/raw-literal-keywords.rs create mode 100644 src/test/ui/raw-literal-keywords.stderr create mode 100644 src/test/ui/raw-literal-self.rs create mode 100644 src/test/ui/raw-literal-self.stderr create mode 100644 src/test/ui/raw-literal-underscore.rs create mode 100644 src/test/ui/raw-literal-underscore.stderr diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index b239f8018bebb..d6e679bad48b7 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -681,7 +681,8 @@ impl TokenTree { Dollar => op!('$'), Question => op!('?'), - Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Ident(ident, false) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Ident(ident, true) => TokenNode::Term(Term(Symbol::intern(&format!("r#{}", ident)))), Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)), Interpolated(_) => { @@ -713,8 +714,14 @@ impl TokenTree { }, TokenNode::Term(symbol) => { let ident = ast::Ident { name: symbol.0, ctxt: self.span.0.ctxt() }; + let sym_str = symbol.0.as_str(); let token = - if symbol.0.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) }; + if sym_str.starts_with("'") { Lifetime(ident) } + else if sym_str.starts_with("r#") { + let name = Symbol::intern(&sym_str[2..]); + let ident = ast::Ident { name, ctxt: self.span.0.ctxt() }; + Ident(ident, true) + } else { Ident(ident, false) }; return TokenTree::Token(self.span.0, token).into(); } TokenNode::Literal(token) => return TokenTree::Token(self.span.0, token.0).into(), diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 513b6c835f982..0b037964981c9 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -318,7 +318,10 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( opt_name.hash_stable(hcx, hasher); } - token::Token::Ident(ident) | + token::Token::Ident(ident, is_raw) => { + ident.name.hash_stable(hcx, hasher); + is_raw.hash_stable(hcx, hasher); + } token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher), token::Token::Interpolated(_) => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 4215bf306a4fd..3c33d29585a8a 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -41,13 +41,13 @@ impl<'a> AstValidator<'a> { keywords::StaticLifetime.name(), keywords::Invalid.name()]; if !valid_names.contains(&lifetime.ident.name) && - token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() { + token::is_reserved_ident(lifetime.ident.without_first_quote()) { self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names"); } } fn check_label(&self, label: Ident, span: Span) { - if token::Ident(label.without_first_quote()).is_reserved_ident() { + if token::is_reserved_ident(label.without_first_quote()) { self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name)); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index dc22c23271d63..2cb2c76c6320b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3206,7 +3206,7 @@ impl<'a> Resolver<'a> { // `$crate::a::b` module = Some(self.resolve_crate_root(ident.node.ctxt, true)); continue - } else if i == 1 && !token::Ident(ident.node).is_path_segment_keyword() { + } else if i == 1 && !token::is_path_segment_keyword(ident.node) { let prev_name = path[0].node.name; if prev_name == keywords::Extern.name() || prev_name == keywords::CrateRoot.name() && diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 95fa0f3b52fef..0692a1e0d7f8a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -268,7 +268,7 @@ impl<'a> base::Resolver for Resolver<'a> { if k > 0 { tokens.push(TokenTree::Token(path.span, Token::ModSep).into()); } - let tok = Token::Ident(segment.identifier); + let tok = Token::from_ast_ident(segment.identifier); tokens.push(TokenTree::Token(path.span, tok).into()); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 4cbebdc3c1c39..78d2357e02b61 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -625,7 +625,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } else { Some(self.resolve_crate_root(source.ctxt.modern(), false)) } - } else if is_extern && !token::Ident(source).is_path_segment_keyword() { + } else if is_extern && !token::is_path_segment_keyword(source) { let crate_id = self.crate_loader.resolve_crate_from_path(source.name, directive.span); let crate_root = @@ -667,7 +667,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } PathResult::Failed(span, msg, true) => { let (mut self_path, mut self_result) = (module_path.clone(), None); - let is_special = |ident| token::Ident(ident).is_path_segment_keyword() && + let is_special = |ident| token::is_path_segment_keyword(ident) && ident.name != keywords::CrateRoot.name(); if !self_path.is_empty() && !is_special(self_path[0].node) && !(self_path.len() > 1 && is_special(self_path[1].node)) { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 659ec8a993dc8..cfa3f5a4e0b4f 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -323,12 +323,12 @@ impl<'a> Classifier<'a> { } // Keywords are also included in the identifier set. - token::Ident(ident) => { + token::Ident(ident, is_raw) => { match &*ident.name.as_str() { - "ref" | "mut" => Class::RefKeyWord, + "ref" | "mut" if !is_raw => Class::RefKeyWord, - "self" |"Self" => Class::Self_, - "false" | "true" => Class::Bool, + "self" | "Self" => Class::Self_, + "false" | "true" if !is_raw => Class::Bool, "Option" | "Result" => Class::PreludeTy, "Some" | "None" | "Ok" | "Err" => Class::PreludeVal, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1f16b728cd239..a3af6b247ee2f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -112,7 +112,7 @@ impl Path { // or starts with something like `self`/`super`/`$crate`/etc. pub fn make_root(&self) -> Option { if let Some(ident) = self.segments.get(0).map(|seg| seg.identifier) { - if ::parse::token::Ident(ident).is_path_segment_keyword() && + if ::parse::token::is_path_segment_keyword(ident) && ident.name != keywords::Crate.name() { return None; } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index f2cdcda98da51..5954b9eb27475 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -1106,7 +1106,8 @@ impl IntType { impl MetaItem { fn tokens(&self) -> TokenStream { - let ident = TokenTree::Token(self.span, Token::Ident(Ident::with_empty_ctxt(self.name))); + let ident = TokenTree::Token(self.span, + Token::from_ast_ident(Ident::with_empty_ctxt(self.name))); TokenStream::concat(vec![ident.into(), self.node.tokens(self.span)]) } @@ -1114,9 +1115,9 @@ impl MetaItem { where I: Iterator, { let (span, name) = match tokens.next() { - Some(TokenTree::Token(span, Token::Ident(ident))) => (span, ident.name), + Some(TokenTree::Token(span, Token::Ident(ident, _))) => (span, ident.name), Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 { - token::Nonterminal::NtIdent(ident) => (ident.span, ident.node.name), + token::Nonterminal::NtIdent(ident, _) => (ident.span, ident.node.name), token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()), _ => return None, }, @@ -1269,14 +1270,14 @@ impl LitKind { "true" } else { "false" - }))), + })), false), } } fn from_token(token: Token) -> Option { match token { - Token::Ident(ident) if ident.name == "true" => Some(LitKind::Bool(true)), - Token::Ident(ident) if ident.name == "false" => Some(LitKind::Bool(false)), + Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)), + Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)), Token::Interpolated(ref nt) => match nt.0 { token::NtExpr(ref v) => match v.node { ExprKind::Lit(ref lit) => Some(lit.node.clone()), diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 2c91844da96d7..c7e453c9e1054 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -44,7 +44,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box { let code = match (token_tree.len(), token_tree.get(0)) { - (1, Some(&TokenTree::Token(_, token::Ident(code)))) => code, + (1, Some(&TokenTree::Token(_, token::Ident(code, false)))) => code, _ => unreachable!() }; @@ -82,10 +82,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, token_tree.get(1), token_tree.get(2) ) { - (1, Some(&TokenTree::Token(_, token::Ident(ref code))), None, None) => { + (1, Some(&TokenTree::Token(_, token::Ident(ref code, false))), None, None) => { (code, None) }, - (3, Some(&TokenTree::Token(_, token::Ident(ref code))), + (3, Some(&TokenTree::Token(_, token::Ident(ref code, false))), Some(&TokenTree::Token(_, token::Comma)), Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => { (code, Some(description)) @@ -150,9 +150,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. - &TokenTree::Token(_, token::Ident(ref crate_name)), + &TokenTree::Token(_, token::Ident(ref crate_name, false)), // DIAGNOSTICS ident. - &TokenTree::Token(_, token::Ident(ref name)) + &TokenTree::Token(_, token::Ident(ref name, false)) ) => (*&crate_name, name), _ => unreachable!() }; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 23c42972912a1..c3ae0fd2ca863 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -229,8 +229,9 @@ impl TTMacroExpander for F impl Folder for AvoidInterpolatedIdents { fn fold_tt(&mut self, tt: tokenstream::TokenTree) -> tokenstream::TokenTree { if let tokenstream::TokenTree::Token(_, token::Interpolated(ref nt)) = tt { - if let token::NtIdent(ident) = nt.0 { - return tokenstream::TokenTree::Token(ident.span, token::Ident(ident.node)); + if let token::NtIdent(ident, is_raw) = nt.0 { + return tokenstream::TokenTree::Token(ident.span, + token::Ident(ident.node, is_raw)); } } fold::noop_fold_tt(tt, self) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 6844532e7b375..090b9a3544630 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -75,7 +75,7 @@ pub mod rt { impl ToTokens for ast::Ident { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![TokenTree::Token(DUMMY_SP, token::Ident(*self))] + vec![TokenTree::Token(DUMMY_SP, Token::from_ast_ident(*self))] } } @@ -238,7 +238,8 @@ pub mod rt { if i > 0 { inner.push(TokenTree::Token(self.span, token::Colon).into()); } - inner.push(TokenTree::Token(self.span, token::Ident(segment.identifier)).into()); + inner.push(TokenTree::Token(self.span, + token::Ident(segment.identifier, false)).into()); } inner.push(self.tokens.clone()); @@ -658,10 +659,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Literal(token::ByteStr(i), suf) => return mk_lit!("ByteStr", suf, i), token::Literal(token::ByteStrRaw(i, n), suf) => return mk_lit!("ByteStrRaw", suf, i, n), - token::Ident(ident) => { + token::Ident(ident, is_raw) => { return cx.expr_call(sp, mk_token_path(cx, sp, "Ident"), - vec![mk_ident(cx, sp, ident)]); + vec![mk_ident(cx, sp, ident), cx.expr_bool(sp, is_raw)]); } token::Lifetime(ident) => { @@ -720,7 +721,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, quoted: bool) -> Vec { match *tt { - TokenTree::Token(sp, token::Ident(ident)) if quoted => { + TokenTree::Token(sp, token::Ident(ident, _)) if quoted => { // tt.extend($ident.to_tokens(ext_cx)) let e_to_toks = diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 667653b5f7f26..714b7ca981da0 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -365,7 +365,7 @@ pub fn parse_failure_msg(tok: Token) -> String { /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1: &Token, t2: &Token) -> bool { if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { - id1.name == id2.name + id1.name == id2.name && t1.is_raw_ident() == t2.is_raw_ident() } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { id1.name == id2.name } else { @@ -711,9 +711,10 @@ pub fn parse( /// The token is an identifier, but not `_`. /// We prohibit passing `_` to macros expecting `ident` for now. -fn get_macro_ident(token: &Token) -> Option { +fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { match *token { - token::Ident(ident) if ident.name != keywords::Underscore.name() => Some(ident), + token::Ident(ident, is_raw) if ident.name != keywords::Underscore.name() => + Some((ident, is_raw)), _ => None, } } @@ -737,7 +738,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { "ident" => get_macro_ident(token).is_some(), "vis" => match *token { // The follow-set of :vis + "priv" keyword + interpolated - Token::Comma | Token::Ident(_) | Token::Interpolated(_) => true, + Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true, _ => token.can_begin_type(), }, "block" => match *token { @@ -746,7 +747,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { token::NtItem(_) | token::NtPat(_) | token::NtTy(_) - | token::NtIdent(_) + | token::NtIdent(..) | token::NtMeta(_) | token::NtPath(_) | token::NtVis(_) => false, // none of these may start with '{'. @@ -755,7 +756,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { _ => false, }, "path" | "meta" => match *token { - Token::ModSep | Token::Ident(_) => true, + Token::ModSep | Token::Ident(..) => true, Token::Interpolated(ref nt) => match nt.0 { token::NtPath(_) | token::NtMeta(_) => true, _ => may_be_ident(&nt.0), @@ -763,7 +764,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { _ => false, }, "pat" => match *token { - Token::Ident(_) | // box, ref, mut, and other identifiers (can stricten) + Token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) Token::OpenDelim(token::Paren) | // tuple pattern Token::OpenDelim(token::Bracket) | // slice pattern Token::BinOp(token::And) | // reference @@ -823,9 +824,9 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "expr" => token::NtExpr(panictry!(p.parse_expr())), "ty" => token::NtTy(panictry!(p.parse_ty())), // this could be handled like a token, since it is one - "ident" => if let Some(ident) = get_macro_ident(&p.token) { + "ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) { p.bump(); - token::NtIdent(respan(p.prev_span, ident)) + token::NtIdent(respan(p.prev_span, ident), is_raw) } else { let token_str = pprust::token_to_string(&p.token); p.fatal(&format!("expected ident, found {}", &token_str)).emit(); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a4b2c3990f5e1..10e5926eb9e36 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -831,7 +831,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { TokenTree::Token(_, ref tok) => match *tok { FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true), - Ident(i) if i.name == "if" || i.name == "in" => Ok(true), + Ident(i, false) if i.name == "if" || i.name == "in" => Ok(true), _ => Ok(false) }, _ => Ok(false), @@ -840,7 +840,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) | Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true), - Ident(i) if i.name == "as" || i.name == "where" => Ok(true), + Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true), _ => Ok(false) }, TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => Ok(true), @@ -860,7 +860,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { Comma => Ok(true), - Ident(i) if i.name != "priv" => Ok(true), + Ident(i, is_raw) if is_raw || i.name != "priv" => Ok(true), ref tok => Ok(tok.can_begin_type()) }, TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident" diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 122bb9ba024a4..11eb9b940aea5 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -296,7 +296,7 @@ where name: keywords::DollarCrate.name(), ..ident }; - TokenTree::Token(span, token::Ident(ident)) + TokenTree::Token(span, token::Ident(ident, false)) } else { TokenTree::MetaVar(span, ident) } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 7883c4bbc1648..0f5855a32259c 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -169,7 +169,7 @@ pub fn transcribe(cx: &ExtCtxt, Ident { ctxt: ident.ctxt.apply_mark(cx.current_expansion.mark), ..ident }; sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); result.push(TokenTree::Token(sp, token::Dollar).into()); - result.push(TokenTree::Token(sp, token::Ident(ident)).into()); + result.push(TokenTree::Token(sp, token::Ident(ident, false)).into()); } } quoted::TokenTree::Delimited(mut span, delimited) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 46e6027b094bc..05a3150c139c9 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -578,7 +578,7 @@ pub fn noop_fold_tts(tts: TokenStream, fld: &mut T) -> TokenStream { // apply ident folder if it's an ident, apply other folds to interpolated nodes pub fn noop_fold_token(t: token::Token, fld: &mut T) -> token::Token { match t { - token::Ident(id) => token::Ident(fld.fold_ident(id)), + token::Ident(id, is_raw) => token::Ident(fld.fold_ident(id), is_raw), token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)), token::Interpolated(nt) => { let nt = match Lrc::try_unwrap(nt) { @@ -630,7 +630,8 @@ pub fn noop_fold_interpolated(nt: token::Nonterminal, fld: &mut T) token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), - token::NtIdent(id) => token::NtIdent(Spanned::{node: fld.fold_ident(id.node), ..id}), + token::NtIdent(id, is_raw) => + token::NtIdent(Spanned::{node: fld.fold_ident(id.node), ..id}, is_raw), token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)), token::NtPath(path) => token::NtPath(fld.fold_path(path)), token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)), diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0e20eb49d395e..0596fb44abeea 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -14,7 +14,7 @@ use codemap::{CodeMap, FilePathMapping}; use errors::{FatalError, DiagnosticBuilder}; use parse::{token, ParseSess}; use str::char_at; -use symbol::Symbol; +use symbol::{Symbol, keywords}; use std_unicode::property::Pattern_White_Space; use std::borrow::Cow; @@ -1115,26 +1115,49 @@ impl<'a> StringReader<'a> { /// token, and updates the interner fn next_token_inner(&mut self) -> Result { let c = self.ch; - if ident_start(c) && - match (c.unwrap(), self.nextch(), self.nextnextch()) { - // Note: r as in r" or r#" is part of a raw string literal, - // b as in b' is part of a byte literal. - // They are not identifiers, and are handled further down. - ('r', Some('"'), _) | - ('r', Some('#'), _) | - ('b', Some('"'), _) | - ('b', Some('\''), _) | - ('b', Some('r'), Some('"')) | - ('b', Some('r'), Some('#')) => false, - _ => true, - } { - let start = self.pos; - while ident_continue(self.ch) { - self.bump(); - } - // FIXME: perform NFKC normalization here. (Issue #2253) - return Ok(self.with_str_from(start, |string| token::Ident(self.mk_ident(string)))); + if ident_start(c) { + let (is_ident_start, is_raw_ident) = + match (c.unwrap(), self.nextch(), self.nextnextch()) { + // r# followed by an identifier starter is a raw identifier. + // This is an exception to the r# case below. + ('r', Some('#'), x) if ident_start(x) => (true, true), + // r as in r" or r#" is part of a raw string literal. + // b as in b' is part of a byte literal. + // They are not identifiers, and are handled further down. + ('r', Some('"'), _) | + ('r', Some('#'), _) | + ('b', Some('"'), _) | + ('b', Some('\''), _) | + ('b', Some('r'), Some('"')) | + ('b', Some('r'), Some('#')) => (false, false), + _ => (true, false), + }; + if is_ident_start { + let raw_start = self.pos; + if is_raw_ident { + // Consume the 'r#' characters. + self.bump(); + self.bump(); + } + + let start = self.pos; + while ident_continue(self.ch) { + self.bump(); + } + + return Ok(self.with_str_from(start, |string| { + // FIXME: perform NFKC normalization here. (Issue #2253) + let ident = self.mk_ident(string); + if is_raw_ident && (token::is_path_segment_keyword(ident) || + ident.name == keywords::Underscore.name()) { + self.fatal_span_(raw_start, self.pos, + &format!("`r#{}` is not currently supported.", ident.name) + ).raise(); + } + token::Ident(ident, is_raw_ident) + })); + } } if is_dec_digit(c) { @@ -1801,7 +1824,7 @@ mod tests { assert_eq!(string_reader.next_token().tok, token::Whitespace); let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan { - tok: token::Ident(id), + tok: token::Ident(id, false), sp: Span::new(BytePos(21), BytePos(23), NO_EXPANSION), }; assert_eq!(tok1, tok2); @@ -1811,7 +1834,7 @@ mod tests { // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan { - tok: token::Ident(Ident::from_str("main")), + tok: mk_ident("main"), sp: Span::new(BytePos(24), BytePos(28), NO_EXPANSION), }; assert_eq!(tok3, tok4); @@ -1830,7 +1853,7 @@ mod tests { // make the identifier by looking up the string in the interner fn mk_ident(id: &str) -> token::Token { - token::Ident(Ident::from_str(id)) + token::Token::from_ast_ident(Ident::from_str(id)) } #[test] diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f7e5d40b52468..4acfdab53c094 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -741,9 +741,9 @@ mod tests { match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) { ( 4, - Some(&TokenTree::Token(_, token::Ident(name_macro_rules))), + Some(&TokenTree::Token(_, token::Ident(name_macro_rules, false))), Some(&TokenTree::Token(_, token::Not)), - Some(&TokenTree::Token(_, token::Ident(name_zip))), + Some(&TokenTree::Token(_, token::Ident(name_zip, false))), Some(&TokenTree::Delimited(_, ref macro_delimed)), ) if name_macro_rules.name == "macro_rules" @@ -762,7 +762,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), + Some(&TokenTree::Token(_, token::Ident(ident, false))), ) if first_delimed.delim == token::Paren && ident.name == "a" => {}, _ => panic!("value 3: {:?}", *first_delimed), @@ -772,7 +772,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), + Some(&TokenTree::Token(_, token::Ident(ident, false))), ) if second_delimed.delim == token::Paren && ident.name == "a" => {}, @@ -793,17 +793,18 @@ mod tests { let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); let expected = TokenStream::concat(vec![ - TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(), - TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(), + TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"), false)).into(), + TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"), false)).into(), TokenTree::Delimited( sp(5, 14), tokenstream::Delimited { delim: token::DelimToken::Paren, tts: TokenStream::concat(vec![ - TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(6, 7), + token::Ident(Ident::from_str("b"), false)).into(), TokenTree::Token(sp(8, 9), token::Colon).into(), TokenTree::Token(sp(10, 13), - token::Ident(Ident::from_str("i32"))).into(), + token::Ident(Ident::from_str("i32"), false)).into(), ]).into(), }).into(), TokenTree::Delimited( @@ -811,7 +812,8 @@ mod tests { tokenstream::Delimited { delim: token::DelimToken::Brace, tts: TokenStream::concat(vec![ - TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(17, 18), + token::Ident(Ident::from_str("b"), false)).into(), TokenTree::Token(sp(18, 19), token::Semi).into(), ]).into(), }).into() diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb5010a638df4..4c1575cf58939 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -358,7 +358,7 @@ impl TokenCursor { let body = TokenTree::Delimited(sp, Delimited { delim: token::Bracket, - tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"))), + tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)), TokenTree::Token(sp, token::Eq), TokenTree::Token(sp, token::Literal( token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))] @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i) => { + token::Ident(i, _) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -1925,7 +1925,7 @@ impl<'a> Parser<'a> { pub fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(sid) if self.token.is_path_segment_keyword() => { + token::Ident(sid, _) if self.token.is_path_segment_keyword() => { self.bump(); Ok(sid) } @@ -2740,11 +2740,14 @@ impl<'a> Parser<'a> { } pub fn process_potential_macro_variable(&mut self) { - let ident = match self.token { + let (ident, is_raw) = match self.token { token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() && self.look_ahead(1, |t| t.is_ident()) => { self.bump(); - let name = match self.token { token::Ident(ident) => ident, _ => unreachable!() }; + let name = match self.token { + token::Ident(ident, _) => ident, + _ => unreachable!() + }; let mut err = self.fatal(&format!("unknown macro variable `{}`", name)); err.span_label(self.span, "unknown macro variable"); err.emit(); @@ -2753,13 +2756,13 @@ impl<'a> Parser<'a> { token::Interpolated(ref nt) => { self.meta_var_span = Some(self.span); match nt.0 { - token::NtIdent(ident) => ident, + token::NtIdent(ident, is_raw) => (ident, is_raw), _ => return, } } _ => return, }; - self.token = token::Ident(ident.node); + self.token = token::Ident(ident.node, is_raw); self.span = ident.span; } @@ -4245,7 +4248,7 @@ impl<'a> Parser<'a> { -> PResult<'a, Option>> { let token_lo = self.span; let (ident, def) = match self.token { - token::Ident(ident) if ident.name == keywords::Macro.name() => { + token::Ident(ident, false) if ident.name == keywords::Macro.name() => { self.bump(); let ident = self.parse_ident()?; let tokens = if self.check(&token::OpenDelim(token::Brace)) { @@ -4273,7 +4276,7 @@ impl<'a> Parser<'a> { (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) } - token::Ident(ident) if ident.name == "macro_rules" && + token::Ident(ident, _) if ident.name == "macro_rules" && self.look_ahead(1, |t| *t == token::Not) => { let prev_span = self.prev_span; self.complain_if_pub_macro(&vis.node, prev_span); @@ -5078,7 +5081,9 @@ impl<'a> Parser<'a> { fn parse_self_arg(&mut self) -> PResult<'a, Option> { let expect_ident = |this: &mut Self| match this.token { // Preserve hygienic context. - token::Ident(ident) => { let sp = this.span; this.bump(); codemap::respan(sp, ident) } + token::Ident(ident, _) => { + let sp = this.span; this.bump(); codemap::respan(sp, ident) + } _ => unreachable!() }; let isolated_self = |this: &mut Self, n| { @@ -5375,7 +5380,7 @@ impl<'a> Parser<'a> { VisibilityKind::Inherited => Ok(()), _ => { let is_macro_rules: bool = match self.token { - token::Ident(sid) => sid.name == Symbol::intern("macro_rules"), + token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"), _ => false, }; if is_macro_rules { @@ -7016,7 +7021,7 @@ impl<'a> Parser<'a> { fn parse_rename(&mut self) -> PResult<'a, Option> { if self.eat_keyword(keywords::As) { match self.token { - token::Ident(ident) if ident.name == keywords::Underscore.name() => { + token::Ident(ident, false) if ident.name == keywords::Underscore.name() => { self.bump(); // `_` Ok(Some(Ident { name: ident.name.gensymed(), ..ident })) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 4ada9e20f2cc0..6406651bcba88 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -91,8 +91,8 @@ impl Lit { } } -fn ident_can_begin_expr(ident: ast::Ident) -> bool { - let ident_token: Token = Ident(ident); +fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool { + let ident_token: Token = Ident(ident, is_raw); !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() || @@ -116,8 +116,8 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool { ].contains(&ident.name) } -fn ident_can_begin_type(ident: ast::Ident) -> bool { - let ident_token: Token = Ident(ident); +fn ident_can_begin_type(ident: ast::Ident, is_raw: bool) -> bool { + let ident_token: Token = Ident(ident, is_raw); !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() || @@ -132,6 +132,37 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool { ].contains(&ident.name) } +pub fn is_path_segment_keyword(id: ast::Ident) -> bool { + id.name == keywords::Super.name() || + id.name == keywords::SelfValue.name() || + id.name == keywords::SelfType.name() || + id.name == keywords::Extern.name() || + id.name == keywords::Crate.name() || + id.name == keywords::CrateRoot.name() || + id.name == keywords::DollarCrate.name() +} + +// Returns true for reserved identifiers used internally for elided lifetimes, +// unnamed method parameters, crate root module, error recovery etc. +pub fn is_special_ident(id: ast::Ident) -> bool { + id.name <= keywords::Underscore.name() +} + +/// Returns `true` if the token is a keyword used in the language. +pub fn is_used_keyword(id: ast::Ident) -> bool { + id.name >= keywords::As.name() && id.name <= keywords::While.name() +} + +/// Returns `true` if the token is a keyword reserved for possible future use. +pub fn is_unused_keyword(id: ast::Ident) -> bool { + id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name() +} + +/// Returns `true` if the token is either a special identifier or a keyword. +pub fn is_reserved_ident(id: ast::Ident) -> bool { + is_special_ident(id) || is_used_keyword(id) || is_unused_keyword(id) +} + #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)] pub enum Token { /* Expression-operator symbols. */ @@ -175,7 +206,7 @@ pub enum Token { Literal(Lit, Option), /* Name components */ - Ident(ast::Ident), + Ident(ast::Ident, /* is_raw */ bool), Lifetime(ast::Ident), // The `LazyTokenStream` is a pure function of the `Nonterminal`, @@ -203,6 +234,11 @@ impl Token { Token::Interpolated(Lrc::new((nt, LazyTokenStream::new()))) } + /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. + pub fn from_ast_ident(ident: ast::Ident) -> Token { + Ident(ident, is_reserved_ident(ident)) + } + /// Returns `true` if the token starts with '>'. pub fn is_like_gt(&self) -> bool { match *self { @@ -214,7 +250,8 @@ impl Token { /// Returns `true` if the token can appear at the start of an expression. pub fn can_begin_expr(&self) -> bool { match *self { - Ident(ident) => ident_can_begin_expr(ident), // value name or keyword + Ident(ident, is_raw) => + ident_can_begin_expr(ident, is_raw), // value name or keyword OpenDelim(..) | // tuple, array or block Literal(..) | // literal Not | // operator not @@ -239,7 +276,8 @@ impl Token { /// Returns `true` if the token can appear at the start of a type. pub fn can_begin_type(&self) -> bool { match *self { - Ident(ident) => ident_can_begin_type(ident), // type name or keyword + Ident(ident, is_raw) => + ident_can_begin_type(ident, is_raw), // type name or keyword OpenDelim(Paren) | // tuple OpenDelim(Bracket) | // array Not | // never @@ -272,17 +310,32 @@ impl Token { } } - pub fn ident(&self) -> Option { + fn ident_common(&self, allow_raw: bool) -> Option { match *self { - Ident(ident) => Some(ident), + Ident(ident, is_raw) if !is_raw || allow_raw => Some(ident), Interpolated(ref nt) => match nt.0 { - NtIdent(ident) => Some(ident.node), + NtIdent(ident, is_raw) if !is_raw || allow_raw => Some(ident.node), _ => None, }, _ => None, } } + pub fn nonraw_ident(&self) -> Option { + self.ident_common(false) + } + + pub fn is_raw_ident(&self) -> bool { + match *self { + Ident(_, true) => true, + _ => false, + } + } + + pub fn ident(&self) -> Option { + self.ident_common(true) + } + /// Returns `true` if the token is an identifier. pub fn is_ident(&self) -> bool { self.ident().is_some() @@ -351,18 +404,12 @@ impl Token { /// Returns `true` if the token is a given keyword, `kw`. pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - self.ident().map(|ident| ident.name == kw.name()).unwrap_or(false) + self.nonraw_ident().map(|ident| ident.name == kw.name()).unwrap_or(false) } pub fn is_path_segment_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name == keywords::Super.name() || - id.name == keywords::SelfValue.name() || - id.name == keywords::SelfType.name() || - id.name == keywords::Extern.name() || - id.name == keywords::Crate.name() || - id.name == keywords::CrateRoot.name() || - id.name == keywords::DollarCrate.name(), + match self.nonraw_ident() { + Some(id) => is_path_segment_keyword(id), None => false, } } @@ -370,24 +417,24 @@ impl Token { // Returns true for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { - match self.ident() { - Some(id) => id.name <= keywords::Underscore.name(), + match self.nonraw_ident() { + Some(id) => is_special_ident(id), _ => false, } } /// Returns `true` if the token is a keyword used in the language. pub fn is_used_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(), + match self.nonraw_ident() { + Some(id) => is_used_keyword(id), _ => false, } } /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_unused_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(), + match self.nonraw_ident() { + Some(id) => is_unused_keyword(id), _ => false, } } @@ -460,7 +507,10 @@ impl Token { /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved_ident(&self) -> bool { - self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword() + match self.nonraw_ident() { + Some(id) => is_reserved_ident(id), + _ => false, + } } pub fn interpolated_to_tokenstream(&self, sess: &ParseSess, span: Span) @@ -496,8 +546,8 @@ impl Token { Nonterminal::NtImplItem(ref item) => { tokens = prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span); } - Nonterminal::NtIdent(ident) => { - let token = Token::Ident(ident.node); + Nonterminal::NtIdent(ident, is_raw) => { + let token = Token::Ident(ident.node, is_raw); tokens = Some(TokenTree::Token(ident.span, token).into()); } Nonterminal::NtLifetime(lifetime) => { @@ -529,7 +579,7 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), - NtIdent(ast::SpannedIdent), + NtIdent(ast::SpannedIdent, /* is_raw */ bool), /// Stuff inside brackets for attributes NtMeta(ast::MetaItem), NtPath(ast::Path), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7adb2848f8d94..50577a26abf41 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -250,7 +250,8 @@ pub fn token_to_string(tok: &Token) -> String { } /* Name components */ - token::Ident(s) => s.to_string(), + token::Ident(s, false) => s.to_string(), + token::Ident(s, true) => format!("r#{}", s), token::Lifetime(s) => s.to_string(), /* Other */ @@ -261,24 +262,25 @@ pub fn token_to_string(tok: &Token) -> String { token::Shebang(s) => format!("/* shebang: {}*/", s), token::Interpolated(ref nt) => match nt.0 { - token::NtExpr(ref e) => expr_to_string(e), - token::NtMeta(ref e) => meta_item_to_string(e), - token::NtTy(ref e) => ty_to_string(e), - token::NtPath(ref e) => path_to_string(e), - token::NtItem(ref e) => item_to_string(e), - token::NtBlock(ref e) => block_to_string(e), - token::NtStmt(ref e) => stmt_to_string(e), - token::NtPat(ref e) => pat_to_string(e), - token::NtIdent(ref e) => ident_to_string(e.node), - token::NtTT(ref tree) => tt_to_string(tree.clone()), - token::NtArm(ref e) => arm_to_string(e), - token::NtImplItem(ref e) => impl_item_to_string(e), - token::NtTraitItem(ref e) => trait_item_to_string(e), - token::NtGenerics(ref e) => generic_params_to_string(&e.params), - token::NtWhereClause(ref e) => where_clause_to_string(e), - token::NtArg(ref e) => arg_to_string(e), - token::NtVis(ref e) => vis_to_string(e), - token::NtLifetime(ref e) => lifetime_to_string(e), + token::NtExpr(ref e) => expr_to_string(e), + token::NtMeta(ref e) => meta_item_to_string(e), + token::NtTy(ref e) => ty_to_string(e), + token::NtPath(ref e) => path_to_string(e), + token::NtItem(ref e) => item_to_string(e), + token::NtBlock(ref e) => block_to_string(e), + token::NtStmt(ref e) => stmt_to_string(e), + token::NtPat(ref e) => pat_to_string(e), + token::NtIdent(ref e, false) => ident_to_string(e.node), + token::NtIdent(ref e, true) => format!("r#{}", ident_to_string(e.node)), + token::NtTT(ref tree) => tt_to_string(tree.clone()), + token::NtArm(ref e) => arm_to_string(e), + token::NtImplItem(ref e) => impl_item_to_string(e), + token::NtTraitItem(ref e) => trait_item_to_string(e), + token::NtGenerics(ref e) => generic_params_to_string(&e.params), + token::NtWhereClause(ref e) => where_clause_to_string(e), + token::NtArg(ref e) => arg_to_string(e), + token::NtVis(ref e) => vis_to_string(e), + token::NtLifetime(ref e) => lifetime_to_string(e), } } } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 1219e909e121a..3a7a1b9a66966 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -684,7 +684,7 @@ mod tests { with_globals(|| { let test0: TokenStream = Vec::::new().into_iter().collect(); let test1: TokenStream = - TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"))).into(); + TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"), false)).into(); let test2 = string_to_ts("foo(bar::baz)"); assert_eq!(test0.is_empty(), true); diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8d0104e512bfb..d513008f0e2d3 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -44,7 +44,8 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, } } else { match *e { - TokenTree::Token(_, token::Ident(ident)) => res_str.push_str(&ident.name.as_str()), + TokenTree::Token(_, token::Ident(ident, _)) => + res_str.push_str(&ident.name.as_str()), _ => { cx.span_err(sp, "concat_idents! requires ident args."); return DummyResult::expr(sp); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 8fd95aa1ca861..d9c68e3167bd6 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -149,7 +149,7 @@ fn parse_args(ecx: &mut ExtCtxt, if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) { named = true; let ident = match p.token { - token::Ident(i) => { + token::Ident(i, _) => { p.bump(); i } diff --git a/src/test/parse-fail/raw-str-delim.rs b/src/test/parse-fail/raw-str-delim.rs index 3fc5f8aae1876..8c0027287dece 100644 --- a/src/test/parse-fail/raw-str-delim.rs +++ b/src/test/parse-fail/raw-str-delim.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only static s: &'static str = - r#x"#"x# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation + r#~"#"~# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation ; diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs index 26419a51513f2..ed0434051b703 100644 --- a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs +++ b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs @@ -49,7 +49,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) } let text = match args[0] { - TokenTree::Token(_, token::Ident(s)) => s.to_string(), + TokenTree::Token(_, token::Ident(s, _)) => s.to_string(), _ => { cx.span_err(sp, "argument should be a single identifier"); return DummyResult::any(sp); diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs new file mode 100644 index 0000000000000..2ef9fba2076ad --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +#[r#repr(r#C, r#packed)] +struct Test { + a: bool, b: u64 +} + +#[r#derive(r#Debug)] +struct Test2(u32); + +pub fn main() { + assert_eq!(mem::size_of::(), 9); + assert_eq!("Test2(123)", format!("{:?}", Test2(123))); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs new file mode 100644 index 0000000000000..eefce3981bec1 --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn r#fn(r#match: u32) -> u32 { + r#match +} + +pub fn main() { + let r#struct = 1; + assert_eq!(1, r#struct); + + let foo = 2; + assert_eq!(2, r#foo); + + let r#bar = 3; + assert_eq!(3, bar); + + assert_eq!(4, r#fn(4)); + + let r#true = false; + assert_eq!(r#true, false); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs new file mode 100644 index 0000000000000..4306ffe2042af --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs @@ -0,0 +1,41 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug, PartialEq, Eq)] +struct IntWrapper(u32); + +#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Copy, Clone, Default)] +struct HasKeywordField { + r#struct: u32, +} + +struct Generic(T); + +trait Trait { + fn r#trait(&self) -> u32; +} +impl Trait for Generic { + fn r#trait(&self) -> u32 { + self.0 + } +} + +pub fn main() { + assert_eq!(IntWrapper(1), r#IntWrapper(1)); + + match IntWrapper(2) { + r#IntWrapper(r#struct) => assert_eq!(2, r#struct), + } + + assert_eq!("HasKeywordField { struct: 3 }", format!("{:?}", HasKeywordField { r#struct: 3 })); + + assert_eq!(4, Generic(4).0); + assert_eq!(5, Generic(5).r#trait()); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs new file mode 100644 index 0000000000000..9e89b79266cfa --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs @@ -0,0 +1,47 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(decl_macro)] + +r#macro_rules! r#struct { + ($r#struct:expr) => { $r#struct } +} + +macro_rules! old_macro { + ($a:expr) => {$a} +} + +macro r#decl_macro($r#fn:expr) { + $r#fn +} + +macro passthrough($id:ident) { + $id +} + +macro_rules! test_pat_match { + (a) => { 6 }; + (r#a) => { 7 }; +} + +pub fn main() { + r#println!("{struct}", r#struct = 1); + assert_eq!(2, r#struct!(2)); + assert_eq!(3, r#old_macro!(3)); + assert_eq!(4, decl_macro!(4)); + + let r#match = 5; + assert_eq!(5, passthrough!(r#match)); + + assert_eq!("r#struct", stringify!(r#struct)); + + assert_eq!(6, test_pat_match!(a)); + assert_eq!(7, test_pat_match!(r#a)); +} diff --git a/src/test/ui/raw-literal-keywords.rs b/src/test/ui/raw-literal-keywords.rs new file mode 100644 index 0000000000000..8b3747dbe15e4 --- /dev/null +++ b/src/test/ui/raw-literal-keywords.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +#![feature(dyn_trait)] + +fn test_if() { + r#if true { } //~ ERROR found `true` +} + +fn test_struct() { + r#struct Test; //~ ERROR found `Test` +} + +fn test_union() { + r#union Test; //~ ERROR found `Test` +} diff --git a/src/test/ui/raw-literal-keywords.stderr b/src/test/ui/raw-literal-keywords.stderr new file mode 100644 index 0000000000000..022f80ae8a4ec --- /dev/null +++ b/src/test/ui/raw-literal-keywords.stderr @@ -0,0 +1,20 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true` + --> $DIR/raw-literal-keywords.rs:16:10 + | +LL | r#if true { } //~ ERROR found `true` + | ^^^^ expected one of 8 possible tokens here + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:20:14 + | +LL | r#struct Test; //~ ERROR found `Test` + | ^^^^ expected one of 8 possible tokens here + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:24:13 + | +LL | r#union Test; //~ ERROR found `Test` + | ^^^^ expected one of 8 possible tokens here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/raw-literal-self.rs b/src/test/ui/raw-literal-self.rs new file mode 100644 index 0000000000000..17496d767b622 --- /dev/null +++ b/src/test/ui/raw-literal-self.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +fn self_test(r#self: u32) { + //~^ ERROR `r#self` is not currently supported. +} diff --git a/src/test/ui/raw-literal-self.stderr b/src/test/ui/raw-literal-self.stderr new file mode 100644 index 0000000000000..f4b759372471c --- /dev/null +++ b/src/test/ui/raw-literal-self.stderr @@ -0,0 +1,8 @@ +error: `r#self` is not currently supported. + --> $DIR/raw-literal-self.rs:13:14 + | +LL | fn self_test(r#self: u32) { + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/raw-literal-underscore.rs b/src/test/ui/raw-literal-underscore.rs new file mode 100644 index 0000000000000..ec33e4861958e --- /dev/null +++ b/src/test/ui/raw-literal-underscore.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +fn underscore_test(r#_: u32) { + //~^ ERROR `r#_` is not currently supported. +} diff --git a/src/test/ui/raw-literal-underscore.stderr b/src/test/ui/raw-literal-underscore.stderr new file mode 100644 index 0000000000000..8072eee4f0604 --- /dev/null +++ b/src/test/ui/raw-literal-underscore.stderr @@ -0,0 +1,8 @@ +error: `r#_` is not currently supported. + --> $DIR/raw-literal-underscore.rs:13:20 + | +LL | fn underscore_test(r#_: u32) { + | ^^^ + +error: aborting due to previous error + From 7d5c29b9eae5857c040bf6f1b2d729596c8af3ae Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Wed, 14 Mar 2018 02:00:41 -0500 Subject: [PATCH 107/546] Feature gate raw identifiers. --- src/libsyntax/feature_gate.rs | 14 ++++++++++++++ src/libsyntax/parse/lexer/mod.rs | 1 + src/libsyntax/parse/mod.rs | 4 ++++ src/libsyntax/parse/parser.rs | 5 ++++- src/test/run-pass/rfc-2151-raw-identifiers/attr.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/basic.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/items.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/macros.rs | 1 + src/test/ui/feature-gate-raw-identifiers.rs | 14 ++++++++++++++ src/test/ui/feature-gate-raw-identifiers.stderr | 11 +++++++++++ src/test/ui/raw-literal-keywords.rs | 1 + src/test/ui/raw-literal-keywords.stderr | 6 +++--- src/test/ui/raw-literal-self.rs | 2 ++ src/test/ui/raw-literal-self.stderr | 2 +- 14 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/feature-gate-raw-identifiers.rs create mode 100644 src/test/ui/feature-gate-raw-identifiers.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd686064..153e42c8214f8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -452,6 +452,9 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), + + // Raw identifiers allowing keyword names to be used + (active, raw_identifiers, "1.26.0", Some(48589), None), ); declare_features! ( @@ -1932,6 +1935,17 @@ pub fn check_crate(krate: &ast::Crate, parse_sess: sess, plugin_attributes, }; + + if !features.raw_identifiers { + for &span in sess.raw_identifier_spans.borrow().iter() { + if !span.allows_unstable() { + gate_feature!(&ctx, raw_identifiers, span, + "raw identifiers are experimental and subject to change" + ); + } + } + } + let visitor = &mut PostExpansionVisitor { context: &ctx }; visitor.whole_crate_feature_gates(krate); visit::walk_crate(visitor, krate); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0596fb44abeea..8e746ea69e79f 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1796,6 +1796,7 @@ mod tests { included_mod_stack: RefCell::new(Vec::new()), code_map: cm, missing_fragment_specifiers: RefCell::new(HashSet::new()), + raw_identifier_spans: RefCell::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), non_modrs_mods: RefCell::new(vec![]), } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 4acfdab53c094..03ac1e8b5a9bb 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -48,6 +48,9 @@ pub struct ParseSess { pub unstable_features: UnstableFeatures, pub config: CrateConfig, pub missing_fragment_specifiers: RefCell>, + /// Places where raw identifiers were used. This is used for feature gating + /// raw identifiers + pub raw_identifier_spans: RefCell>, /// The registered diagnostics codes pub registered_diagnostics: Lock, // Spans where a `mod foo;` statement was included in a non-mod.rs file. @@ -74,6 +77,7 @@ impl ParseSess { unstable_features: UnstableFeatures::from_environment(), config: HashSet::new(), missing_fragment_specifiers: RefCell::new(HashSet::new()), + raw_identifier_spans: RefCell::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), included_mod_stack: RefCell::new(vec![]), code_map, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4c1575cf58939..c2ee78e9e9d1b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i, _) => { + token::Ident(i, is_raw) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -793,6 +793,9 @@ impl<'a> Parser<'a> { return Err(err); } } + if is_raw { + self.sess.raw_identifier_spans.borrow_mut().push(self.span); + } self.bump(); Ok(i) } diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs index 2ef9fba2076ad..6cea75cf1d11e 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + use std::mem; #[r#repr(r#C, r#packed)] diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs index eefce3981bec1..5d495c4e9e557 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + fn r#fn(r#match: u32) -> u32 { r#match } diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs index 4306ffe2042af..256bd263d38d4 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + #[derive(Debug, PartialEq, Eq)] struct IntWrapper(u32); diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs index 9e89b79266cfa..4bd16ded52fbd 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(decl_macro)] +#![feature(raw_identifiers)] r#macro_rules! r#struct { ($r#struct:expr) => { $r#struct } diff --git a/src/test/ui/feature-gate-raw-identifiers.rs b/src/test/ui/feature-gate-raw-identifiers.rs new file mode 100644 index 0000000000000..38024feb432d9 --- /dev/null +++ b/src/test/ui/feature-gate-raw-identifiers.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change + println!("{}", foo); +} diff --git a/src/test/ui/feature-gate-raw-identifiers.stderr b/src/test/ui/feature-gate-raw-identifiers.stderr new file mode 100644 index 0000000000000..02eff7247c47b --- /dev/null +++ b/src/test/ui/feature-gate-raw-identifiers.stderr @@ -0,0 +1,11 @@ +error[E0658]: raw identifiers are experimental and subject to change (see issue #48589) + --> $DIR/feature-gate-raw-identifiers.rs:12:9 + | +LL | let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change + | ^^^^^ + | + = help: add #![feature(raw_identifiers)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/raw-literal-keywords.rs b/src/test/ui/raw-literal-keywords.rs index 8b3747dbe15e4..9b28aa0b15116 100644 --- a/src/test/ui/raw-literal-keywords.rs +++ b/src/test/ui/raw-literal-keywords.rs @@ -11,6 +11,7 @@ // compile-flags: -Z parse-only #![feature(dyn_trait)] +#![feature(raw_identifiers)] fn test_if() { r#if true { } //~ ERROR found `true` diff --git a/src/test/ui/raw-literal-keywords.stderr b/src/test/ui/raw-literal-keywords.stderr index 022f80ae8a4ec..3758568323cc0 100644 --- a/src/test/ui/raw-literal-keywords.stderr +++ b/src/test/ui/raw-literal-keywords.stderr @@ -1,17 +1,17 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true` - --> $DIR/raw-literal-keywords.rs:16:10 + --> $DIR/raw-literal-keywords.rs:17:10 | LL | r#if true { } //~ ERROR found `true` | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:20:14 + --> $DIR/raw-literal-keywords.rs:21:14 | LL | r#struct Test; //~ ERROR found `Test` | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:24:13 + --> $DIR/raw-literal-keywords.rs:25:13 | LL | r#union Test; //~ ERROR found `Test` | ^^^^ expected one of 8 possible tokens here diff --git a/src/test/ui/raw-literal-self.rs b/src/test/ui/raw-literal-self.rs index 17496d767b622..f88d6cf9a67bd 100644 --- a/src/test/ui/raw-literal-self.rs +++ b/src/test/ui/raw-literal-self.rs @@ -10,6 +10,8 @@ // compile-flags: -Z parse-only +#![feature(raw_identifiers)] + fn self_test(r#self: u32) { //~^ ERROR `r#self` is not currently supported. } diff --git a/src/test/ui/raw-literal-self.stderr b/src/test/ui/raw-literal-self.stderr index f4b759372471c..e3345847aa895 100644 --- a/src/test/ui/raw-literal-self.stderr +++ b/src/test/ui/raw-literal-self.stderr @@ -1,5 +1,5 @@ error: `r#self` is not currently supported. - --> $DIR/raw-literal-self.rs:13:14 + --> $DIR/raw-literal-self.rs:15:14 | LL | fn self_test(r#self: u32) { | ^^^^^^ From a23f685296b2edd59acc998411340184b958ec82 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 18 Mar 2018 16:58:38 +0100 Subject: [PATCH 108/546] num::NonZero* types now have their own tracking issue: #49137 Fixes #27730 --- src/libcore/nonzero.rs | 7 +------ src/libcore/num/mod.rs | 4 ++-- src/libstd/num.rs | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 59aaef9d66a00..19836d98844e2 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -9,9 +9,7 @@ // except according to those terms. //! Exposes the NonZero lang item which provides optimization hints. -#![unstable(feature = "nonzero", - reason = "deprecated", - issue = "27730")] +#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")] #![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead", since = "1.26.0")] #![allow(deprecated)] @@ -70,9 +68,6 @@ pub struct NonZero(pub(crate) T); impl NonZero { /// Creates an instance of NonZero with the provided value. /// You must indeed ensure that the value is actually "non-zero". - #[unstable(feature = "nonzero", - reason = "needs an RFC to flesh out the design", - issue = "27730")] #[inline] pub const unsafe fn new_unchecked(inner: T) -> Self { NonZero(inner) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 84f6ab9b76498..2ffcb9e95e2d9 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -92,7 +92,7 @@ macro_rules! nonzero_integers { } nonzero_integers! { - #[unstable(feature = "nonzero", issue = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU8(u8); NonZeroI8(i8); NonZeroU16(u16); NonZeroI16(i16); NonZeroU32(u32); NonZeroI32(i32); @@ -103,7 +103,7 @@ nonzero_integers! { nonzero_integers! { // Change this to `#[unstable(feature = "i128", issue = "35118")]` // if other NonZero* integer types are stabilizied before 128-bit integers - #[unstable(feature = "nonzero", issue = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU128(u128); NonZeroI128(i128); } diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 5e0406ca2202c..0c618370ac212 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,7 +21,7 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{ NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, @@ -29,7 +29,7 @@ pub use core::num::{ // Change this to `#[unstable(feature = "i128", issue = "35118")]` // if other NonZero* integer types are stabilizied before 128-bit integers -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{NonZeroU128, NonZeroI128}; #[cfg(test)] use fmt; From efa9016390c6980983c58271436813215595bd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 17 Mar 2018 22:17:33 +0100 Subject: [PATCH 109/546] Add a CI job for parallel rustc using x.py check --- config.toml.example | 3 +++ src/bootstrap/configure.py | 1 + src/ci/docker/x86_64-gnu-debug/Dockerfile | 1 + src/ci/run.sh | 7 +++++++ 4 files changed, 12 insertions(+) diff --git a/config.toml.example b/config.toml.example index b47f9163c0dac..86ddefefb43bc 100644 --- a/config.toml.example +++ b/config.toml.example @@ -268,6 +268,9 @@ # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) #backtrace = true +# Build rustc with experimental parallelization +#experimental-parallel-queries = false + # The default linker that will be hard-coded into the generated compiler for # targets that don't specify linker explicitly in their target specifications. # Note that this is not the linker used to link said compiler. diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 97da7cae07f7c..a5c373d5d5e77 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -44,6 +44,7 @@ def v(*args): o("docs", "build.docs", "build standard library documentation") o("compiler-docs", "build.compiler-docs", "build compiler documentation") o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") +o("experimental-parallel-queries", "rust.experimental-parallel-queries", "build rustc with experimental parallelization") o("test-miri", "rust.test-miri", "run miri's test suite") o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata") o("quiet-tests", "rust.quiet-tests", "enable quieter output when running tests") diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 95d41028595f8..ff6ab1013b4c2 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +ENV PARALLEL_CHECK 1 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-debug \ diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a92..7fc2a963640b1 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -72,6 +72,13 @@ fi # sccache server at the start of the build, but no need to worry if this fails. SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true +if [ "$PARALLEL_CHECK" != "" ]; then + $SRC/configure --enable-experimental-parallel-queries + python2.7 ../x.py check + rm -f config.toml + rm -rf build +fi + travis_fold start configure travis_time_start $SRC/configure $RUST_CONFIGURE_ARGS From d2e7953d1325b1a1fe1cef526dbe8d23fa3e00a1 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 11:21:38 -0500 Subject: [PATCH 110/546] Move raw_identifiers check to the lexer. --- src/libsyntax/parse/lexer/mod.rs | 4 ++++ src/libsyntax/parse/parser.rs | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 8e746ea69e79f..068929c8948df 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1155,6 +1155,10 @@ impl<'a> StringReader<'a> { &format!("`r#{}` is not currently supported.", ident.name) ).raise(); } + if is_raw_ident { + let span = self.mk_sp(raw_start, self.pos); + self.sess.raw_identifier_spans.borrow_mut().push(span); + } token::Ident(ident, is_raw_ident) })); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c2ee78e9e9d1b..4c1575cf58939 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i, is_raw) => { + token::Ident(i, _) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -793,9 +793,6 @@ impl<'a> Parser<'a> { return Err(err); } } - if is_raw { - self.sess.raw_identifier_spans.borrow_mut().push(self.span); - } self.bump(); Ok(i) } From e269a7435e80e0c4e02e3a5aa21233ef28892def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 18 Mar 2018 18:08:17 +0100 Subject: [PATCH 111/546] Allow test target to pass without installing explicitly pass -L target-lib to rustdoc --- src/test/run-make/tools.mk | 2 +- src/tools/compiletest/src/runtest.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk index d9103e1992735..af1707de6c02f 100644 --- a/src/test/run-make/tools.mk +++ b/src/test/run-make/tools.mk @@ -9,7 +9,7 @@ RUSTC_ORIGINAL := $(RUSTC) BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)' BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)' RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -RUSTDOC := $(BARE_RUSTDOC) +RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR) ifdef RUSTC_LINKER RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER) RUSTDOC := $(RUSTDOC) --linker $(RUSTC_LINKER) -Z unstable-options diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 953a13a3f5820..23bb39215d37a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1324,6 +1324,8 @@ impl<'test> TestCx<'test> { let mut rustdoc = Command::new(rustdoc_path); rustdoc + .arg("-L") + .arg(self.config.run_lib_path.to_str().unwrap()) .arg("-L") .arg(aux_dir) .arg("-o") From 5c3d6320deb20f78d83d12fb3a319b9dd6b15290 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 12:16:02 -0500 Subject: [PATCH 112/546] Return a is_raw parameter from Token::ident rather than having separate methods. --- src/libsyntax/ext/tt/macro_parser.rs | 4 +-- src/libsyntax/ext/tt/quoted.rs | 4 +-- src/libsyntax/parse/token.rs | 45 ++++++++++------------------ 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 714b7ca981da0..8cb331c65da28 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -364,8 +364,8 @@ pub fn parse_failure_msg(tok: Token) -> String { /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1: &Token, t2: &Token) -> bool { - if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { - id1.name == id2.name && t1.is_raw_ident() == t2.is_raw_ident() + if let (Some((id1, is_raw1)), Some((id2, is_raw2))) = (t1.ident(), t2.ident()) { + id1.name == id2.name && is_raw1 == is_raw2 } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { id1.name == id2.name } else { diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 11eb9b940aea5..f324edeb1178a 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -200,7 +200,7 @@ pub fn parse( let span = match trees.next() { Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() { Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() { - Some(kind) => { + Some((kind, _)) => { let span = end_sp.with_lo(start_sp.lo()); result.push(TokenTree::MetaVarDecl(span, ident, kind)); continue; @@ -289,7 +289,7 @@ where // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special // metavariable that names the crate of the invokation. Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => { - let ident = token.ident().unwrap(); + let (ident, _) = token.ident().unwrap(); let span = ident_span.with_lo(span.lo()); if ident.name == keywords::Crate.name() { let ident = ast::Ident { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 6406651bcba88..4e7a282adc584 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -310,32 +310,17 @@ impl Token { } } - fn ident_common(&self, allow_raw: bool) -> Option { + pub fn ident(&self) -> Option<(ast::Ident, bool)> { match *self { - Ident(ident, is_raw) if !is_raw || allow_raw => Some(ident), + Ident(ident, is_raw) => Some((ident, is_raw)), Interpolated(ref nt) => match nt.0 { - NtIdent(ident, is_raw) if !is_raw || allow_raw => Some(ident.node), + NtIdent(ident, is_raw) => Some((ident.node, is_raw)), _ => None, }, _ => None, } } - pub fn nonraw_ident(&self) -> Option { - self.ident_common(false) - } - - pub fn is_raw_ident(&self) -> bool { - match *self { - Ident(_, true) => true, - _ => false, - } - } - - pub fn ident(&self) -> Option { - self.ident_common(true) - } - /// Returns `true` if the token is an identifier. pub fn is_ident(&self) -> bool { self.ident().is_some() @@ -404,37 +389,37 @@ impl Token { /// Returns `true` if the token is a given keyword, `kw`. pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - self.nonraw_ident().map(|ident| ident.name == kw.name()).unwrap_or(false) + self.ident().map(|(ident, is_raw)| ident.name == kw.name() && !is_raw).unwrap_or(false) } pub fn is_path_segment_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_path_segment_keyword(id), - None => false, + match self.ident() { + Some((id, false)) => is_path_segment_keyword(id), + _ => false, } } // Returns true for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_special_ident(id), + match self.ident() { + Some((id, false)) => is_special_ident(id), _ => false, } } /// Returns `true` if the token is a keyword used in the language. pub fn is_used_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_used_keyword(id), + match self.ident() { + Some((id, false)) => is_used_keyword(id), _ => false, } } /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_unused_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_unused_keyword(id), + match self.ident() { + Some((id, false)) => is_unused_keyword(id), _ => false, } } @@ -507,8 +492,8 @@ impl Token { /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved_ident(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_reserved_ident(id), + match self.ident() { + Some((id, false)) => is_reserved_ident(id), _ => false, } } From 9a44448a252a94bf6b99388cab82aa9cd4595207 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sun, 18 Mar 2018 18:33:36 +0100 Subject: [PATCH 113/546] add simd_select intrinsic --- src/librustc_trans/intrinsic.rs | 21 +++ src/librustc_typeck/check/intrinsic.rs | 1 + .../simd-intrinsic-generic-select.rs | 56 +++++++ .../run-pass/simd-intrinsic-generic-select.rs | 144 ++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 src/test/compile-fail/simd-intrinsic-generic-select.rs create mode 100644 src/test/run-pass/simd-intrinsic-generic-select.rs diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index c3de9e0ffcce2..76c5bf56daa9f 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1153,6 +1153,27 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } + if name == "simd_select" { + let m_elem_ty = in_elem; + let m_len = in_len; + let v_len = arg_tys[1].simd_size(tcx); + require!(m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, v_len + ); + match m_elem_ty.sty { + ty::TyInt(_) => {}, + _ => { + return_error!("mask element type is `{}`, expected `i_`", m_elem_ty); + } + } + // truncate the mask to a vector of i1s + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, m_len as u64); + let m_i1s = bx.trunc(args[0].immediate(), i1xn); + return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); + } + macro_rules! arith_red { ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { if name == $name { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 99707a4a3c0e5..84c9339be0ad4 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -361,6 +361,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), + "simd_select" => (2, vec![param(0), param(1), param(1)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), "simd_reduce_add_ordered" | "simd_reduce_mul_ordered" => (2, vec![param(0), param(1)], param(1)), diff --git a/src/test/compile-fail/simd-intrinsic-generic-select.rs b/src/test/compile-fail/simd-intrinsic-generic-select.rs new file mode 100644 index 0000000000000..d74d6815d5f5e --- /dev/null +++ b/src/test/compile-fail/simd-intrinsic-generic-select.rs @@ -0,0 +1,56 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the simd_select intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x8(pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +fn main() { + let m4 = b8x4(0, 0, 0, 0); + let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0); + let x = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_select(m4, x, x); + + simd_select(m8, x, x); + //~^ ERROR mismatched lengths: mask length `8` != other vector length `4` + + simd_select(x, x, x); + //~^ ERROR mask element type is `u32`, expected `i_` + + simd_select(z, z, z); + //~^ ERROR mask element type is `f32`, expected `i_` + } +} diff --git a/src/test/run-pass/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd-intrinsic-generic-select.rs new file mode 100644 index 0000000000000..bf0a59309ca29 --- /dev/null +++ b/src/test/run-pass/simd-intrinsic-generic-select.rs @@ -0,0 +1,144 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the simd_select intrinsics produces correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +fn main() { + let m0 = b8x4(!0, !0, !0, !0); + let m1 = b8x4(0, 0, 0, 0); + let m2 = b8x4(!0, !0, 0, 0); + let m3 = b8x4(0, 0, !0, !0); + let m4 = b8x4(!0, 0, !0, 0); + + unsafe { + let a = i32x4(1, -2, 3, 4); + let b = i32x4(5, 6, -7, 8); + + let r: i32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m2, a, b); + let e = i32x4(1, -2, -7, 8); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m3, a, b); + let e = i32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m4, a, b); + let e = i32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = u32x4(1, 2, 3, 4); + let b = u32x4(5, 6, 7, 8); + + let r: u32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m2, a, b); + let e = u32x4(1, 2, 7, 8); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m3, a, b); + let e = u32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m4, a, b); + let e = u32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = f32x4(1., 2., 3., 4.); + let b = f32x4(5., 6., 7., 8.); + + let r: f32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m2, a, b); + let e = f32x4(1., 2., 7., 8.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m3, a, b); + let e = f32x4(5., 6., 3., 4.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m4, a, b); + let e = f32x4(1., 6., 3., 8.); + assert_eq!(r, e); + } + + unsafe { + let t = !0 as i8; + let f = 0 as i8; + let a = b8x4(t, f, t, f); + let b = b8x4(f, f, f, t); + + let r: b8x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m2, a, b); + let e = b8x4(t, f, f, t); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m3, a, b); + let e = b8x4(f, f, t, f); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m4, a, b); + let e = b8x4(t, f, t, t); + assert_eq!(r, e); + } +} From ce84a41936e367dfeb7d348564f2337819395ca6 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 13:27:56 -0500 Subject: [PATCH 114/546] Allow raw identifiers in diagnostic macros. --- src/libsyntax/diagnostics/plugin.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index c7e453c9e1054..aecf32ab6afb7 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -44,7 +44,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box { let code = match (token_tree.len(), token_tree.get(0)) { - (1, Some(&TokenTree::Token(_, token::Ident(code, false)))) => code, + (1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code, _ => unreachable!() }; @@ -82,10 +82,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, token_tree.get(1), token_tree.get(2) ) { - (1, Some(&TokenTree::Token(_, token::Ident(ref code, false))), None, None) => { + (1, Some(&TokenTree::Token(_, token::Ident(ref code, _))), None, None) => { (code, None) }, - (3, Some(&TokenTree::Token(_, token::Ident(ref code, false))), + (3, Some(&TokenTree::Token(_, token::Ident(ref code, _))), Some(&TokenTree::Token(_, token::Comma)), Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => { (code, Some(description)) @@ -150,9 +150,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. - &TokenTree::Token(_, token::Ident(ref crate_name, false)), + &TokenTree::Token(_, token::Ident(ref crate_name, _)), // DIAGNOSTICS ident. - &TokenTree::Token(_, token::Ident(ref name, false)) + &TokenTree::Token(_, token::Ident(ref name, _)) ) => (*&crate_name, name), _ => unreachable!() }; From cca2604e6cf4bf303085d6f38731353621aa39cf Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sun, 18 Mar 2018 19:55:20 +0100 Subject: [PATCH 115/546] add codegen test --- .../codegen/simd-intrinsic-generic-select.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/codegen/simd-intrinsic-generic-select.rs diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs new file mode 100644 index 0000000000000..8a64d7437d84d --- /dev/null +++ b/src/test/codegen/simd-intrinsic-generic-select.rs @@ -0,0 +1,35 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct b8x4(pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +// CHECK-LABEL: @select +#[no_mangle] +pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { + // CHECK: select <4 x i1> + simd_select(m, a, b) +} From 7786f70437f66fb0964ef2685833d2d9d8152b28 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Feb 2018 01:09:30 +0100 Subject: [PATCH 116/546] Add warning for invalid start of code blocks in rustdoc --- src/librustdoc/html/markdown.rs | 7 ++++++- src/librustdoc/markdown.rs | 2 +- src/librustdoc/test.rs | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5e55353a26e6b..5ce3d57f82f23 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -27,6 +27,7 @@ #![allow(non_camel_case_types)] +use rustc::session; use std::cell::RefCell; use std::collections::{HashMap, VecDeque}; use std::default::Default; @@ -434,7 +435,8 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { } } -pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) { +pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span, + sess: Option<&session::Session>) { tests.set_position(position); let mut parser = Parser::new(doc); @@ -484,6 +486,9 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp line, filename, block_info.allow_fail); prev_offset = offset; } else { + if let Some(ref sess) = sess { + sess.span_warn(position, "invalid start of a new code block"); + } break; } } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 0f107457d2bf8..3a55b279b5cc7 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -152,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, true, opts, maybe_sysroot, None, Some(PathBuf::from(input)), linker); - find_testable_code(&input_str, &mut collector, DUMMY_SP); + find_testable_code(&input_str, &mut collector, DUMMY_SP, None); test_args.insert(0, "rustdoctest".to_string()); testing::test_main(&test_args, collector.tests, testing::Options::new().display_output(display_warnings)); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 117b21d47587f..707d5a12bbf9f 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -645,8 +645,10 @@ impl<'a, 'hir> HirCollector<'a, 'hir> { // 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() { - markdown::find_testable_code(&doc, self.collector, - attrs.span.unwrap_or(DUMMY_SP)); + markdown::find_testable_code(&doc, + self.collector, + attrs.span.unwrap_or(DUMMY_SP), + Some(self.sess)); } nested(self); From eca1e18cd7021f01757640c0c5ef63717870686c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 00:11:47 +0000 Subject: [PATCH 117/546] Add stability test for sort_by_cached_key --- src/liballoc/tests/slice.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 7d4dac1c5ec99..66c7dd75c8740 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -485,7 +485,7 @@ fn test_sort_stability() { // the second item represents which occurrence of that // number this element is, i.e. the second elements // will occur in sorted order. - let mut v: Vec<_> = (0..len) + let mut orig: Vec<_> = (0..len) .map(|_| { let n = thread_rng().gen::() % 10; counts[n] += 1; @@ -493,16 +493,21 @@ fn test_sort_stability() { }) .collect(); - // only sort on the first element, so an unstable sort + let mut v = orig.clone(); + // Only sort on the first element, so an unstable sort // may mix up the counts. v.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); - // this comparison includes the count (the second item + // This comparison includes the count (the second item // of the tuple), so elements with equal first items // will need to be ordered with increasing // counts... i.e. exactly asserting that this sort is // stable. assert!(v.windows(2).all(|w| w[0] <= w[1])); + + let mut v = orig.clone(); + v.sort_by_cached_key(|&(x, _)| x); + assert!(v.windows(2).all(|w| w[0] <= w[1])); } } } From ca476dd8d3f0fa51f715d0de16800392cff82dd3 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 01:34:32 +0000 Subject: [PATCH 118/546] Revert "Remove useless powerpc64 entry from ARCH_TABLE, closes #47737" This reverts commit 16ac85ce4dce1e185f2e6ce27df3833e07a9e502. --- src/test/codegen/abi-main-signature-16bit-c-int.rs | 1 + src/test/codegen/fastcall-inreg.rs | 2 ++ src/test/codegen/global_asm.rs | 2 ++ src/test/codegen/global_asm_include.rs | 2 ++ src/test/codegen/global_asm_x2.rs | 2 ++ src/test/codegen/repr-transparent-aggregates-1.rs | 1 + src/tools/compiletest/src/util.rs | 1 + 7 files changed, 11 insertions(+) diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs index 707531bf376a7..367d509cadfe3 100644 --- a/src/test/codegen/abi-main-signature-16bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs @@ -19,6 +19,7 @@ // ignore-mips // ignore-mips64 // ignore-powerpc +// ignore-powerpc64 // ignore-s390x // ignore-sparc // ignore-wasm32 diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs index 9bfe47d0a1f28..d6dd3f356b5fe 100644 --- a/src/test/codegen/fastcall-inreg.rs +++ b/src/test/codegen/fastcall-inreg.rs @@ -23,6 +23,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs index 94b69a6cab583..6b79e79fa0080 100644 --- a/src/test/codegen/global_asm.rs +++ b/src/test/codegen/global_asm.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs index c3688077f221b..3f73a1cabbf19 100644 --- a/src/test/codegen/global_asm_include.rs +++ b/src/test/codegen/global_asm_include.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs index 3b8fe43fa048a..3e118a50d454e 100644 --- a/src/test/codegen/global_asm_x2.rs +++ b/src/test/codegen/global_asm_x2.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 655e67cf7eefe..2eeed2b788ce2 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -14,6 +14,7 @@ // ignore-mips // ignore-mips64 // ignore-powerpc +// ignore-powerpc64 // See repr-transparent.rs #![crate_type="lib"] diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 0e3fa25b13ce9..8c889cc48070d 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -44,6 +44,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), + ("powerpc64", "powerpc64"), ("s390x", "s390x"), ("sparc", "sparc"), ("x86_64", "x86_64"), From a185b56b7caca17c7aa9d6f702fe1b2209c82e4e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 18 Mar 2018 23:02:06 +0900 Subject: [PATCH 119/546] Address review comments --- src/librustc_driver/lib.rs | 8 +++++--- src/libstd/rt.rs | 15 +++++++++++++++ src/libstd/sys/unix/thread.rs | 20 +++++++++++++++++++- src/libstd/thread/mod.rs | 8 -------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 761797239412e..e39a2c2f5dcd9 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1476,13 +1476,15 @@ pub fn in_rustc_thread(f: F) -> Result> } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { true } else { + std::rt::deinit_stack_guard(); rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - error!("in_rustc_thread: error calling setrlimit: {}", err); - true + // We have already deinited the stack. Further corruption is + // not allowed. + panic!("in_rustc_thread: error calling setrlimit: {}", err); } else { - std::thread::update_stack_guard(); + std::rt::update_stack_guard(); false } } diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index e1392762a59dc..8f945470b7e94 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -73,3 +73,18 @@ fn lang_start { lang_start_internal(&move || main().report(), argc, argv) } + +/// Function used for reverting changes to the main stack before setrlimit(). +/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn deinit_stack_guard() { + ::sys::thread::guard::deinit(); +} + +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = ::sys::thread::guard::init(); + ::sys_common::thread_info::reset_guard(main_guard); +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 72cdb9440b8e7..d94e11a5207cb 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -222,7 +222,7 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::mmap; + use libc::{mmap, munmap}; use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -336,6 +336,24 @@ pub mod guard { } } + pub unsafe fn deinit() { + if !cfg!(target_os = "linux") { + if let Some(mut stackaddr) = get_stack_start() { + // Ensure address is aligned. Same as above. + let remainder = (stackaddr as usize) % PAGE_SIZE; + if remainder != 0 { + stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) + as *mut libc::c_void; + } + + // Undo the guard page mapping. + if munmap(stackaddr, PAGE_SIZE) != 0 { + panic!("unable to deallocate the guard page"); + } + } + } + } + #[cfg(any(target_os = "macos", target_os = "bitrig", target_os = "openbsd", diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index b686ddc205ea7..71aee673cfe3e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,14 +208,6 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; -/// Function used for resetting the main stack guard address after setrlimit(). -/// This is POSIX specific and unlikely to be directly stabilized. -#[unstable(feature = "rustc_stack_internals", issue = "0")] -pub unsafe fn update_stack_guard() { - let main_guard = imp::guard::init(); - thread_info::reset_guard(main_guard); -} - //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From 1578b1edc0a1ac9dfa289d369d88bcd0a7db22e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 16 Mar 2018 20:11:48 +0100 Subject: [PATCH 120/546] Update submodules in parallel --- src/ci/init_repo.sh | 72 ++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index 8ab4276fa3b05..f2664e6d196c7 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -17,6 +17,7 @@ ci_dir=$(cd $(dirname $0) && pwd) . "$ci_dir/shared.sh" travis_fold start init_repo +travis_time_start REPO_DIR="$1" CACHE_DIR="$2" @@ -42,54 +43,39 @@ if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then git fetch origin --unshallow beta master fi -travis_fold start update_cache -travis_time_start - -# Update the cache (a pristine copy of the rust source master) -retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \ - git clone --depth 1 https://github.com/rust-lang/rust.git $cache_src_dir" -if [ -d $cache_src_dir/src/llvm ]; then - (cd $cache_src_dir && git rm src/llvm) -fi -if [ -d $cache_src_dir/src/llvm-emscripten ]; then - (cd $cache_src_dir && git rm src/llvm-emscripten) -fi -retry sh -c "cd $cache_src_dir && \ - git submodule deinit -f . && git submodule sync && git submodule update --init" - -travis_fold end update_cache -travis_time_finish +function fetch_submodule { + local module=$1 + local cached="download-${module//\//-}.tar.gz" + retry sh -c "rm -f $cached && \ + curl -sSL -o $cached $2" + mkdir $module + touch "$module/.git" + tar -C $module --strip-components=1 -xf $cached + rm $cached +} -travis_fold start update_submodules -travis_time_start - -# Update the submodules of the repo we're in, using the pristine repo as -# a cache for any object files -# No, `git submodule foreach` won't work: -# http://stackoverflow.com/questions/12641469/list-submodules-in-a-git-repository +included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example" modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)" -for module in $modules; do - if [ "$module" = src/llvm ] || [ "$module" = src/llvm-emscripten ]; then +modules=($modules) +use_git="" +urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)" +urls=($urls) +for i in ${!modules[@]}; do + module=${modules[$i]} + if [[ " $included " = *" $module "* ]]; then commit="$(git ls-tree HEAD $module | awk '{print $3}')" git rm $module - retry sh -c "rm -f $commit.tar.gz && \ - curl -sSL -O https://github.com/rust-lang/llvm/archive/$commit.tar.gz" - tar -C src/ -xf "$commit.tar.gz" - rm "$commit.tar.gz" - mv "src/llvm-$commit" $module - continue - fi - if [ ! -e "$cache_src_dir/$module/.git" ]; then - echo "WARNING: $module not found in pristine repo" - retry sh -c "git submodule deinit -f $module && \ - git submodule update --init --recursive $module" + url=${urls[$i]} + url=${url/\.git/} + fetch_submodule $module "$url/archive/$commit.tar.gz" & continue + else + use_git="$use_git $module" fi - retry sh -c "git submodule deinit -f $module && \ - git submodule update --init --recursive --reference $cache_src_dir/$module $module" done - -travis_fold end update_submodules -travis_time_finish - +retry sh -c "git submodule deinit -f $use_git && \ + git submodule sync && \ + git submodule update -j 16 --init --recursive $use_git" +wait travis_fold end init_repo +travis_time_finish From c5c650d670f5f191ea9667b455c15a607e550fdb Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 00:26:41 -0500 Subject: [PATCH 121/546] Split out termination_trait_test feature gate --- src/libsyntax/feature_gate.rs | 3 +++ src/libsyntax/test.rs | 8 +++---- .../feature-gate-termination_trait_test.rs | 22 +++++++++++++++++++ .../termination-trait-in-test.rs | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/feature-gate-termination_trait_test.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd686064..0950965233f6a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -432,6 +432,9 @@ declare_features! ( // Termination trait in main (RFC 1937) (active, termination_trait, "1.24.0", Some(43301), None), + // Termination trait in tests (RFC 1937) + (active, termination_trait_test, "1.24.0", Some(48854), None), + // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9edfa767d3195..d107ab59a9ad9 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -332,7 +332,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -359,7 +359,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { match has_test_signature(cx, i) { Yes => true, No => { - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as tests can not have any arguments"); } else { diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"); @@ -388,7 +388,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -416,7 +416,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { if has_bench_attr && !has_bench_signature { let diag = cx.span_diagnostic; - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> impl Termination`"); } else { diff --git a/src/test/compile-fail/feature-gate-termination_trait_test.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs new file mode 100644 index 0000000000000..4af7e94671627 --- /dev/null +++ b/src/test/compile-fail/feature-gate-termination_trait_test.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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --test + +fn main() {} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() -> Result<(), ()> { + //~^ ERROR functions used as tests must have signature fn() -> () + Ok(()) + } +} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs index 494500d522abe..11997eb691728 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -10,7 +10,7 @@ // compile-flags: --test -#![feature(termination_trait)] +#![feature(termination_trait_test)] #![feature(test)] extern crate test; From 685c3c1b4a7c1949048177409ca43fc05daefd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:01:11 -0700 Subject: [PATCH 122/546] Reduce the diagnostic span when multiple fields are missing in pattern --- src/librustc_typeck/check/_match.rs | 70 +++++++++++-------- .../ui/missing-fields-in-struct-pattern.rs | 17 +++++ 2 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.rs diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 379fd93ba2bd6..0b5383f1f8d1e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -904,6 +904,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap(); + let mut inexistent_fields = vec![]; // Typecheck each field. for &Spanned { node: ref field, span } in fields { let field_ty = match used_fields.entry(field.name) { @@ -927,34 +928,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.field_ty(span, f, substs) }) .unwrap_or_else(|| { - let mut err = struct_span_err!( - tcx.sess, - span, - E0026, - "{} `{}` does not have a field named `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name - ); - err.span_label(span, - format!("{} `{}` does not have field `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name)); - if tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "This error indicates that a struct pattern attempted to \ - extract a non-existent field from a struct. Struct fields \ - are identified by the name used before the colon : so struct \ - patterns should resemble the declaration of the struct type \ - being matched.\n\n\ - If you are using shorthand field patterns but want to refer \ - to the struct field by a different name, you should rename \ - it explicitly." - ); - } - err.emit(); - + inexistent_fields.push((span, field.name)); tcx.types.err }) } @@ -963,6 +937,46 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.check_pat_walk(&field.pat, field_ty, def_bm, true); } + if inexistent_fields.len() > 0 { + let field_names = if inexistent_fields.len() == 1 { + format!("a field named `{}`", inexistent_fields[0].1) + } else { + format!("fields named {}", + inexistent_fields.iter() + .map(|(_, name)| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; + let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); + let mut err = struct_span_err!(tcx.sess, + spans, + E0026, + "{} `{}` does not have {}", + kind_name, + tcx.item_path_str(variant.did), + field_names); + for (span, name) in &inexistent_fields { + err.span_label(*span, + format!("{} `{}` does not have field `{}`", + kind_name, + tcx.item_path_str(variant.did), + name)); + } + if tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "This error indicates that a struct pattern attempted to \ + extract a non-existent field from a struct. Struct fields \ + are identified by the name used before the colon : so struct \ + patterns should resemble the declaration of the struct type \ + being matched.\n\n\ + If you are using shorthand field patterns but want to refer \ + to the struct field by a different name, you should rename \ + it explicitly." + ); + } + err.emit(); + } + // Require `..` if struct has non_exhaustive attribute. if adt.is_struct() && adt.is_non_exhaustive() && !adt.did.is_local() && !etc { span_err!(tcx.sess, span, E0638, diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs new file mode 100644 index 0000000000000..2469f24534543 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S(usize, usize, usize, usize); + +fn main() { + if let S { a, b, c, d } = S(1, 2, 3, 4) { + println!("hi"); + } +} From 97b3bf99f667736c3220a91b72a587eafe4cda49 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:31:04 -0500 Subject: [PATCH 123/546] Stabilize termination_trait This stabilizes `main` with non-() return types; see #48453. --- src/librustc_typeck/check/mod.rs | 35 +++++++++---------- src/librustc_typeck/lib.rs | 3 +- src/libstd/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 5 ++- .../termination-trait-main-i32.rs} | 3 +- .../termination-trait-main-wrong-type.rs | 1 - .../termination-trait-not-satisfied.rs | 2 -- .../termination-trait-for-never.rs | 2 -- ...mination-trait-for-result-box-error_err.rs | 2 -- .../termination-trait-for-empty.rs | 2 -- .../termination-trait-for-exitcode.rs | 1 - ...rmination-trait-for-result-box-error_ok.rs | 2 -- .../termination-trait-for-result.rs | 2 -- 13 files changed, 22 insertions(+), 40 deletions(-) rename src/test/compile-fail/{feature-gate-termination_trait.rs => rfc-1937-termination-trait/termination-trait-main-i32.rs} (82%) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4a685cfddb7a4..42bf516a0afa5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1106,25 +1106,22 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } fcx.demand_suptype(span, ret_ty, actual_return_ty); - if fcx.tcx.features().termination_trait { - // If the termination trait language item is activated, check that the main return type - // implements the termination trait. - if let Some(term_id) = fcx.tcx.lang_items().termination() { - if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { - if id == fn_id { - match fcx.sess().entry_type.get() { - Some(config::EntryMain) => { - let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); - let trait_ref = ty::TraitRef::new(term_id, substs); - let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); - - inherited.register_predicate( - traits::Obligation::new( - cause, param_env, trait_ref.to_predicate())); - }, - _ => {}, - } + // Check that the main return type implements the termination trait. + if let Some(term_id) = fcx.tcx.lang_items().termination() { + if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { + if id == fn_id { + match fcx.sess().entry_type.get() { + Some(config::EntryMain) => { + let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); + let trait_ref = ty::TraitRef::new(term_id, substs); + let cause = traits::ObligationCause::new( + span, fn_id, ObligationCauseCode::MainFunctionType); + + inherited.register_predicate( + traits::Obligation::new( + cause, param_env, trait_ref.to_predicate())); + }, + _ => {}, } } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 964c0021133aa..8089014044211 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -208,8 +208,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let actual = tcx.fn_sig(main_def_id); - let expected_return_type = if tcx.lang_items().termination().is_some() - && tcx.features().termination_trait { + let expected_return_type = if tcx.lang_items().termination().is_some() { // we take the return type of the given main function, the real check is done // in `check_fn` actual.output().skip_binder() diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a159..33da0e5788653 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -308,7 +308,6 @@ #![feature(str_char)] #![feature(str_internals)] #![feature(str_utf16)] -#![feature(termination_trait)] #![feature(test, rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] @@ -325,6 +324,7 @@ #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(used))] #![cfg_attr(stage0, feature(never_type))] +#![cfg_attr(stage0, feature(termination_trait))] #![default_lib_allocator] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0950965233f6a..781071b7f7f07 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -429,9 +429,6 @@ declare_features! ( // `foo.rs` as an alternative to `foo/mod.rs` (active, non_modrs_mods, "1.24.0", Some(44660), None), - // Termination trait in main (RFC 1937) - (active, termination_trait, "1.24.0", Some(43301), None), - // Termination trait in tests (RFC 1937) (active, termination_trait_test, "1.24.0", Some(48854), None), @@ -558,6 +555,8 @@ declare_features! ( (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/feature-gate-termination_trait.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs similarity index 82% rename from src/test/compile-fail/feature-gate-termination_trait.rs rename to src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 5a56445b64e57..ff2b32f3fd93b 100644 --- a/src/test/compile-fail/feature-gate-termination_trait.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() -> i32 { //~ ERROR main function has wrong type [E0580] +fn main() -> i32 { +//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 93e2561adf753..ea39ba92f4143 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] fn main() -> char { //~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index e87e0ceebf1b1..bab02fc559706 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - struct ReturnType {} fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs index c1dd44a91765e..863de85af88fb 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - // error-pattern:oh, dear fn main() -> ! { diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs index 8ce27c0a06250..0c6cb4de9567d 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs @@ -11,8 +11,6 @@ // must-compile-successfully // failure-status: 1 -#![feature(termination_trait)] - use std::io::{Error, ErrorKind}; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs index 5e534da012875..046d27a9f0fe5 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - fn main() {} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs index 80fa4d17b6116..4aa7d8c3a77d2 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] #![feature(process_exitcode_placeholder)] use std::process::ExitCode; diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs index 269ac451cf4d8..33686ed0b8fa2 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs index 751db0fb50082..1c87e31e763e9 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Error> { From e5a55e74405dedf8bc0744300a8c506eea94bc18 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:59:51 -0500 Subject: [PATCH 124/546] Stabilize termination_trait in 1.25, not 1.26 --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 781071b7f7f07..e71726bcebdc9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From e2cf17278d1eabe30100095191f0b3c19e1f4f2a Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Mon, 19 Mar 2018 12:38:04 +0000 Subject: [PATCH 125/546] Update RELEASES.md --- RELEASES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index e6f6e0440839d..51c36c99858b8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -33,7 +33,6 @@ Libraries - [`UnsafeCell::into_inner` is now safe.][47204] - [Implement libstd for CloudABI.][47268] - [`Float::{from_bits, to_bits}` is now available in libcore.][46931] - - [Implement `AsRef` for Component][46985] - [Implemented `Write` for `Cursor<&mut Vec>`][46830] - [Moved `Duration` to libcore.][46666] @@ -59,7 +58,6 @@ Cargo Misc ---- - - [Rust by example is now shipped with new releases][46196] Compatibility Notes From 8236e431ce67f0cd32e0584a826586648842eaa3 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 19 Mar 2018 22:09:47 +0900 Subject: [PATCH 126/546] Document only-X test header --- src/test/COMPILER_TESTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index c255294e790b7..8553665c01797 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -54,6 +54,8 @@ be compiled or run. * `ignore-test` always ignores the test * `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger. +`only-X` is the opposite. The test will run only when `X` matches. + Some examples of `X` in `ignore-X`: * Architecture: `aarch64`, `arm`, `asmjs`, `mips`, `wasm32`, `x86_64`, `x86`, ... From deae8de673af638537421804b360443af76d55e4 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 19 Mar 2018 14:33:39 +0100 Subject: [PATCH 127/546] Clarify AcqRel's docs This implied things that are not true. Fixes #49127 --- src/libcore/sync/atomic.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 25827edee7d93..fd6e5140a0997 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -205,8 +205,9 @@ pub enum Ordering { /// [`Release`]: http://llvm.org/docs/Atomics.html#release #[stable(feature = "rust1", since = "1.0.0")] Acquire, - /// When coupled with a load, uses [`Acquire`] ordering, and with a store - /// [`Release`] ordering. + /// Has the effects of both [`Acquire`] and [`Release`] together. + /// + /// If you only are concerned about a load or a store, consider using one of those instead. /// /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release From 37ff4736c790f87ab957235c65e93ff8351daa80 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 Mar 2018 18:01:14 +0100 Subject: [PATCH 128/546] wording nits --- src/librustc_lint/builtin.rs | 8 ++++---- src/test/ui/type-alias-bounds.stderr | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2ea13b2cb6d68..f6acc085861e6 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1356,9 +1356,9 @@ impl TypeAliasBounds { fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) { // Access to associates types should use `::Assoc`, which does not need a - // bound. Let's see of this type does that. + // bound. Let's see if this type does that. - // We use an AST visitor to walk the type. + // We use a HIR visitor to walk the type. use rustc::hir::intravisit::{self, Visitor}; use syntax::ast::NodeId; struct WalkAssocTypes<'a, 'db> where 'db: 'a { @@ -1373,8 +1373,8 @@ impl TypeAliasBounds { fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) { if TypeAliasBounds::is_type_variable_assoc(qpath) { self.err.span_help(span, - "use absolute paths (i.e., ::Assoc) to refer to associated \ - types in type aliases"); + "use fully disambiguated paths (i.e., `::Assoc`) to refer to \ + associated types in type aliases"); } intravisit::walk_qpath(self, qpath, id, span) } diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 5288dca79be68..2a2b0b0f26e34 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -46,7 +46,7 @@ LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^ | = help: the bound will not be checked when the type alias is used, and should be removed -help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases +help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases --> $DIR/type-alias-bounds.rs:57:21 | LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases @@ -59,7 +59,7 @@ LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliase | ^^^^^^^^ | = help: the clause will not be checked when the type alias is used, and should be removed -help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases +help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases --> $DIR/type-alias-bounds.rs:58:29 | LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases From c05d23406ead7b5747256c02127097807db45b83 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 Mar 2018 18:08:12 +0100 Subject: [PATCH 129/546] update compile-fail tests: fewer warnings because this is now a HIR lint --- src/test/compile-fail/issue-17994.rs | 1 - src/test/compile-fail/private-in-public-warn.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs index 7c3811e2ef28b..25141b9b82557 100644 --- a/src/test/compile-fail/issue-17994.rs +++ b/src/test/compile-fail/issue-17994.rs @@ -10,5 +10,4 @@ trait Tr {} type Huh where T: Tr = isize; //~ ERROR type parameter `T` is unused - //~| WARNING where clauses are not enforced in type aliases fn main() {} diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 8bd9b0a901d65..6eeb14638e759 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,6 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING bounds on generic parameters are not enforced in type aliases //~| WARNING hard error pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error @@ -85,7 +84,6 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error - //~| WARNING where clauses are not enforced in type aliases pub trait Tr2 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error From 2b64799365a43bf8685cb9750d9e887c006c1f22 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Mar 2018 19:41:22 +0100 Subject: [PATCH 130/546] Make Atomic doc examples specific to each type --- src/libcore/sync/atomic.rs | 765 +++++++++++++++++++------------------ 1 file changed, 401 insertions(+), 364 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 25827edee7d93..fe5ed5d494224 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -948,6 +948,7 @@ macro_rules! atomic_int { $stable_from:meta, $stable_nand:meta, $s_int_type:expr, $int_ref:expr, + $extra_feature:expr, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. /// @@ -959,12 +960,7 @@ macro_rules! atomic_int { /// ). For more about the differences between atomic types and /// non-atomic types, please see the [module-level documentation]. /// - /// Please note that examples are shared between atomic variants of - /// primitive integer types, so it's normal that they are all - /// demonstrating [`AtomicIsize`]. - /// /// [module-level documentation]: index.html - /// [`AtomicIsize`]: struct.AtomicIsize.html #[$stable] pub struct $atomic_type { v: UnsafeCell<$int_type>, @@ -1001,395 +997,426 @@ macro_rules! atomic_int { unsafe impl Sync for $atomic_type {} impl $atomic_type { - /// Creates a new atomic integer. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::AtomicIsize; - /// - /// let atomic_forty_two = AtomicIsize::new(42); - /// ``` - #[inline] - #[$stable] - pub const fn new(v: $int_type) -> Self { - $atomic_type {v: UnsafeCell::new(v)} + doc_comment! { + concat!("Creates a new atomic integer. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), "; + +let atomic_forty_two = ", stringify!($atomic_type), "::new(42); +```"), + #[inline] + #[$stable] + pub const fn new(v: $int_type) -> Self { + $atomic_type {v: UnsafeCell::new(v)} + } } - /// Returns a mutable reference to the underlying integer. - /// - /// This is safe because the mutable reference guarantees that no other threads are - /// concurrently accessing the atomic data. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let mut some_isize = AtomicIsize::new(10); - /// assert_eq!(*some_isize.get_mut(), 10); - /// *some_isize.get_mut() = 5; - /// assert_eq!(some_isize.load(Ordering::SeqCst), 5); - /// ``` - #[inline] - #[$stable_access] - pub fn get_mut(&mut self) -> &mut $int_type { - unsafe { &mut *self.v.get() } + doc_comment! { + concat!("Returns a mutable reference to the underlying integer. + +This is safe because the mutable reference guarantees that no other threads are +concurrently accessing the atomic data. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let mut some_var = ", stringify!($atomic_type), "::new(10); +assert_eq!(*some_var.get_mut(), 10); +*some_var.get_mut() = 5; +assert_eq!(some_var.load(Ordering::SeqCst), 5); +```"), + #[inline] + #[$stable_access] + pub fn get_mut(&mut self) -> &mut $int_type { + unsafe { &mut *self.v.get() } + } } - /// Consumes the atomic and returns the contained value. - /// - /// This is safe because passing `self` by value guarantees that no other threads are - /// concurrently accessing the atomic data. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::AtomicIsize; - /// - /// let some_isize = AtomicIsize::new(5); - /// assert_eq!(some_isize.into_inner(), 5); - /// ``` - #[inline] - #[$stable_access] - pub fn into_inner(self) -> $int_type { - self.v.into_inner() + doc_comment! { + concat!("Consumes the atomic and returns the contained value. + +This is safe because passing `self` by value guarantees that no other threads are +concurrently accessing the atomic data. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), "; + +let some_var = ", stringify!($atomic_type), "::new(5); +assert_eq!(some_var.into_inner(), 5); +```"), + #[inline] + #[$stable_access] + pub fn into_inner(self) -> $int_type { + self.v.into_inner() + } } - /// Loads a value from the atomic integer. - /// - /// `load` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// # Panics - /// - /// Panics if `order` is [`Release`] or [`AcqRel`]. - /// - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.load(Ordering::Relaxed), 5); - /// ``` - #[inline] - #[$stable] - pub fn load(&self, order: Ordering) -> $int_type { - unsafe { atomic_load(self.v.get(), order) } + doc_comment! { + concat!("Loads a value from the atomic integer. + +`load` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +# Panics + +Panics if `order` is [`Release`] or [`AcqRel`]. + +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.load(Ordering::Relaxed), 5); +```"), + #[inline] + #[$stable] + pub fn load(&self, order: Ordering) -> $int_type { + unsafe { atomic_load(self.v.get(), order) } + } } - /// Stores a value into the atomic integer. - /// - /// `store` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// some_isize.store(10, Ordering::Relaxed); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - /// - /// # Panics - /// - /// Panics if `order` is [`Acquire`] or [`AcqRel`]. - /// - /// [`Acquire`]: enum.Ordering.html#variant.Acquire - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - #[inline] - #[$stable] - pub fn store(&self, val: $int_type, order: Ordering) { - unsafe { atomic_store(self.v.get(), val, order); } + doc_comment! { + concat!("Stores a value into the atomic integer. + +`store` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +some_var.store(10, Ordering::Relaxed); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +``` + +# Panics + +Panics if `order` is [`Acquire`] or [`AcqRel`]. + +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`AcqRel`]: enum.Ordering.html#variant.AcqRel"), + #[inline] + #[$stable] + pub fn store(&self, val: $int_type, order: Ordering) { + unsafe { atomic_store(self.v.get(), val, order); } + } } - /// Stores a value into the atomic integer, returning the previous value. - /// - /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5); - /// ``` - #[inline] - #[$stable] - pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_swap(self.v.get(), val, order) } + doc_comment! { + concat!("Stores a value into the atomic integer, returning the previous value. + +`swap` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); +```"), + #[inline] + #[$stable] + pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_swap(self.v.get(), val, order) } + } } - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// The return value is always the previous value. If it is equal to `current`, then the - /// value was updated. - /// - /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory - /// ordering of this operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// - /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - #[inline] - #[$stable] - pub fn compare_and_swap(&self, - current: $int_type, - new: $int_type, - order: Ordering) -> $int_type { - match self.compare_exchange(current, - new, - order, - strongest_failure_ordering(order)) { - Ok(x) => x, - Err(x) => x, + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +The return value is always the previous value. If it is equal to `current`, then the +value was updated. + +`compare_and_swap` also takes an [`Ordering`] argument which describes the memory +ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5); +assert_eq!(some_var.load(Ordering::Relaxed), 10); + +assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[inline] + #[$stable] + pub fn compare_and_swap(&self, + current: $int_type, + new: $int_type, + order: Ordering) -> $int_type { + match self.compare_exchange(current, + new, + order, + strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } } } - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// The return value is a result indicating whether the new value was written and - /// containing the previous value. On success this value is guaranteed to be equal to - /// `current`. - /// - /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if - /// the operation succeeds while the second describes the required ordering when - /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and - /// must be equivalent or weaker than the success ordering. - /// - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.compare_exchange(5, 10, - /// Ordering::Acquire, - /// Ordering::Relaxed), - /// Ok(5)); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// - /// assert_eq!(some_isize.compare_exchange(6, 12, - /// Ordering::SeqCst, - /// Ordering::Acquire), - /// Err(10)); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - #[inline] - #[$stable_cxchg] - pub fn compare_exchange(&self, - current: $int_type, - new: $int_type, - success: Ordering, - failure: Ordering) -> Result<$int_type, $int_type> { - unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +The return value is a result indicating whether the new value was written and +containing the previous value. On success this value is guaranteed to be equal to +`current`. + +`compare_exchange` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. The first describes the required ordering if +the operation succeeds while the second describes the required ordering when +the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and +must be equivalent or weaker than the success ordering. + +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.compare_exchange(5, 10, + Ordering::Acquire, + Ordering::Relaxed), + Ok(5)); +assert_eq!(some_var.load(Ordering::Relaxed), 10); + +assert_eq!(some_var.compare_exchange(6, 12, + Ordering::SeqCst, + Ordering::Acquire), + Err(10)); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[inline] + #[$stable_cxchg] + pub fn compare_exchange(&self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering) -> Result<$int_type, $int_type> { + unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + } } - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even - /// when the comparison succeeds, which can result in more efficient code on some - /// platforms. The return value is a result indicating whether the new value was - /// written and containing the previous value. - /// - /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if the - /// operation succeeds while the second describes the required ordering when the - /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and - /// must be equivalent or weaker than the success ordering. - /// - /// [`compare_exchange`]: #method.compare_exchange - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let val = AtomicIsize::new(4); - /// - /// let mut old = val.load(Ordering::Relaxed); - /// loop { - /// let new = old * 2; - /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { - /// Ok(_) => break, - /// Err(x) => old = x, - /// } - /// } - /// ``` - #[inline] - #[$stable_cxchg] - pub fn compare_exchange_weak(&self, - current: $int_type, - new: $int_type, - success: Ordering, - failure: Ordering) -> Result<$int_type, $int_type> { - unsafe { - atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +Unlike [`compare_exchange`], this function is allowed to spuriously fail even +when the comparison succeeds, which can result in more efficient code on some +platforms. The return value is a result indicating whether the new value was +written and containing the previous value. + +`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. The first describes the required ordering if the +operation succeeds while the second describes the required ordering when the +operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and +must be equivalent or weaker than the success ordering. + +[`compare_exchange`]: #method.compare_exchange +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let val = ", stringify!($atomic_type), "::new(4); + +let mut old = val.load(Ordering::Relaxed); +loop { + let new = old * 2; + match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + Ok(_) => break, + Err(x) => old = x, + } +} +```"), + #[inline] + #[$stable_cxchg] + pub fn compare_exchange_weak(&self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering) -> Result<$int_type, $int_type> { + unsafe { + atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) + } } } - /// Adds to the current value, returning the previous value. - /// - /// This operation wraps around on overflow. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0); - /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); - /// assert_eq!(foo.load(Ordering::SeqCst), 10); - /// ``` - #[inline] - #[$stable] - pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_add(self.v.get(), val, order) } + doc_comment! { + concat!("Adds to the current value, returning the previous value. + +This operation wraps around on overflow. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[$stable] + pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_add(self.v.get(), val, order) } + } } - /// Subtracts from the current value, returning the previous value. - /// - /// This operation wraps around on overflow. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0); - /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0); - /// assert_eq!(foo.load(Ordering::SeqCst), -10); - /// ``` - #[inline] - #[$stable] - pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_sub(self.v.get(), val, order) } + doc_comment! { + concat!("Subtracts from the current value, returning the previous value. + +This operation wraps around on overflow. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(20); +assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[$stable] + pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_sub(self.v.get(), val, order) } + } } - /// Bitwise "and" with the current value. - /// - /// Performs a bitwise "and" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001); - #[inline] - #[$stable] - pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_and(self.v.get(), val, order) } + doc_comment! { + concat!("Bitwise \"and\" with the current value. + +Performs a bitwise \"and\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b100001); +```"), + #[inline] + #[$stable] + pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_and(self.v.get(), val, order) } + } } - /// Bitwise "nand" with the current value. - /// - /// Performs a bitwise "nand" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// #![feature(atomic_nand)] - /// - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0xf731); - /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731); - /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f)); - #[inline] - #[$stable_nand] - pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_nand(self.v.get(), val, order) } + doc_comment! { + concat!("Bitwise \"nand\" with the current value. + +Performs a bitwise \"nand\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "#![feature(atomic_nand)] + +use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0x13); +assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13); +assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); +```"), + #[inline] + #[$stable_nand] + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_nand(self.v.get(), val, order) } + } } - /// Bitwise "or" with the current value. - /// - /// Performs a bitwise "or" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111); - #[inline] - #[$stable] - pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_or(self.v.get(), val, order) } + doc_comment! { + concat!("Bitwise \"or\" with the current value. + +Performs a bitwise \"or\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b111111); +```"), + #[inline] + #[$stable] + pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_or(self.v.get(), val, order) } + } } - /// Bitwise "xor" with the current value. - /// - /// Performs a bitwise "xor" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110); - #[inline] - #[$stable] - pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_xor(self.v.get(), val, order) } + doc_comment! { + concat!("Bitwise \"xor\" with the current value. + +Performs a bitwise \"xor\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b011110); +```"), + #[inline] + #[$stable] + pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_xor(self.v.get(), val, order) } + } } } } @@ -1404,6 +1431,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i8", "../../../std/primitive.i8.html", + "#![feature(integer_atomics)]\n\n", i8 AtomicI8 ATOMIC_I8_INIT } #[cfg(target_has_atomic = "8")] @@ -1415,6 +1443,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u8", "../../../std/primitive.u8.html", + "#![feature(integer_atomics)]\n\n", u8 AtomicU8 ATOMIC_U8_INIT } #[cfg(target_has_atomic = "16")] @@ -1426,6 +1455,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i16", "../../../std/primitive.i16.html", + "#![feature(integer_atomics)]\n\n", i16 AtomicI16 ATOMIC_I16_INIT } #[cfg(target_has_atomic = "16")] @@ -1437,6 +1467,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u16", "../../../std/primitive.u16.html", + "#![feature(integer_atomics)]\n\n", u16 AtomicU16 ATOMIC_U16_INIT } #[cfg(target_has_atomic = "32")] @@ -1448,6 +1479,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i32", "../../../std/primitive.i32.html", + "#![feature(integer_atomics)]\n\n", i32 AtomicI32 ATOMIC_I32_INIT } #[cfg(target_has_atomic = "32")] @@ -1459,6 +1491,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u32", "../../../std/primitive.u32.html", + "#![feature(integer_atomics)]\n\n", u32 AtomicU32 ATOMIC_U32_INIT } #[cfg(target_has_atomic = "64")] @@ -1470,6 +1503,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i64", "../../../std/primitive.i64.html", + "#![feature(integer_atomics)]\n\n", i64 AtomicI64 ATOMIC_I64_INIT } #[cfg(target_has_atomic = "64")] @@ -1481,6 +1515,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u64", "../../../std/primitive.u64.html", + "#![feature(integer_atomics)]\n\n", u64 AtomicU64 ATOMIC_U64_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1492,6 +1527,7 @@ atomic_int!{ stable(feature = "atomic_from", since = "1.23.0"), unstable(feature = "atomic_nand", issue = "13226"), "isize", "../../../std/primitive.isize.html", + "", isize AtomicIsize ATOMIC_ISIZE_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1503,6 +1539,7 @@ atomic_int!{ stable(feature = "atomic_from", since = "1.23.0"), unstable(feature = "atomic_nand", issue = "13226"), "usize", "../../../std/primitive.usize.html", + "", usize AtomicUsize ATOMIC_USIZE_INIT } From f332a9ce5676859f0f07c4d6bf2d2c415be67066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:26:57 -0700 Subject: [PATCH 131/546] Single diagnostic for all non-mentioned fields in a pattern --- src/librustc_typeck/check/_match.rs | 22 ++++++++++++++----- .../ui/missing-fields-in-struct-pattern.rs | 2 ++ .../missing-fields-in-struct-pattern.stderr | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0b5383f1f8d1e..cc72a565ba28e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -993,13 +993,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); tcx.sess.span_err(span, "`..` cannot be used in union patterns"); } } else if !etc { - for field in variant.fields + let unmentioned_fields = variant.fields .iter() - .filter(|field| !used_fields.contains_key(&field.name)) { + .map(|field| field.name) + .filter(|field| !used_fields.contains_key(&field)) + .collect::>(); + if unmentioned_fields.len() > 0 { + let field_names = if unmentioned_fields.len() == 1 { + format!("field `{}`", unmentioned_fields[0]) + } else { + format!("fields {}", + unmentioned_fields.iter() + .map(|name| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; let mut diag = struct_span_err!(tcx.sess, span, E0027, - "pattern does not mention field `{}`", - field.name); - diag.span_label(span, format!("missing field `{}`", field.name)); + "pattern does not mention {}", + field_names); + diag.span_label(span, format!("missing {}", field_names)); if variant.ctor_kind == CtorKind::Fn { diag.note("trying to match a tuple variant with a struct variant pattern"); } diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 2469f24534543..28ed151b98606 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -12,6 +12,8 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { + //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] + //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr new file mode 100644 index 0000000000000..88fba19d14e35 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -0,0 +1,22 @@ +error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` + --> $DIR/missing-fields-in-struct-pattern.rs:14:16 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^ ^ ^ ^ struct `S` does not have field `d` + | | | | + | | | struct `S` does not have field `c` + | | struct `S` does not have field `b` + | struct `S` does not have field `a` + +error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` + --> $DIR/missing-fields-in-struct-pattern.rs:14:12 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3` + | + = note: trying to match a tuple variant with a struct variant pattern + +error: aborting due to 2 previous errors + +Some errors occurred: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. From bac6484a315a805287b98adc3c9c0909579c8393 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Mar 2018 23:25:55 +0100 Subject: [PATCH 132/546] Fix automatic urls with backticks --- src/librustdoc/clean/mod.rs | 16 ++++++++-------- src/librustdoc/html/markdown.rs | 4 ++-- src/test/rustdoc/check-styled-link.rs | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/test/rustdoc/check-styled-link.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 904c24815cb7f..72e303e198202 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -929,7 +929,7 @@ fn ambiguity_error(cx: &DocContext, attrs: &Attributes, select the {}", disambig1, kind1, disambig2, kind2)) - .emit(); + .emit(); } /// Given an enum variant's def, return the def of its enum and the associated fragment @@ -1074,6 +1074,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { } } +#[derive(Debug)] enum PathKind { /// can be either value or type, not a macro Unknown, @@ -1082,7 +1083,7 @@ enum PathKind { /// values, functions, consts, statics, everything in the value namespace Value, /// types, traits, everything in the type namespace - Type + Type, } impl Clean for [ast::Attribute] { @@ -1091,12 +1092,13 @@ impl Clean for [ast::Attribute] { if UnstableFeatures::from_environment().is_nightly_build() { let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new); - for link in markdown_links(&dox) { + for ori_link in markdown_links(&dox) { // bail early for real links - if link.contains('/') { + if ori_link.contains('/') { continue; } - let (def, fragment) = { + let link = ori_link.replace("`", ""); + let (def, fragment) = { let mut kind = PathKind::Unknown; let path_str = if let Some(prefix) = ["struct@", "enum@", "type@", @@ -1132,7 +1134,6 @@ impl Clean for [ast::Attribute] { continue; } - match kind { PathKind::Value => { if let Ok(def) = resolve(cx, path_str, true) { @@ -1206,9 +1207,8 @@ impl Clean for [ast::Attribute] { } }; - let id = register_def(cx, def); - attrs.links.push((link, id, fragment)); + attrs.links.push((ori_link, id, fragment)); } cx.sess().abort_if_errors(); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5e55353a26e6b..8d1c9e4575e26 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -232,14 +232,14 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { /// Make headings links with anchor ids and build up TOC. struct LinkReplacer<'a, 'b, I: Iterator>> { inner: I, - links: &'b [(String, String)] + links: &'b [(String, String)], } impl<'a, 'b, I: Iterator>> LinkReplacer<'a, 'b, I> { fn new(iter: I, links: &'b [(String, String)]) -> Self { LinkReplacer { inner: iter, - links + links, } } } diff --git a/src/test/rustdoc/check-styled-link.rs b/src/test/rustdoc/check-styled-link.rs new file mode 100644 index 0000000000000..1633711e83d9a --- /dev/null +++ b/src/test/rustdoc/check-styled-link.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +pub struct Foo; + +// @has foo/struct.Bar.html '//a[@href="../foo/struct.Foo.html"]' 'Foo' + +/// Code-styled reference to [`Foo`]. +pub struct Bar; From 6212904dd800864ca20ede8690fc827a1169fa26 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 19 Mar 2018 15:40:09 -0700 Subject: [PATCH 133/546] Don't use posix_spawn() if PATH was modified in the environment. The expected behavior is that the environment's PATH should be used to find the process. posix_spawn() could be used if we iterated PATH to search for the binary to execute. For now just skip posix_spawn() if PATH is modified. --- src/libstd/sys/unix/process/process_common.rs | 3 +++ src/libstd/sys/unix/process/process_unix.rs | 1 + src/libstd/sys_common/process.rs | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index d0486f06a143a..48255489dd916 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -184,6 +184,9 @@ impl Command { let maybe_env = self.env.capture_if_changed(); maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) } + pub fn env_saw_path(&self) -> bool { + self.env.have_changed_path() + } pub fn setup_io(&self, default: Stdio, needs_stdin: bool) -> io::Result<(StdioPipes, ChildPipes)> { diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 29e33ee822ee5..9d6d607e3f340 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -256,6 +256,7 @@ impl Command { if self.get_cwd().is_some() || self.get_gid().is_some() || self.get_uid().is_some() || + self.env_saw_path() || self.get_closures().len() != 0 { return Ok(None) } diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs index fd1a5fdb4109b..775491d762cda 100644 --- a/src/libstd/sys_common/process.rs +++ b/src/libstd/sys_common/process.rs @@ -47,6 +47,7 @@ impl EnvKey for DefaultEnvKey {} #[derive(Clone, Debug)] pub struct CommandEnv { clear: bool, + saw_path: bool, vars: BTreeMap> } @@ -54,6 +55,7 @@ impl Default for CommandEnv { fn default() -> Self { CommandEnv { clear: false, + saw_path: false, vars: Default::default() } } @@ -108,9 +110,11 @@ impl CommandEnv { // The following functions build up changes pub fn set(&mut self, key: &OsStr, value: &OsStr) { + self.maybe_saw_path(&key); self.vars.insert(key.to_owned().into(), Some(value.to_owned())); } pub fn remove(&mut self, key: &OsStr) { + self.maybe_saw_path(&key); if self.clear { self.vars.remove(key); } else { @@ -121,4 +125,12 @@ impl CommandEnv { self.clear = true; self.vars.clear(); } + pub fn have_changed_path(&self) -> bool { + self.saw_path || self.clear + } + fn maybe_saw_path(&mut self, key: &OsStr) { + if !self.saw_path && key.to_os_string() == OsString::from("PATH") { + self.saw_path = true; + } + } } From 25c8210c01db12fb9edfd2481ca81c91934c4bbd Mon Sep 17 00:00:00 2001 From: memoryleak47 Date: Mon, 19 Mar 2018 23:48:02 +0100 Subject: [PATCH 134/546] Put `#[macro_use] extern crate ` before fn main() in doctests --- src/librustdoc/test.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 117b21d47587f..0f27775417d86 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -416,6 +416,7 @@ fn partition_source(s: &str) -> (String, String) { let trimline = line.trim(); let header = trimline.is_whitespace() || trimline.starts_with("#![") || + trimline.starts_with("#[macro_use] extern crate") || trimline.starts_with("extern crate"); if !header || after_header { after_header = true; @@ -825,6 +826,24 @@ assert_eq!(2+2, 4); assert_eq!(output, (expected, 2)); } + #[test] + fn make_test_manual_extern_crate_with_macro_use() { + let opts = TestOptions::default(); + let input = +"#[macro_use] extern crate asdf; +use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +#[macro_use] extern crate asdf; +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 2)); + } + #[test] fn make_test_opts_attrs() { //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those From 8e0faf79c0859f22d4e11268f272247a6ef73709 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 19 Mar 2018 16:15:26 -0700 Subject: [PATCH 135/546] Simplify PATH key comparison --- src/libstd/sys_common/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs index 775491d762cda..d0c5951bd6c0a 100644 --- a/src/libstd/sys_common/process.rs +++ b/src/libstd/sys_common/process.rs @@ -129,7 +129,7 @@ impl CommandEnv { self.saw_path || self.clear } fn maybe_saw_path(&mut self, key: &OsStr) { - if !self.saw_path && key.to_os_string() == OsString::from("PATH") { + if !self.saw_path && key == "PATH" { self.saw_path = true; } } From c43b1a09e034f978317bf087214f8f4cde80ba40 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 15 Mar 2018 18:56:20 -0400 Subject: [PATCH 136/546] Convert SerializedDepGraph to be a struct-of-arrays Fixes #47326 --- src/librustc/dep_graph/graph.rs | 7 +++---- src/librustc/dep_graph/prev.rs | 8 ++++---- src/librustc/dep_graph/serialized.rs | 6 +++++- src/librustc_data_structures/indexed_vec.rs | 7 +++++++ src/librustc_incremental/persist/save.rs | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0ad79eacd2b03..d60c22064d3a0 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -476,10 +476,8 @@ impl DepGraph { fingerprints.resize(current_dep_graph.nodes.len(), Fingerprint::ZERO); } - let nodes: IndexVec<_, (DepNode, Fingerprint)> = - current_dep_graph.nodes.iter_enumerated().map(|(idx, &dep_node)| { - (dep_node, fingerprints[idx]) - }).collect(); + let fingerprints = fingerprints.clone().convert_index_type(); + let nodes = current_dep_graph.nodes.clone().convert_index_type(); let total_edge_count: usize = current_dep_graph.edges.iter() .map(|v| v.len()) @@ -503,6 +501,7 @@ impl DepGraph { SerializedDepGraph { nodes, + fingerprints, edge_list_indices, edge_list_data, } diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 504b60e763e23..669a99019aa60 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -23,7 +23,7 @@ impl PreviousDepGraph { pub fn new(data: SerializedDepGraph) -> PreviousDepGraph { let index: FxHashMap<_, _> = data.nodes .iter_enumerated() - .map(|(idx, &(dep_node, _))| (dep_node, idx)) + .map(|(idx, &dep_node)| (dep_node, idx)) .collect(); PreviousDepGraph { data, index } } @@ -41,7 +41,7 @@ impl PreviousDepGraph { #[inline] pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { - self.data.nodes[dep_node_index].0 + self.data.nodes[dep_node_index] } #[inline] @@ -58,14 +58,14 @@ impl PreviousDepGraph { pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { self.index .get(dep_node) - .map(|&node_index| self.data.nodes[node_index].1) + .map(|&node_index| self.data.fingerprints[node_index]) } #[inline] pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { - self.data.nodes[dep_node_index].1 + self.data.fingerprints[dep_node_index] } pub fn node_count(&self) -> usize { diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index c96040ab9b6e3..60fc813a25d51 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -20,7 +20,10 @@ newtype_index!(SerializedDepNodeIndex); #[derive(Debug, RustcEncodable, RustcDecodable)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph - pub nodes: IndexVec, + pub nodes: IndexVec, + /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to + /// the DepNode at the same index in the nodes vector. + pub fingerprints: IndexVec, /// For each DepNode, stores the list of edges originating from that /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data, /// which holds the actual DepNodeIndices of the target nodes. @@ -35,6 +38,7 @@ impl SerializedDepGraph { pub fn new() -> SerializedDepGraph { SerializedDepGraph { nodes: IndexVec::new(), + fingerprints: IndexVec::new(), edge_list_indices: IndexVec::new(), edge_list_data: Vec::new(), } diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index a5b1a7e57ab46..cbb3ff5171592 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -503,6 +503,13 @@ impl IndexVec { (c1, c2) } } + + pub fn convert_index_type(self) -> IndexVec { + IndexVec { + raw: self.raw, + _marker: PhantomData, + } + } } impl IndexVec { diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index ca1e3563089db..a5bc1106ba0b0 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -162,7 +162,7 @@ fn encode_dep_graph(tcx: TyCtxt, let mut counts: FxHashMap<_, Stat> = FxHashMap(); - for (i, &(node, _)) in serialized_graph.nodes.iter_enumerated() { + for (i, &node) in serialized_graph.nodes.iter_enumerated() { let stat = counts.entry(node.kind).or_insert(Stat { kind: node.kind, node_counter: 0, From 062a46fdd1d49b1ccdc4f713433521463224d7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Mar 2018 14:13:57 -0700 Subject: [PATCH 137/546] Reduce diagnostic verbosity by removing labels --- src/librustc_typeck/check/_match.rs | 17 +++++++++-------- .../compile-fail/struct-pat-derived-error.rs | 6 ++---- src/test/ui/error-codes/E0026-teach.stderr | 2 +- src/test/ui/error-codes/E0026.stderr | 2 +- src/test/ui/missing-fields-in-struct-pattern.rs | 2 +- .../ui/missing-fields-in-struct-pattern.stderr | 6 +----- src/test/ui/numeric-fields.stderr | 2 +- src/test/ui/type-check/issue-41314.stderr | 2 +- src/test/ui/union/union-fields-2.stderr | 2 +- 9 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cc72a565ba28e..7965806af5d09 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -938,14 +938,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } if inexistent_fields.len() > 0 { - let field_names = if inexistent_fields.len() == 1 { - format!("a field named `{}`", inexistent_fields[0].1) + let (field_names, t, plural) = if inexistent_fields.len() == 1 { + (format!("a field named `{}`", inexistent_fields[0].1), "this", "") } else { - format!("fields named {}", - inexistent_fields.iter() + (format!("fields named {}", + inexistent_fields.iter() .map(|(_, name)| format!("`{}`", name)) .collect::>() - .join(", ")) + .join(", ")), "these", "s") }; let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); let mut err = struct_span_err!(tcx.sess, @@ -955,12 +955,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); kind_name, tcx.item_path_str(variant.did), field_names); - for (span, name) in &inexistent_fields { + if let Some((span, _)) = inexistent_fields.last() { err.span_label(*span, - format!("{} `{}` does not have field `{}`", + format!("{} `{}` does not have {} field{}", kind_name, tcx.item_path_str(variant.did), - name)); + t, + plural)); } if tcx.sess.teach(&err.get_code().unwrap()) { err.note( diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs index f525ec373753d..d3130c4e831f6 100644 --- a/src/test/compile-fail/struct-pat-derived-error.rs +++ b/src/test/compile-fail/struct-pat-derived-error.rs @@ -16,10 +16,8 @@ struct a { impl a { fn foo(&self) { let a { x, y } = self.d; //~ ERROR no field `d` on type `&a` - //~^ ERROR struct `a` does not have a field named `x` - //~^^ ERROR struct `a` does not have a field named `y` - //~^^^ ERROR pattern does not mention field `b` - //~^^^^ ERROR pattern does not mention field `c` + //~^ ERROR struct `a` does not have fields named `x`, `y` + //~| ERROR pattern does not mention fields `b`, `c` } } diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr index 63d072fe03d0a..67ea32fba86d6 100644 --- a/src/test/ui/error-codes/E0026-teach.stderr +++ b/src/test/ui/error-codes/E0026-teach.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026-teach.rs:21:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field | = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr index af8519511276c..9dabbc8a775fb 100644 --- a/src/test/ui/error-codes/E0026.stderr +++ b/src/test/ui/error-codes/E0026.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026.rs:19:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field error: aborting due to previous error diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 28ed151b98606..dfde37994998b 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -13,7 +13,7 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] - //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] + //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr index 88fba19d14e35..d1c3260f11e30 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.stderr +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -2,11 +2,7 @@ error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` --> $DIR/missing-fields-in-struct-pattern.rs:14:16 | LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^ ^ ^ ^ struct `S` does not have field `d` - | | | | - | | | struct `S` does not have field `c` - | | struct `S` does not have field `b` - | struct `S` does not have field `a` + | ^ ^ ^ ^ struct `S` does not have these fields error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` --> $DIR/missing-fields-in-struct-pattern.rs:14:12 diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr index 607980ba3bf54..68a87da8ded32 100644 --- a/src/test/ui/numeric-fields.stderr +++ b/src/test/ui/numeric-fields.stderr @@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:17:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^^^^ struct `S` does not have field `0x1` + | ^^^^^^ struct `S` does not have this field error: aborting due to 2 previous errors diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index bcb0f9a99a779..f7d4bb9a02f45 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -2,7 +2,7 @@ error[E0026]: variant `X::Y` does not have a field named `number` --> $DIR/issue-41314.rs:17:16 | LL | X::Y { number } => {} //~ ERROR does not have a field named `number` - | ^^^^^^ variant `X::Y` does not have field `number` + | ^^^^^^ variant `X::Y` does not have this field error[E0027]: pattern does not mention field `0` --> $DIR/issue-41314.rs:17:9 diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index 3ea4d3426dad7..cfb5bc7520b59 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -52,7 +52,7 @@ error[E0026]: union `U` does not have a field named `c` --> $DIR/union-fields-2.rs:28:19 | LL | let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field - | ^ union `U` does not have field `c` + | ^ union `U` does not have this field error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:28:9 From 57e3df3f879090207f5a128a497b66916aeabb6b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 19 Mar 2018 23:35:23 -0400 Subject: [PATCH 138/546] Fix ordering of auto-generated trait bounds in rustdoc output While the order of the where clauses was deterministic, the ordering of bounds and lifetimes was not. This made the order flip- flop randomly when new traits and impls were added to libstd. This PR makes the ordering of bounds and lifetimes deterministic, and re-enables the test that was causing the issue. Fixes #49123 --- src/librustdoc/clean/auto_trait.rs | 102 ++++++++++++------ .../rustdoc/synthetic_auto/no-redundancy.rs | 2 - 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 370fc9bbca243..918bc1df0b1d6 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -9,6 +9,7 @@ // except according to those terms. use rustc::ty::TypeFoldable; +use std::fmt::Debug; use super::*; @@ -1081,18 +1082,25 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { return None; } + let mut bounds_vec = bounds.into_iter().collect(); + self.sort_where_bounds(&mut bounds_vec); + Some(WherePredicate::BoundPredicate { ty, - bounds: bounds.into_iter().collect(), + bounds: bounds_vec, }) }) .chain( lifetime_to_bounds .into_iter() .filter(|&(_, ref bounds)| !bounds.is_empty()) - .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { - lifetime, - bounds: bounds.into_iter().collect(), + .map(|(lifetime, bounds)| { + let mut bounds_vec = bounds.into_iter().collect(); + self.sort_where_lifetimes(&mut bounds_vec); + WherePredicate::RegionPredicate { + lifetime, + bounds: bounds_vec, + } }), ) .collect() @@ -1372,40 +1380,64 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // a given set of predicates always appears in the same order - // both for visual consistency between 'rustdoc' runs, and to // make writing tests much easier - fn sort_where_predicates(&self, predicates: &mut Vec) { + #[inline] + fn sort_where_predicates(&self, mut predicates: &mut Vec) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. - predicates.sort_unstable_by(|first, second| { - // This might look horrendously hacky, but it's actually not that bad. - // - // For performance reasons, we use several different FxHashMaps - // in the process of computing the final set of where predicates. - // However, the iteration order of a HashMap is completely unspecified. - // In fact, the iteration of an FxHashMap can even vary between platforms, - // since FxHasher has different behavior for 32-bit and 64-bit platforms. - // - // Obviously, it's extremely undesireable for documentation rendering - // to be depndent on the platform it's run on. Apart from being confusing - // to end users, it makes writing tests much more difficult, as predicates - // can appear in any order in the final result. - // - // To solve this problem, we sort WherePredicates by their Debug - // string. The thing to keep in mind is that we don't really - // care what the final order is - we're synthesizing an impl - // ourselves, so any order can be considered equally valid. - // By sorting the predicates, however, we ensure that for - // a given codebase, all auto-trait impls always render - // in exactly the same way. - // - // Using the Debug impementation for sorting prevents - // us from needing to write quite a bit of almost - // entirely useless code (e.g. how should two - // Types be sorted relative to each other). - // This approach is probably somewhat slower, but - // the small number of items involved (impls - // rarely have more than a few bounds) means - // that it shouldn't matter in practice. + self.unstable_debug_sort(&mut predicates); + } + + // Ensure that the bounds are in a consistent order. The precise + // ordering doesn't actually matter, but it's important that + // a given set of bounds always appears in the same order - + // both for visual consistency between 'rustdoc' runs, and to + // make writing tests much easier + #[inline] + fn sort_where_bounds(&self, mut bounds: &mut Vec) { + // We should never have identical bounds - and if we do, + // they're visually identical as well. Therefore, using + // an unstable sort is fine. + self.unstable_debug_sort(&mut bounds); + } + + #[inline] + fn sort_where_lifetimes(&self, mut bounds: &mut Vec) { + // We should never have identical bounds - and if we do, + // they're visually identical as well. Therefore, using + // an unstable sort is fine. + self.unstable_debug_sort(&mut bounds); + } + + // This might look horrendously hacky, but it's actually not that bad. + // + // For performance reasons, we use several different FxHashMaps + // in the process of computing the final set of where predicates. + // However, the iteration order of a HashMap is completely unspecified. + // In fact, the iteration of an FxHashMap can even vary between platforms, + // since FxHasher has different behavior for 32-bit and 64-bit platforms. + // + // Obviously, it's extremely undesireable for documentation rendering + // to be depndent on the platform it's run on. Apart from being confusing + // to end users, it makes writing tests much more difficult, as predicates + // can appear in any order in the final result. + // + // To solve this problem, we sort WherePredicates and TyParamBounds + // by their Debug string. The thing to keep in mind is that we don't really + // care what the final order is - we're synthesizing an impl or bound + // ourselves, so any order can be considered equally valid. By sorting the + // predicates and bounds, however, we ensure that for a given codebase, all + // auto-trait impls always render in exactly the same way. + // + // Using the Debug impementation for sorting prevents us from needing to + // write quite a bit of almost entirely useless code (e.g. how should two + // Types be sorted relative to each other). It also allows us to solve the + // problem for both WherePredicates and TyParamBounds at the same time. This + // approach is probably somewhat slower, but the small number of items + // involved (impls rarely have more than a few bounds) means that it + // shouldn't matter in practice. + fn unstable_debug_sort(&self, vec: &mut Vec) { + vec.sort_unstable_by(|first, second| { format!("{:?}", first).cmp(&format!("{:?}", second)) }); } diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index daa91c3e12bb8..0b37f2ed31790 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test - pub struct Inner { field: T, } From 7daf3f941af996d6b816aa778aab4b9348d26703 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 01:02:15 -0400 Subject: [PATCH 139/546] Fix tidy trailing whitespace --- src/librustdoc/clean/auto_trait.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 918bc1df0b1d6..9ff3d25a45ae4 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -1387,7 +1387,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // an unstable sort is fine. self.unstable_debug_sort(&mut predicates); } - + // Ensure that the bounds are in a consistent order. The precise // ordering doesn't actually matter, but it's important that // a given set of bounds always appears in the same order - @@ -1400,7 +1400,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // an unstable sort is fine. self.unstable_debug_sort(&mut bounds); } - + #[inline] fn sort_where_lifetimes(&self, mut bounds: &mut Vec) { // We should never have identical bounds - and if we do, From be29e52c5a3d9da894a0292f9175106a955071c9 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:02:17 -0500 Subject: [PATCH 140/546] Match against friendly error message --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ff2b32f3fd93b..67ee39d10d91c 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` fn main() -> i32 { -//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index ea39ba92f4143..5f4ccf2b5862e 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `char fn main() -> char { -//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied ' ' } From 5ccf3ffab24a4237e467b884af6783b1af54bdd8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:06:46 -0500 Subject: [PATCH 141/546] diagnostics: Remove main return type errors from E0580 --- src/librustc/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b3a904f2f5fec..7627071e56037 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1764,12 +1764,12 @@ The `main` function was incorrectly declared. Erroneous code example: ```compile_fail,E0580 -fn main() -> i32 { // error: main function has wrong type - 0 +fn main(x: i32) { // error: main function has wrong type + println!("{}", x); } ``` -The `main` function prototype should never take arguments or return type. +The `main` function prototype should never take arguments. Example: ``` From 4eff4d9500968e8a6275185eac153e102996edb5 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 20 Mar 2018 08:25:25 +0100 Subject: [PATCH 142/546] ignore emscripten in run-pass test --- src/test/run-pass/simd-intrinsic-generic-select.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-pass/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd-intrinsic-generic-select.rs index bf0a59309ca29..8e94d797e8944 100644 --- a/src/test/run-pass/simd-intrinsic-generic-select.rs +++ b/src/test/run-pass/simd-intrinsic-generic-select.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten + // Test that the simd_select intrinsics produces correct results. #![feature(repr_simd, platform_intrinsics)] From 619003d1d414167630331efffe83702f74413be6 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 05:33:59 -0400 Subject: [PATCH 143/546] Implement some trivial size_hints for various iterators This also implements ExactSizeIterator where applicable. Addresses most of the Iterator traits mentioned in #23708. --- src/libcore/char.rs | 5 ++++ src/libcore/iter/traits.rs | 4 ++++ src/libcore/option.rs | 5 ++++ src/librustc/hir/pat_util.rs | 4 ++++ src/librustc/mir/traversal.rs | 26 +++++++++++++++++++++ src/librustc/session/search_paths.rs | 7 ++++++ src/librustc/traits/util.rs | 5 ++++ src/librustc_data_structures/bitvec.rs | 5 ++++ src/librustc_data_structures/graph/mod.rs | 13 +++++++++++ src/librustc_driver/pretty.rs | 7 ++++++ src/librustc_typeck/check/method/suggest.rs | 7 ++++++ src/librustdoc/clean/mod.rs | 5 ++++ src/libsyntax_ext/format_foreign.rs | 9 +++++++ 13 files changed, 102 insertions(+) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 1638f9710f597..2f56238a4638b 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -902,6 +902,11 @@ impl> Iterator for DecodeUtf8 { } }) } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[unstable(feature = "decode_utf8", issue = "33906")] diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 0267fcd375453..5e4622f804aff 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -901,6 +901,10 @@ impl Iterator for ResultShunt None => None, } } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } } #[stable(feature = "iter_arith_traits_result", since="1.16.0")] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 570f745f8330c..1ca69f3f503d1 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1188,6 +1188,11 @@ impl> FromIterator> for Option { None => None, } } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } } let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 2bec224362ea6..1f00a3ab1f5de 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -31,6 +31,10 @@ impl Iterator for EnumerateAndAdjust where I: Iterator { (if i < self.gap_pos { i } else { i + self.gap_len }, elem) }) } + + fn size_hint(&self) -> (usize, Option) { + self.enumerate.size_hint() + } } pub trait EnumerateAndAdjustIterator { diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 74c3408c4c2f6..666ca5eabe81b 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -77,8 +77,18 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { None } + + fn size_hint(&self) -> (usize, Option) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} + /// Postorder traversal of a graph. /// /// Postorder traversal is when each node is visited after all of it's @@ -210,8 +220,18 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { next.map(|(bb, _)| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {} + /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. @@ -276,4 +296,10 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + (self.idx, Some(self.idx)) + } } + +impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {} diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 5bbc6841693ea..d2dca9f60845a 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -78,4 +78,11 @@ impl<'a> Iterator for Iter<'a> { } } } + + fn size_hint(&self) -> (usize, Option) { + // This iterator will never return more elements than the base iterator; + // but it can ignore all the remaining elements. + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 8f7a24057472c..9e38911f53c9a 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -347,6 +347,11 @@ impl<'tcx,I:Iterator>> Iterator for FilterToTraits { } } } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.base_iterator.size_hint(); + (0, upper) + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_data_structures/bitvec.rs b/src/librustc_data_structures/bitvec.rs index 54565afa4c6c7..28e3180063c17 100644 --- a/src/librustc_data_structures/bitvec.rs +++ b/src/librustc_data_structures/bitvec.rs @@ -132,6 +132,11 @@ impl<'a> Iterator for BitVectorIter<'a> { self.idx += offset + 1; return Some(self.idx - 1); } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } impl FromIterator for BitVector { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 1945b82c03145..e2b393071ff5c 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -334,6 +334,11 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { self.next = edge.next_edge[self.direction.repr]; Some((edge_index, edge)) } + + fn size_hint(&self) -> (usize, Option) { + // At most, all the edges in the graph. + (0, Some(self.graph.len_edges())) + } } pub struct DepthFirstTraversal<'g, N, E> @@ -383,8 +388,16 @@ impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> { } next } + + fn size_hint(&self) -> (usize, Option) { + // We will visit every node in the graph exactly once. + let remaining = self.graph.len_nodes() - self.visited.count(); + (remaining, Some(remaining)) + } } +impl<'g, N: Debug, E: Debug> ExactSizeIterator for DepthFirstTraversal<'g, N, E> {} + impl Edge { pub fn source(&self) -> NodeIndex { self.source diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4ae6a93d6983a..c5e7fdb30d36a 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -584,6 +584,13 @@ impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> { &mut NodesMatchingSuffix(ref mut iter) => iter.next(), } } + + fn size_hint(&self) -> (usize, Option) { + match self { + &NodesMatchingDirect(ref iter) => iter.size_hint(), + &NodesMatchingSuffix(ref iter) => iter.size_hint(), + } + } } impl UserIdentifiedItem { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d6409..a753698050332 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -718,8 +718,15 @@ impl<'a> Iterator for AllTraits<'a> { TraitInfo::new(*info) }) } + + fn size_hint(&self) -> (usize, Option) { + let len = self.borrow.as_ref().unwrap().len() - self.idx; + (len, Some(len)) + } } +impl<'a> ExactSizeIterator for AllTraits<'a> {} + struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> { target_module: ast::NodeId, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 904c24815cb7f..a2a0e878fd888 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -602,6 +602,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { None } + + fn size_hint(&self) -> (usize, Option) { + let lower = self.current_list.len(); + (lower, None) + } } pub trait AttributesExt { diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index 0476d7d4fcc1c..e95c6f2e1243f 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -272,6 +272,11 @@ pub mod printf { self.s = tail; Some(sub) } + + fn size_hint(&self) -> (usize, Option) { + // Substitutions are at least 2 characters long. + (0, Some(self.s.len() / 2)) + } } enum State { @@ -782,6 +787,10 @@ pub mod shell { None => None, } } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.s.len())) + } } /// Parse the next substitution from the input string. From 13bfbe1394732163c7130dd57e6b0a86e147c7e8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 20 Mar 2018 10:36:45 +0100 Subject: [PATCH 144/546] Encode/decode extern statics in metadata and incremental cache --- src/librustc/mir/interpret/mod.rs | 14 +++++++++++++ src/librustc/ty/maps/on_disk_cache.rs | 2 +- src/librustc_metadata/encoder.rs | 4 ++-- .../incremental/extern_static/issue-49153.rs | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/test/incremental/extern_static/issue-49153.rs diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 04ffb9af29ed5..e242ec4985ab4 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -156,6 +156,8 @@ impl ::rustc_serialize::UseSpecializedDecodable for AllocId {} pub const ALLOC_DISCRIMINANT: usize = 0; pub const FN_DISCRIMINANT: usize = 1; +pub const EXTERN_STATIC_DISCRIMINANT: usize = 2; +pub const SHORTHAND_START: usize = 3; pub fn specialized_encode_alloc_id< 'a, 'tcx, @@ -173,6 +175,7 @@ pub fn specialized_encode_alloc_id< trace!("encoding {:?} with {:#?}", alloc_id, alloc); ALLOC_DISCRIMINANT.encode(encoder)?; alloc.encode(encoder)?; + // encode whether this allocation is the root allocation of a static tcx.interpret_interner .get_corresponding_static_def_id(alloc_id) .encode(encoder)?; @@ -180,6 +183,10 @@ pub fn specialized_encode_alloc_id< trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); FN_DISCRIMINANT.encode(encoder)?; fn_instance.encode(encoder)?; + } else if let Some(did) = tcx.interpret_interner.get_corresponding_static_def_id(alloc_id) { + // extern "C" statics don't have allocations, just encode its def_id + EXTERN_STATIC_DISCRIMINANT.encode(encoder)?; + did.encode(encoder)?; } else { bug!("alloc id without corresponding allocation: {}", alloc_id); } @@ -225,6 +232,13 @@ pub fn specialized_decode_alloc_id< cache(decoder, pos, id); Ok(id) }, + EXTERN_STATIC_DISCRIMINANT => { + trace!("creating extern static alloc id at {}", pos); + let did = DefId::decode(decoder)?; + let alloc_id = tcx.interpret_interner.reserve(); + tcx.interpret_interner.cache(did, alloc_id); + Ok(alloc_id) + }, shorthand => { trace!("loading shorthand {}", shorthand); short(decoder, shorthand) diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index e56d8f8e818dd..d636246b57f1b 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -819,7 +819,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder< // of the metadata file, because that would end up making our indices // not special. It is essentially impossible for that to happen, // but let's make sure - assert!(pos != interpret::ALLOC_DISCRIMINANT && pos != interpret::FN_DISCRIMINANT); + assert!(pos >= interpret::SHORTHAND_START); entry.insert(pos); None }, diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0da23c2caf4ae..6b3453f2c99e8 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -203,9 +203,9 @@ impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx Entry::Occupied(entry) => Some(entry.get().clone()), Entry::Vacant(entry) => { // ensure that we don't place any AllocIds at the very beginning - // of the metadata file, because that would end up making our 0 and 1 indices + // of the metadata file, because that would end up making our indices // not special. This is essentially impossible, but let's make sure - assert!(pos != 0 && pos != 1); + assert!(pos >= interpret::SHORTHAND_START); entry.insert(pos); None }, diff --git a/src/test/incremental/extern_static/issue-49153.rs b/src/test/incremental/extern_static/issue-49153.rs new file mode 100644 index 0000000000000..e0538e09c6470 --- /dev/null +++ b/src/test/incremental/extern_static/issue-49153.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49153 + +// revisions:rpass1 rpass2 + +extern "C" { + pub static __ImageBase: u8; +} + +pub static FOO: &'static u8 = unsafe { &__ImageBase }; + +fn main() {} From eae6d512f0549307947e5fe1b8ee646916b82320 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 19:07:13 +0000 Subject: [PATCH 145/546] Add more canonicalisations for OS_TABLE and ARCH_TABLE --- src/tools/compiletest/src/util.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 8c889cc48070d..b73f3e2f64954 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -14,21 +14,25 @@ use common::Config; /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("android", "android"), + ("androideabi", "android"), ("bitrig", "bitrig"), ("cloudabi", "cloudabi"), ("darwin", "macos"), ("dragonfly", "dragonfly"), + ("emscripten", "emscripten"), ("freebsd", "freebsd"), + ("fuchsia", "fuchsia"), ("haiku", "haiku"), ("ios", "ios"), + ("l4re", "l4re"), ("linux", "linux"), ("mingw32", "windows"), ("netbsd", "netbsd"), ("openbsd", "openbsd"), + ("redox", "redox"), + ("solaris", "solaris"), ("win32", "windows"), ("windows", "windows"), - ("solaris", "solaris"), - ("emscripten", "emscripten"), ]; const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ @@ -36,21 +40,33 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("amd64", "x86_64"), ("arm", "arm"), ("arm64", "aarch64"), + ("armv4t", "arm"), + ("armv5te", "arm"), + ("armv7", "arm"), + ("armv7s", "arm"), + ("asmjs", "asmjs"), ("hexagon", "hexagon"), ("i386", "x86"), ("i586", "x86"), ("i686", "x86"), - ("mips64", "mips64"), ("mips", "mips"), + ("mips64", "mips64"), + ("mips64el", "mips64"), + ("mipsel", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), ("powerpc64", "powerpc64"), + ("powerpc64le", "powerpc64"), ("s390x", "s390x"), ("sparc", "sparc"), + ("sparc64", "sparc64"), + ("sparcv9", "sparc64"), + ("thumbv6m", "thumb"), + ("thumbv7em", "thumb"), + ("thumbv7m", "thumb"), + ("wasm32", "wasm32"), ("x86_64", "x86_64"), ("xcore", "xcore"), - ("asmjs", "asmjs"), - ("wasm32", "wasm32"), ]; pub fn matches_os(triple: &str, name: &str) -> bool { From 1af952cc490b62a1f43f48c9fd809cf99aff2630 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 07:31:22 -0400 Subject: [PATCH 146/546] Remove StdioRaw doc additions, add backticks --- src/libstd/io/stdio.rs | 9 --------- src/libstd/net/addr.rs | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 9a4cde7e16286..1f73054e3beed 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -30,27 +30,18 @@ thread_local! { /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdin_raw` function. -/// -/// The size of a StdinRaw struct may vary depending on the target operating -/// system. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdout_raw` function. -/// -/// The size of a StdoutRaw struct may vary depending on the target operating -/// system. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stderr_raw` function. -/// -/// The size of a StderrRaw struct may vary depending on the target operating -/// system. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index f985c1f2bc8ce..57efc3095fc9e 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -28,7 +28,7 @@ use slice; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// -/// The size of a SocketAddr instance may vary depending on the target operating +/// The size of a `SocketAddr` instance may vary depending on the target operating /// system. /// /// [IP address]: ../../std/net/enum.IpAddr.html From 61e1fbc659103513e68eae29ea830d798e2ec2d5 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 01:36:53 +0000 Subject: [PATCH 147/546] Make compiletest do exact matching on triples This avoids the issues of the previous substring matching, ensuring `ARCH_TABLE` and `OS_TABLE` will no longer contain redundant entries. --- src/tools/compiletest/src/util.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index b73f3e2f64954..c612f0117aaf7 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -75,16 +75,18 @@ pub fn matches_os(triple: &str, name: &str) -> bool { if triple == "wasm32-unknown-unknown" { return name == "emscripten" || name == "wasm32-bare" } + let triple: Vec<_> = triple.split('-').collect(); for &(triple_os, os) in OS_TABLE { - if triple.contains(triple_os) { + if triple.contains(&triple_os) { return os == name; } } panic!("Cannot determine OS from triple"); } pub fn get_arch(triple: &str) -> &'static str { + let triple: Vec<_> = triple.split('-').collect(); for &(triple_arch, arch) in ARCH_TABLE { - if triple.contains(triple_arch) { + if triple.contains(&triple_arch) { return arch; } } From 8c8a72f8224b9cbf283cd120d87397c032ed62f1 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:15:21 +0900 Subject: [PATCH 148/546] Reinit the stack guard on unexpected failure --- src/librustc_driver/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e39a2c2f5dcd9..e56c9928dccd6 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1480,9 +1480,9 @@ pub fn in_rustc_thread(f: F) -> Result> rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - // We have already deinited the stack. Further corruption is - // not allowed. - panic!("in_rustc_thread: error calling setrlimit: {}", err); + error!("in_rustc_thread: error calling setrlimit: {}", err); + std::rt::update_stack_guard(); + true } else { std::rt::update_stack_guard(); false From 8d9774713df3b5d0b3a1bdbb4ecd55658d401d75 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 19 Mar 2018 21:57:41 +0300 Subject: [PATCH 149/546] Update Cargo to fix regression This should fix regressions in Cargo after swithing to clap: * If an external subcommand name was close to built-in one, clap errored (fixed by updating clap version) * External subcomands didn't received their name as a first arg --- src/Cargo.lock | 14 +++++++------- src/tools/cargo | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 26508dec4bba2..675457905eade 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -184,7 +184,7 @@ version = "0.27.0" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.16.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -273,7 +273,7 @@ dependencies = [ [[package]] name = "clap" -version = "2.31.1" +version = "2.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -840,7 +840,7 @@ version = "0.1.0" name = "installer" version = "0.0.0" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1033,7 +1033,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1322,7 +1322,7 @@ name = "racer" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1533,7 +1533,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2699,7 +2699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" +"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" diff --git a/src/tools/cargo b/src/tools/cargo index d6c3983fe3bd8..d10ec661b0642 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d6c3983fe3bd8fa06b54712e53fb23645598188b +Subproject commit d10ec661b06420654bbc4ed0ccd32295698aa1dc From 2928c7a8a253b655132ac9f2beb4ca74540f0e14 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:22:45 +0900 Subject: [PATCH 150/546] Refactor the stack addr aligning code into a function --- src/libstd/sys/unix/thread.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index d94e11a5207cb..4364089a18184 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -284,10 +284,10 @@ pub mod guard { ret } - pub unsafe fn init() -> Option { - PAGE_SIZE = os::page_size(); - - let mut stackaddr = get_stack_start()?; + // Precondition: PAGE_SIZE is initialized. + unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { + assert!(PAGE_SIZE != 0); + let stackaddr = get_stack_start()?; // Ensure stackaddr is page aligned! A parent process might // have reset RLIMIT_STACK to be non-page aligned. The @@ -296,10 +296,17 @@ pub mod guard { // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } + Some(if remainder == 0 { + stackaddr + } else { + ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void + }) + } + + pub unsafe fn init() -> Option { + PAGE_SIZE = os::page_size(); + + let stackaddr = get_stack_start_aligned()?; if cfg!(target_os = "linux") { // Linux doesn't allocate the whole stack right away, and @@ -338,14 +345,7 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { - if let Some(mut stackaddr) = get_stack_start() { - // Ensure address is aligned. Same as above. - let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } - + if let Some(stackaddr) = get_stack_start_aligned() { // Undo the guard page mapping. if munmap(stackaddr, PAGE_SIZE) != 0 { panic!("unable to deallocate the guard page"); From 1b5eb17d61f1651d6b9d412a5be586dfb80fd447 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 12:10:47 -0700 Subject: [PATCH 151/546] ci: Print out how long each step takes on CI This commit updates CI configuration to inform rustbuild that it should print out how long each step takes on CI. This'll hopefully allow us to track the duration of steps over time and follow regressions a bit more closesly (as well as have closer analysis of differences between two builds). cc #48829 --- config.toml.example | 4 +++ src/bootstrap/bin/rustc.rs | 65 ++++++++++++++++++++++++++------------ src/bootstrap/builder.rs | 29 +++++++++++++++-- src/bootstrap/config.rs | 3 ++ src/ci/run.sh | 2 ++ 5 files changed, 81 insertions(+), 22 deletions(-) diff --git a/config.toml.example b/config.toml.example index aec5e5a0e2c80..e92807d5aaaaa 100644 --- a/config.toml.example +++ b/config.toml.example @@ -186,6 +186,10 @@ # essentially skipping stage0 as the local compiler is recompiling itself again. #local-rebuild = false +# Print out how long each rustbuild step took (mostly intended for CI and +# tracking over time) +#print-step-timings = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 4be16475590f4..6701f58ba8e92 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -31,9 +31,11 @@ extern crate bootstrap; use std::env; use std::ffi::OsString; -use std::str::FromStr; +use std::io; use std::path::PathBuf; -use std::process::{Command, ExitStatus}; +use std::process::Command; +use std::str::FromStr; +use std::time::Instant; fn main() { let mut args = env::args_os().skip(1).collect::>(); @@ -90,7 +92,7 @@ fn main() { }; let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); - let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); + let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); @@ -103,6 +105,7 @@ fn main() { .arg(format!("stage{}", stage)) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + let mut maybe_crate = None; if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we @@ -134,6 +137,7 @@ fn main() { .find(|a| &*a[0] == "--crate-name") .unwrap(); let crate_name = &*crate_name[1]; + maybe_crate = Some(crate_name); // If we're compiling specifically the `panic_abort` crate then we pass // the `-C panic=abort` option. Note that we do not do this for any @@ -281,31 +285,52 @@ fn main() { eprintln!("libdir: {:?}", libdir); } - // Actually run the compiler! - std::process::exit(if let Some(ref mut on_fail) = on_fail { - match cmd.status() { - Ok(s) if s.success() => 0, - _ => { - println!("\nDid not run successfully:\n{:?}\n-------------", cmd); - exec_cmd(on_fail).expect("could not run the backup command"); - 1 + if let Some(mut on_fail) = on_fail { + let e = match cmd.status() { + Ok(s) if s.success() => std::process::exit(0), + e => e, + }; + println!("\nDid not run successfully: {:?}\n{:?}\n-------------", e, cmd); + exec_cmd(&mut on_fail).expect("could not run the backup command"); + std::process::exit(1); + } + + if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() { + if let Some(krate) = maybe_crate { + let start = Instant::now(); + let status = cmd + .status() + .expect(&format!("\n\n failed to run {:?}", cmd)); + let dur = start.elapsed(); + + let is_test = args.iter().any(|a| a == "--test"); + eprintln!("[RUSTC-TIMING] {} test:{} {}.{:03}", + krate.to_string_lossy(), + is_test, + dur.as_secs(), + dur.subsec_nanos() / 1_000_000); + + match status.code() { + Some(i) => std::process::exit(i), + None => { + eprintln!("rustc exited with {}", status); + std::process::exit(0xfe); + } } } - } else { - std::process::exit(match exec_cmd(&mut cmd) { - Ok(s) => s.code().unwrap_or(0xfe), - Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), - }) - }) + } + + let code = exec_cmd(&mut cmd).expect(&format!("\n\n failed to run {:?}", cmd)); + std::process::exit(code); } #[cfg(unix)] -fn exec_cmd(cmd: &mut Command) -> ::std::io::Result { +fn exec_cmd(cmd: &mut Command) -> io::Result { use std::os::unix::process::CommandExt; Err(cmd.exec()) } #[cfg(not(unix))] -fn exec_cmd(cmd: &mut Command) -> ::std::io::Result { - cmd.status() +fn exec_cmd(cmd: &mut Command) -> io::Result { + cmd.status().map(|status| status.code().unwrap()) } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437eef..3fd50f17ef3e9 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::any::Any; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; use std::env; use std::fmt::Debug; @@ -18,6 +18,7 @@ use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::process::Command; +use std::time::{Instant, Duration}; use compile; use install; @@ -40,6 +41,7 @@ pub struct Builder<'a> { pub kind: Kind, cache: Cache, stack: RefCell>>, + time_spent_on_dependencies: Cell, } impl<'a> Deref for Builder<'a> { @@ -343,6 +345,7 @@ impl<'a> Builder<'a> { kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), }; let builder = &builder; @@ -383,6 +386,7 @@ impl<'a> Builder<'a> { kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), }; if kind == Kind::Dist { @@ -662,6 +666,10 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_ON_FAIL", on_fail); } + if self.config.print_step_timings { + cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1"); + } + cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity)); // Throughout the build Cargo can execute a number of build scripts @@ -818,7 +826,24 @@ impl<'a> Builder<'a> { self.build.verbose(&format!("{}> {:?}", " ".repeat(stack.len()), step)); stack.push(Box::new(step.clone())); } - let out = step.clone().run(self); + + let (out, dur) = { + let start = Instant::now(); + let zero = Duration::new(0, 0); + let parent = self.time_spent_on_dependencies.replace(zero); + let out = step.clone().run(self); + let dur = start.elapsed(); + let deps = self.time_spent_on_dependencies.replace(parent + dur); + (out, dur - deps) + }; + + if self.build.config.print_step_timings && dur > Duration::from_millis(100) { + println!("[TIMING] {:?} -- {}.{:03}", + step, + dur.as_secs(), + dur.subsec_nanos() / 1_000_000); + } + { let mut stack = self.stack.borrow_mut(); let cur_step = stack.pop().expect("step stack empty"); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 920a8ffc2fc86..3ef4b0f8ae7ac 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -121,6 +121,7 @@ pub struct Config { pub quiet_tests: bool, pub test_miri: bool, pub save_toolstates: Option, + pub print_step_timings: bool, // Fallback musl-root for all targets pub musl_root: Option, @@ -204,6 +205,7 @@ struct Build { openssl_static: Option, configure_args: Option>, local_rebuild: Option, + print_step_timings: Option, } /// TOML representation of various global install decisions. @@ -413,6 +415,7 @@ impl Config { set(&mut config.openssl_static, build.openssl_static); set(&mut config.configure_args, build.configure_args); set(&mut config.local_rebuild, build.local_rebuild); + set(&mut config.print_step_timings, build.print_step_timings); config.verbose = cmp::max(config.verbose, flags.verbose); if let Some(ref install) = toml.install { diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a92..9a26043c92c13 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -25,6 +25,8 @@ source "$ci_dir/shared.sh" if [ "$TRAVIS" == "true" ] && [ "$TRAVIS_BRANCH" != "auto" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-quiet-tests" +else + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings" fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache" From 859640a3ca99490ea7415449d84ccf87ee7c439c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 20 Mar 2018 15:33:22 +0100 Subject: [PATCH 152/546] Run the `run-make` tests last, so more tests run on Windows when `make` is unavailable --- src/bootstrap/builder.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437eef..07026cbe2650c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -308,12 +308,14 @@ impl<'a> Builder<'a> { test::UiFullDeps, test::RunPassFullDeps, test::RunFailFullDeps, test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty, test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, - test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake, + test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, test::TheBook, test::UnstableBook, - test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), + test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme, + // Run run-make last, since these won't pass without make on Windows + test::RunMake), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, From de9e6652480ad3de5f6dc52348f8e51865d7cf69 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:11:26 +0000 Subject: [PATCH 153/546] Improve comments for Rule Implemented-From-Impl --- src/librustc_traits/lowering.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index c9666f55d440e..a69f9988f3713 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -118,15 +118,24 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId return Lrc::new(vec![]); } - // Rule Implemented-From-Impl + // Rule Implemented-From-Impl (see rustc guide) // - // (see rustc guide) + // `impl Trait for A0 where WC { .. }` + // + // ``` + // forall { + // Implemented(A0: Trait) :- WC + // } + // ``` let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); - let trait_ref = ty::TraitPredicate { trait_ref }.lower(); + // `Implemented(A0: Trait)` + let trait_pred = ty::TraitPredicate { trait_ref }.lower(); + // `WC` let where_clauses = tcx.predicates_of(def_id).predicates.lower(); - let clause = Clause::Implies(where_clauses, trait_ref); + // `Implemented(A0: Trait) :- WC` + let clause = Clause::Implies(where_clauses, trait_pred); Lrc::new(vec![clause]) } From b8c75d98f9c3fe01b23f50c42b36b491e256c7a1 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:13:44 +0000 Subject: [PATCH 154/546] Implement Rule Implemented-From-Env This extends the Chalk lowering pass with the "Implemented-From-Env" rule for generating program clauses from a trait definition as part of #49177. --- src/librustc_traits/lowering.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index a69f9988f3713..1092e826a35f9 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -12,6 +12,7 @@ use rustc::hir::{self, ImplPolarity}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::ty::{self, TyCtxt}; +use rustc::ty::subst::Substs; use rustc::traits::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom}; use syntax::ast; use rustc_data_structures::sync::Lrc; @@ -104,6 +105,7 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let item = tcx.hir.expect_item(node_id); match item.node { + hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id), hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), // FIXME: other constructions e.g. traits, associated types... @@ -111,6 +113,36 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI } } +fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) + -> Lrc>> +{ + // Rule Implemented-From-Env (see rustc guide) + // + // `trait Trait where WC { .. } // P0 == Self` + // + // ``` + // forall { + // Implemented(Self: Trait) :- FromEnv(Self: Trait) + // } + // ``` + + // `Self: Trait` + let trait_pred = ty::TraitPredicate { + trait_ref: ty::TraitRef { + def_id, + substs: Substs::identity_for_item(tcx, def_id) + } + }; + // `FromEnv(Self: Trait)` + let from_env = Goal::DomainGoal(DomainGoal::FromEnv(trait_pred.lower())); + // `Implemented(Self: Trait)` + let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred)); + + // `Implemented(Self: Trait) :- FromEnv(Self: Trait)` + let clause = Clause::Implies(vec![from_env], impl_trait); + Lrc::new(vec![clause]) +} + fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Lrc>> { From 7791995ad5200b65cd9c8391703a76a18f492664 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:23:54 +0000 Subject: [PATCH 155/546] Add unit test for Implemented-From-Env --- src/test/ui/chalkify/lower_trait.rs | 22 ++++++++++++++++++++++ src/test/ui/chalkify/lower_trait.stderr | 8 ++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/chalkify/lower_trait.rs create mode 100644 src/test/ui/chalkify/lower_trait.stderr diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs new file mode 100644 index 0000000000000..010cb77edc3f1 --- /dev/null +++ b/src/test/ui/chalkify/lower_trait.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] + +#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo) :- +trait Foo { + fn s(S) -> S; + fn t(T) -> T; + fn u(U) -> U; +} + +fn main() { + println!("hello"); +} diff --git a/src/test/ui/chalkify/lower_trait.stderr b/src/test/ui/chalkify/lower_trait.stderr new file mode 100644 index 0000000000000..6da1e2fd8edd8 --- /dev/null +++ b/src/test/ui/chalkify/lower_trait.stderr @@ -0,0 +1,8 @@ +error: Implemented(Self: Foo) :- FromEnv(Self: Foo). + --> $DIR/lower_trait.rs:13:1 + | +LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo) :- + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From df76629da77b58cd9a63d41b7bc1cc987dcc2bb8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 20 Mar 2018 17:14:33 +0100 Subject: [PATCH 156/546] Remove outdated comment --- src/librustc/ty/sty.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bb5c7b5fd2a5e..3fe310c54bfe1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1667,7 +1667,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub struct Const<'tcx> { pub ty: Ty<'tcx>, - // FIXME(eddyb) Replace this with a miri value. pub val: ConstVal<'tcx>, } From 5e93394d321823ec2f54e130150791ab95b6f755 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 11:18:42 -0500 Subject: [PATCH 157/546] talk about --display-warnings --- src/doc/rustdoc/src/unstable-features.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 93489f89626fe..6a786c1985142 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -329,3 +329,19 @@ When rendering docs, `rustdoc` creates several CSS and JavaScript files as part all these files are linked from every page, changing where they are can be cumbersome if you need to specially cache them. This flag will rename all these files in the output to include the suffix in the filename. For example, `main.css` would become `main-suf.css` with the above command. + +### `--display-warnings`: display warnings when documenting or running documentation tests + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --display-warnings +$ rustdoc --test src/lib.rs -Z unstable-options --display-warnings +``` + +The intent behind this flag is to allow the user to see warnings that occur within their library or +their documentation tests, which are usually suppressed. However, [due to a +bug][issue-display-warnings], this flag doesn't 100% work as intended. See the linked issue for +details. + +[issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574 From 83e9f395d17afc95d259febe8d675084f1baf497 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 11:23:48 -0500 Subject: [PATCH 158/546] talk about force-unstable-if-unmarked --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 6a786c1985142..ac69cc1007d80 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -345,3 +345,16 @@ bug][issue-display-warnings], this flag doesn't 100% work as intended. See the l details. [issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574 + +### `-Z force-unstable-if-unmarked` + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z force-unstable-if-unmarked +``` + +This is an internal flag intended for the standard library and compiler that applies an +`#[unstable]` attribute to any dependent crate that doesn't have another stability attribute. This +allows `rustdoc` to be able to generate documentation for the compiler crates and the standard +library, as an equivalent command-line argument is provided to `rustc` when building those crates. From 3c8d55549728ec117fb6e3de93ce3d96fb6622d4 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:30:06 -0700 Subject: [PATCH 159/546] rename epoch to edition --- src/librustc/lint/context.rs | 12 ++--- src/librustc/lint/mod.rs | 20 ++++----- src/librustc/session/config.rs | 24 +++++----- src/librustc/session/mod.rs | 10 ++--- src/librustc_driver/driver.rs | 2 +- src/librustc_lint/lib.rs | 34 +++++++------- src/librustc_typeck/check/method/probe.rs | 2 +- src/libsyntax/config.rs | 6 +-- src/libsyntax/{epoch.rs => edition.rs} | 44 +++++++++---------- src/libsyntax/feature_gate.rs | 20 ++++----- src/libsyntax/lib.rs | 2 +- ....rs => edition-raw-pointer-method-2015.rs} | 4 +- ....rs => edition-raw-pointer-method-2018.rs} | 4 +- src/test/run-pass/dyn-trait.rs | 2 +- src/test/run-pass/epoch-gate-feature.rs | 2 +- ...ference-variable-behind-raw-pointer.stderr | 2 +- 16 files changed, 95 insertions(+), 95 deletions(-) rename src/libsyntax/{epoch.rs => edition.rs} (56%) rename src/test/compile-fail/{epoch-raw-pointer-method-2015.rs => edition-raw-pointer-method-2015.rs} (85%) rename src/test/compile-fail/{epoch-raw-pointer-method-2018.rs => edition-raw-pointer-method-2018.rs} (85%) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4fa6594df169c..936aa71f16cea 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -41,7 +41,7 @@ use util::nodemap::FxHashMap; use std::default::Default as StdDefault; use std::cell::{Ref, RefCell}; use syntax::ast; -use syntax::epoch; +use syntax::edition; use syntax_pos::{MultiSpan, Span}; use errors::DiagnosticBuilder; use hir; @@ -103,9 +103,9 @@ pub struct FutureIncompatibleInfo { pub id: LintId, /// e.g., a URL for an issue/PR/RFC or error code pub reference: &'static str, - /// If this is an epoch fixing lint, the epoch in which + /// If this is an edition fixing lint, the edition in which /// this lint becomes obsolete - pub epoch: Option, + pub edition: Option, } /// The target of the `by_name` map, which accounts for renaming/deprecation. @@ -201,11 +201,11 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for epoch in epoch::ALL_EPOCHS { - let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id) + for edition in edition::ALL_EPOCHS { + let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, epoch.lint_name(), lints) + self.register_group(sess, false, edition.lint_name(), lints) } } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7c103dc272109..cd038d067a1fd 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -42,7 +42,7 @@ use session::{Session, DiagnosticMessageId}; use std::hash; use syntax::ast; use syntax::codemap::MultiSpan; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::symbol::Symbol; use syntax::visit as ast_visit; use syntax_pos::Span; @@ -77,8 +77,8 @@ pub struct Lint { /// e.g. "imports that are never used" pub desc: &'static str, - /// Deny lint after this epoch - pub epoch_deny: Option, + /// Deny lint after this edition + pub edition_deny: Option, } impl Lint { @@ -88,8 +88,8 @@ impl Lint { } pub fn default_level(&self, session: &Session) -> Level { - if let Some(epoch_deny) = self.epoch_deny { - if session.epoch() >= epoch_deny { + if let Some(edition_deny) = self.edition_deny { + if session.edition() >= edition_deny { return Level::Deny } } @@ -100,12 +100,12 @@ impl Lint { /// Declare a static item of type `&'static Lint`. #[macro_export] macro_rules! declare_lint { - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $edition: expr) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: Some($epoch) + edition_deny: Some($edition) }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( @@ -113,7 +113,7 @@ macro_rules! declare_lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: None, + edition_deny: None, }; ); } @@ -499,8 +499,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, // Check for future incompatibility lints and issue a stronger warning. let lints = sess.lint_store.borrow(); if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) { - let future = if let Some(epoch) = future_incompatible.epoch { - format!("the {} epoch", epoch) + let future = if let Some(edition) = future_incompatible.edition { + format!("the {} edition", edition) } else { "a future release".to_owned() }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0d91074e946bd..4ba634f8b25cd 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -28,7 +28,7 @@ use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; use syntax::codemap::{FileName, FilePathMapping}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -771,7 +771,7 @@ macro_rules! options { Some("`string` or `string=string`"); pub const parse_lto: Option<&'static str> = Some("one of `thin`, `fat`, or omitted"); - pub const parse_epoch: Option<&'static str> = + pub const parse_edition: Option<&'static str> = Some("one of: `2015`, `2018`"); } @@ -780,7 +780,7 @@ macro_rules! options { use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; - use syntax::epoch::Epoch; + use syntax::edition::Edition; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -983,11 +983,11 @@ macro_rules! options { true } - fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool { + fn parse_edition(slot: &mut Edition, v: Option<&str>) -> bool { match v { Some(s) => { - let epoch = s.parse(); - if let Ok(parsed) = epoch { + let edition = s.parse(); + if let Ok(parsed) = edition { *slot = parsed; true } else { @@ -1280,10 +1280,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, `everybody_loops` (all function bodies replaced with `loop {}`), `hir` (the HIR), `hir,identified`, or `hir,typed` (HIR with types for each node)."), - epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED], - "The epoch to build Rust with. Newer epochs may include features - that require breaking changes. The default epoch is 2015 (the first - epoch). Crates compiled with different epochs can be linked together."), + edition: Edition = (Edition::Edition2015, parse_edition, [TRACKED], + "The edition to build Rust with. Newer editions may include features + that require breaking changes. The default edition is 2015 (the first + edition). Crates compiled with different editions can be linked together."), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], @@ -2258,7 +2258,7 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{CrateType, DebugInfoLevel, Epoch, ErrorOutputType, Lto, OptLevel, OutputTypes, + use super::{CrateType, DebugInfoLevel, Edition, ErrorOutputType, Lto, OptLevel, OutputTypes, Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2320,7 +2320,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Epoch); + impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3f52ecfc0999b..556255e06ed00 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -31,7 +31,7 @@ use rustc_data_structures::sync::{Lrc, Lock}; use syntax::ast::NodeId; use errors::{self, DiagnosticBuilder, DiagnosticId}; use errors::emitter::{Emitter, EmitterWriter}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::json::JsonEmitter; use syntax::feature_gate; use syntax::symbol::Symbol; @@ -976,13 +976,13 @@ impl Session { self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code) } - /// Are we allowed to use features from the Rust 2018 epoch? + /// Are we allowed to use features from the Rust 2018 edition? pub fn rust_2018(&self) -> bool { - self.opts.debugging_opts.epoch >= Epoch::Epoch2018 + self.opts.debugging_opts.edition >= Edition::Edition2018 } - pub fn epoch(&self) -> Epoch { - self.opts.debugging_opts.epoch + pub fn edition(&self) -> Edition { + self.opts.debugging_opts.edition } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f2fe6542db171..a3115544f30b9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -648,7 +648,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, { let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test, - sess.opts.debugging_opts.epoch); + sess.opts.debugging_opts.edition); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ce896bfb701ba..59d2d3e8fdc07 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -48,7 +48,7 @@ use rustc::session; use rustc::util; use session::Session; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -197,82 +197,82 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), reference: "issue #35203 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), reference: "issue #36887 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), reference: "issue #37872 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_IMPORTS), reference: "issue #38260 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), reference: "issue #39207 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), reference: "issue #41620 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ANONYMOUS_PARAMETERS), reference: "issue #41686 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), reference: "issue #42238 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), reference: "issue #42868 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_PACKED_BORROWS), reference: "issue #46043 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS), reference: "issue #46205 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(TYVAR_BEHIND_RAW_POINTER), reference: "issue #46906 ", - epoch: Some(Epoch::Epoch2018), + edition: Some(Edition::Edition2018), } ]); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4d344eb279903..c7921d2bd4588 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -326,7 +326,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if reached_raw_pointer && !self.tcx.features().arbitrary_self_types { // this case used to be allowed by the compiler, - // so we do a future-compat lint here for the 2015 epoch + // so we do a future-compat lint here for the 2015 edition // (see https://github.com/rust-lang/rust/issues/46906) if self.tcx.sess.rust_2018() { span_err!(self.tcx.sess, span, E0908, diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 6013c20daf235..56b1306e5b33f 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -13,7 +13,7 @@ use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features use {fold, attr}; use ast; use codemap::Spanned; -use epoch::Epoch; +use edition::Edition; use parse::{token, ParseSess}; use ptr::P; @@ -27,7 +27,7 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch) +pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, edition: Edition) -> (ast::Crate, Features) { let features; { @@ -47,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoc return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, epoch); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/epoch.rs b/src/libsyntax/edition.rs similarity index 56% rename from src/libsyntax/epoch.rs rename to src/libsyntax/edition.rs index 32cbc79c550e3..12ac6410ce193 100644 --- a/src/libsyntax/epoch.rs +++ b/src/libsyntax/edition.rs @@ -11,58 +11,58 @@ use std::fmt; use std::str::FromStr; -/// The epoch of the compiler (RFC 2052) +/// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)] #[non_exhaustive] -pub enum Epoch { - // epochs must be kept in order, newest to oldest +pub enum Edition { + // editions must be kept in order, newest to oldest - /// The 2015 epoch - Epoch2015, - /// The 2018 epoch - Epoch2018, + /// The 2015 edition + Edition2015, + /// The 2018 edition + Edition2018, - // when adding new epochs, be sure to update: + // when adding new editions, be sure to update: // - // - the list in the `parse_epoch` static in librustc::session::config + // - the list in the `parse_edition` static in librustc::session::config // - add a `rust_####()` function to the session // - update the enum in Cargo's sources as well // - // When -Zepoch becomes --epoch, there will - // also be a check for the epoch being nightly-only + // When -Zedition becomes --edition, there will + // also be a check for the edition being nightly-only // somewhere. That will need to be updated - // whenever we're stabilizing/introducing a new epoch + // whenever we're stabilizing/introducing a new edition // as well as changing the default Cargo template. } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018]; +pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; -impl fmt::Display for Epoch { +impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { - Epoch::Epoch2015 => "2015", - Epoch::Epoch2018 => "2018", + Edition::Edition2015 => "2015", + Edition::Edition2018 => "2018", }; write!(f, "{}", s) } } -impl Epoch { +impl Edition { pub fn lint_name(&self) -> &'static str { match *self { - Epoch::Epoch2015 => "epoch_2015", - Epoch::Epoch2018 => "epoch_2018", + Edition::Edition2015 => "edition_2015", + Edition::Edition2018 => "edition_2018", } } } -impl FromStr for Epoch { +impl FromStr for Edition { type Err = (); fn from_str(s: &str) -> Result { match s { - "2015" => Ok(Epoch::Epoch2015), - "2018" => Ok(Epoch::Epoch2018), + "2015" => Ok(Edition::Edition2015), + "2018" => Ok(Edition::Edition2018), _ => Err(()) } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 915396d29fe26..8feb8d6a4020d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,7 +28,7 @@ use self::AttributeGate::*; use abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; -use epoch::Epoch; +use edition::Edition; use codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; @@ -55,13 +55,13 @@ macro_rules! set { } macro_rules! declare_features { - ($((active, $feature: ident, $ver: expr, $issue: expr, $epoch: expr),)+) => { + ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => { /// Represents active features that are currently being implemented or /// currently being considered for addition/removal. const ACTIVE_FEATURES: &'static [(&'static str, &'static str, Option, - Option, fn(&mut Features, Span))] = - &[$((stringify!($feature), $ver, $issue, $epoch, set!($feature))),+]; + Option, fn(&mut Features, Span))] = + &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+]; /// A set of features to be used by later passes. #[derive(Clone)] @@ -402,7 +402,7 @@ declare_features! ( (active, match_default_bindings, "1.22.0", Some(42640), None), // Trait object syntax with `dyn` prefix - (active, dyn_trait, "1.22.0", Some(44662), Some(Epoch::Epoch2018)), + (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), // `crate` as visibility modifier, synonymous to `pub(crate)` (active, crate_visibility_modifier, "1.23.0", Some(45388), None), @@ -1800,16 +1800,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - epoch: Epoch) -> Features { + edition: Edition) -> Features { let mut features = Features::new(); let mut feature_checker = FeatureChecker::default(); - for &(.., f_epoch, set) in ACTIVE_FEATURES.iter() { - if let Some(f_epoch) = f_epoch { - if epoch >= f_epoch { + for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { + if let Some(f_edition) = f_edition { + if edition >= f_edition { // FIXME(Manishearth) there is currently no way to set - // lang features by epoch + // lang features by edition set(&mut features, DUMMY_SP); } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 5f58b3bc3a050..74f1ee373ec63 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -145,7 +145,7 @@ pub mod codemap; #[macro_use] pub mod config; pub mod entry; -pub mod epoch; +pub mod edition; pub mod feature_gate; pub mod fold; pub mod parse; diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/edition-raw-pointer-method-2015.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2015.rs rename to src/test/compile-fail/edition-raw-pointer-method-2015.rs index 6aa83a38b7ee9..fdc9b4f704cd1 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2015.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2015 -Zunstable-options +// compile-flags: -Zedition=2015 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2018.rs rename to src/test/compile-fail/edition-raw-pointer-method-2018.rs index c4815de2306e9..58b34591029ba 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2018 -Zunstable-options +// compile-flags: -Zedition=2018 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs index fdec6a26ac945..399823ec92d0c 100644 --- a/src/test/run-pass/dyn-trait.rs +++ b/src/test/run-pass/dyn-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty `dyn ::foo` parses differently in the current epoch +// ignore-pretty `dyn ::foo` parses differently in the current edition #![feature(dyn_trait)] diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs index 37d092c06e02b..f3d8f216e1132 100644 --- a/src/test/run-pass/epoch-gate-feature.rs +++ b/src/test/run-pass/epoch-gate-feature.rs @@ -11,7 +11,7 @@ // Checks if the correct registers are being used to pass arguments // when the sysv64 ABI is specified. -// compile-flags: -Zepoch=2018 +// compile-flags: -Zedition=2018 pub trait Foo {} diff --git a/src/test/ui/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference-variable-behind-raw-pointer.stderr index eb40151615dad..fe6dc0b07482f 100644 --- a/src/test/ui/inference-variable-behind-raw-pointer.stderr +++ b/src/test/ui/inference-variable-behind-raw-pointer.stderr @@ -5,6 +5,6 @@ LL | if data.is_null() {} | ^^^^^^^ | = note: #[warn(tyvar_behind_raw_pointer)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 epoch! + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 From 11f14060a4da7776c5f56e7dc53cc9545e4ab25f Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:56:13 -0700 Subject: [PATCH 160/546] change all appropriate EPOCH to EDITION --- src/librustc/lint/context.rs | 2 +- src/libsyntax/edition.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 936aa71f16cea..3c833251f72a7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -201,7 +201,7 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for edition in edition::ALL_EPOCHS { + for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index 12ac6410ce193..61246d4493ca3 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -36,7 +36,7 @@ pub enum Edition { } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 53c6d9b49764a05cc87a06888dfa3e24999ff4ce Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Mar 2018 19:21:38 +0100 Subject: [PATCH 161/546] Don't check interpret_interner when accessing a static to fix miri mutable statics --- src/librustc_mir/interpret/place.rs | 32 +++++++++-------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index d27de3ef6bfc4..456f5fd75db09 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -197,29 +197,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { }, Static(ref static_) => { - let alloc = self - .tcx - .interpret_interner - .get_cached(static_.def_id); let layout = self.layout_of(self.place_ty(mir_place))?; - if let Some(alloc) = alloc { - Place::Ptr { - ptr: MemoryPointer::new(alloc, 0).into(), - align: layout.align, - extra: PlaceExtra::None, - } - } else { - let instance = ty::Instance::mono(*self.tcx, static_.def_id); - let cid = GlobalId { - instance, - promoted: None - }; - let alloc = Machine::init_static(self, cid)?; - Place::Ptr { - ptr: MemoryPointer::new(alloc, 0).into(), - align: layout.align, - extra: PlaceExtra::None, - } + let instance = ty::Instance::mono(*self.tcx, static_.def_id); + let cid = GlobalId { + instance, + promoted: None + }; + let alloc = Machine::init_static(self, cid)?; + Place::Ptr { + ptr: MemoryPointer::new(alloc, 0).into(), + align: layout.align, + extra: PlaceExtra::None, } } From 72334fee6fad3c51a036d7f592915ea472959714 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 14:19:16 -0500 Subject: [PATCH 162/546] typeck: Report main return type errors on return type span --- src/librustc_typeck/check/mod.rs | 3 ++- .../termination-trait-main-wrong-type.rs | 3 +-- .../termination-trait-main-wrong-type.stderr | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) rename src/test/{compile-fail => ui}/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs (80%) create mode 100644 src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 42bf516a0afa5..a951fa7eb220e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1114,8 +1114,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, Some(config::EntryMain) => { let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); let trait_ref = ty::TraitRef::new(term_id, substs); + let return_ty_span = decl.output.span(); let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); + return_ty_span, fn_id, ObligationCauseCode::MainFunctionType); inherited.register_predicate( traits::Obligation::new( diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs similarity index 80% rename from src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs rename to src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 5f4ccf2b5862e..425f51ca2fb54 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `char -fn main() -> char { +fn main() -> char { //~ ERROR ' ' } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr new file mode 100644 index 0000000000000..d09aac3ac2f27 --- /dev/null +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `char: std::process::Termination` is not satisfied + --> $DIR/termination-trait-main-wrong-type.rs:11:14 + | +LL | fn main() -> char { //~ ERROR + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | + = help: the trait `std::process::Termination` is not implemented for `char` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From a9cbfaa29687395452208a823502cc906a493ae2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 14 Mar 2018 17:29:09 -0400 Subject: [PATCH 163/546] rewrite to use a custom folder --- src/librustc/infer/anon_types/mod.rs | 92 +++++++++++++++------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index eb26f0c1188bf..6a4f4072f53dc 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -14,8 +14,8 @@ use infer::outlives::free_region_map::FreeRegionRelations; use rustc_data_structures::fx::FxHashMap; use syntax::ast; use traits::{self, PredicateObligation}; -use ty::{self, Ty}; -use ty::fold::{BottomUpFolder, TypeFoldable}; +use ty::{self, Ty, TyCtxt}; +use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; use ty::outlives::Component; use ty::subst::{Kind, UnpackedKind, Substs}; use util::nodemap::DefIdMap; @@ -458,55 +458,63 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = gcx.fold_regions(&instantiated_ty, &mut false, |r, _| { - match *r { - // 'static and early-bound regions are valid. - ty::ReStatic | ty::ReEmpty => 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(UnpackedKind::Lifetime(r1)) = map.get(&r.into()) - .map(|k| k.unpack()) { - 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 - }, - } - }); - + let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper { tcx: self.tcx, map }); debug!( "infer_anon_definition_from_instantiation: definition_ty={:?}", definition_ty ); + // We can unwrap here because our reverse mapper always + // produces things with 'gcx lifetime, though the type folder + // obscures that. + let definition_ty = gcx.lift(&definition_ty).unwrap(); + definition_ty } } +struct ReverseMapper<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + map: FxHashMap, Kind<'gcx>> +} + +impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> { + fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + // ignore bound regions that appear in the type (e.g., this + // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. + if let ty::ReLateBound(..) = *r { + return r; + } + + match self.map.get(&r.into()).map(|k| k.unpack()) { + Some(UnpackedKind::Lifetime(r1)) => r1, + Some(u) => panic!("region mapped to unexpected kind: {:?}", u), + None => { + // 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. + self.tcx.types.re_empty + } + } + } +} + struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, parent_def_id: DefId, From 25abe4830769e7bfceff75dc27d443c6d625fe13 Mon Sep 17 00:00:00 2001 From: Mrowqa Date: Tue, 20 Mar 2018 22:12:31 +0100 Subject: [PATCH 164/546] Pass attributes to hir::TyParam --- src/librustc/hir/lowering.rs | 1 + src/librustc/hir/map/mod.rs | 1 + src/librustc/hir/mod.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1439410f7e9aa..a35af56bd97b1 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1585,6 +1585,7 @@ impl<'a> LoweringContext<'a> { .filter(|attr| attr.check_name("rustc_synthetic")) .map(|_| hir::SyntheticTyParamKind::ImplTrait) .nth(0), + attrs: self.lower_attrs(&tp.attrs), } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 61fae4609d54f..e8bcbfbb77a17 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -962,6 +962,7 @@ impl<'hir> Map<'hir> { Some(NodeField(ref f)) => Some(&f.attrs[..]), Some(NodeExpr(ref e)) => Some(&*e.attrs), Some(NodeStmt(ref s)) => Some(s.node.attrs()), + Some(NodeTyParam(tp)) => Some(&tp.attrs[..]), // unit/tuple structs take the attributes straight from // the struct definition. Some(NodeStructCtor(_)) => { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 5ae84f5685eaf..d6810b2468bcc 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -414,6 +414,7 @@ pub struct TyParam { pub span: Span, pub pure_wrt_drop: bool, pub synthetic: Option, + pub attrs: HirVec, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] From 20e65f11f3bb0538c5676425e74b593676bd0f12 Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 21 Mar 2018 02:59:07 +0800 Subject: [PATCH 165/546] Apply a fix to travis-ci/dpl#788 manually until dpl 1.9.5 is released. --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 41ea0c9afa87c..b2aba305aedc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -318,6 +318,8 @@ before_deploy: deploy: - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -334,6 +336,8 @@ deploy: # this is the same as the above deployment provider except that it uploads to # a slightly different directory and has a different trigger - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -351,6 +355,8 @@ deploy: # try branch. Travis does not appear to provide a way to use "or" in these # conditions. - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -365,6 +371,8 @@ deploy: condition: $DEPLOY = 1 - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy From 1f51840db0d846c2370f7d726eb8e41424431850 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Mar 2018 23:08:04 +0100 Subject: [PATCH 166/546] Propose a variant if it is an enum for E0599 --- src/librustc_typeck/check/method/suggest.rs | 17 +++++++++++++++-- src/test/ui/issue-23217.stderr | 2 ++ src/test/ui/issue-28971.stderr | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d6409..06bec8f6ff659 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -22,12 +22,14 @@ use rustc::traits::{Obligation, SelectionContext}; use util::nodemap::FxHashSet; use syntax::ast; +use syntax::util::lev_distance::find_best_match_for_name; use errors::DiagnosticBuilder; use syntax_pos::Span; use rustc::hir; use rustc::hir::print; use rustc::infer::type_variable::TypeVariableOrigin; +use rustc::ty::TyAdt; use std::cell; use std::cmp::Ordering; @@ -179,9 +181,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, '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 mut suggestion = None; let type_str = if is_method { "method" } else if actual.is_enum() { + if let TyAdt(ref adt_def, _) = actual.sty { + let names = adt_def.variants.iter().map(|s| &s.name); + suggestion = find_best_match_for_name(names, + &item_name.as_str(), + None); + } "variant" } else { match (item_name.as_str().chars().next(), actual.is_fresh_ty()) { @@ -256,7 +265,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.emit(); return; } else { - struct_span_err!( + let mut err = struct_span_err!( tcx.sess, span, E0599, @@ -264,7 +273,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { type_str, item_name, ty_string - ) + ); + if let Some(suggestion) = suggestion { + err.note(&format!("did you mean `{}::{}`?", type_str, suggestion)); + } + err } } else { tcx.sess.diagnostic().struct_dummy() diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr index be9ec9d73c21c..d542a10e9b605 100644 --- a/src/test/ui/issue-23217.stderr +++ b/src/test/ui/issue-23217.stderr @@ -5,6 +5,8 @@ LL | pub enum SomeEnum { | ----------------- variant `A` not found here LL | B = SomeEnum::A, | ^^^^^^^^^^^ variant not found in `SomeEnum` + | + = note: did you mean `variant::B`? error: aborting due to previous error diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr index 81d8d97963bd0..df114351ff571 100644 --- a/src/test/ui/issue-28971.stderr +++ b/src/test/ui/issue-28971.stderr @@ -6,6 +6,8 @@ LL | enum Foo { ... LL | Foo::Baz(..) => (), | ^^^^^^^^^^^^ variant not found in `Foo` + | + = note: did you mean `variant::Bar`? error: aborting due to previous error From 57896abc38f56dce27ca9d4642c18f44be8db620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 20 Mar 2018 00:48:41 +0100 Subject: [PATCH 167/546] Make resuming generators unsafe instead of the creation of immovable generators. Fixes #47787 --- .../src/language-features/generators.md | 20 ++++++------- src/liballoc/boxed.rs | 2 +- src/libcore/ops/generator.rs | 12 +++++--- src/librustc_mir/diagnostics.rs | 10 +++---- src/librustc_mir/transform/check_unsafety.rs | 12 ++------ src/test/run-pass/dynamic-drop.rs | 2 +- .../run-pass/generator/conditional-drop.rs | 8 +++--- src/test/run-pass/generator/control-flow.rs | 2 +- src/test/run-pass/generator/drop-env.rs | 4 +-- src/test/run-pass/generator/issue-44197.rs | 6 ++-- src/test/run-pass/generator/iterator-count.rs | 4 ++- .../generator/live-upvar-across-yield.rs | 2 +- .../run-pass/generator/nested_generators.rs | 2 +- src/test/run-pass/generator/panic-drops.rs | 4 +-- src/test/run-pass/generator/panic-safe.rs | 4 +-- .../run-pass/generator/resume-after-return.rs | 4 +-- src/test/run-pass/generator/smoke.rs | 28 +++++++++---------- .../run-pass/generator/static-generators.rs | 18 ++++++------ .../run-pass/generator/xcrate-reachable.rs | 2 +- src/test/run-pass/generator/xcrate.rs | 6 ++-- src/test/ui/generator/borrowing.rs | 2 +- src/test/ui/generator/borrowing.stderr | 10 +++---- src/test/ui/generator/dropck.rs | 2 +- src/test/ui/generator/sized-yield.rs | 2 +- src/test/ui/generator/sized-yield.stderr | 6 ++-- src/test/ui/generator/unsafe-immovable.rs | 17 ----------- src/test/ui/generator/unsafe-immovable.stderr | 11 -------- .../ui/generator/yield-while-iterating.rs | 6 ++-- .../generator/yield-while-local-borrowed.rs | 6 ++-- .../generator/yield-while-ref-reborrowed.rs | 6 ++-- 30 files changed, 96 insertions(+), 124 deletions(-) delete mode 100644 src/test/ui/generator/unsafe-immovable.rs delete mode 100644 src/test/ui/generator/unsafe-immovable.stderr diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md index e8e2132dca254..8e888de90a951 100644 --- a/src/doc/unstable-book/src/language-features/generators.md +++ b/src/doc/unstable-book/src/language-features/generators.md @@ -36,11 +36,11 @@ fn main() { return "foo" }; - match generator.resume() { + match unsafe { generator.resume() } { GeneratorState::Yielded(1) => {} _ => panic!("unexpected value from resume"), } - match generator.resume() { + match unsafe { generator.resume() } { GeneratorState::Complete("foo") => {} _ => panic!("unexpected value from resume"), } @@ -69,9 +69,9 @@ fn main() { }; println!("1"); - generator.resume(); + unsafe { generator.resume() }; println!("3"); - generator.resume(); + unsafe { generator.resume() }; println!("5"); } ``` @@ -92,7 +92,7 @@ The `Generator` trait in `std::ops` currently looks like: pub trait Generator { type Yield; type Return; - fn resume(&mut self) -> GeneratorState; + unsafe fn resume(&mut self) -> GeneratorState; } ``` @@ -175,8 +175,8 @@ fn main() { return ret }; - generator.resume(); - generator.resume(); + unsafe { generator.resume() }; + unsafe { generator.resume() }; } ``` @@ -200,7 +200,7 @@ fn main() { type Yield = i32; type Return = &'static str; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { use std::mem; match mem::replace(self, __Generator::Done) { __Generator::Start(s) => { @@ -223,8 +223,8 @@ fn main() { __Generator::Start(ret) }; - generator.resume(); - generator.resume(); + unsafe { generator.resume() }; + unsafe { generator.resume() }; } ``` diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index b776556d59f11..a86ab87ec185f 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -892,7 +892,7 @@ impl Generator for Box { type Yield = T::Yield; type Return = T::Return; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { (**self).resume() } } diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs index dc7669d195c13..4b70c5398be4f 100644 --- a/src/libcore/ops/generator.rs +++ b/src/libcore/ops/generator.rs @@ -56,11 +56,11 @@ pub enum GeneratorState { /// return "foo" /// }; /// -/// match generator.resume() { +/// match unsafe { generator.resume() } { /// GeneratorState::Yielded(1) => {} /// _ => panic!("unexpected return from resume"), /// } -/// match generator.resume() { +/// match unsafe { generator.resume() } { /// GeneratorState::Complete("foo") => {} /// _ => panic!("unexpected return from resume"), /// } @@ -98,6 +98,10 @@ pub trait Generator { /// generator will continue executing until it either yields or returns, at /// which point this function will return. /// + /// The function is unsafe because it can be used on an immovable generator. + /// After such a call, the immovable generator must not move again, but + /// this is not enforced by the compiler. + /// /// # Return value /// /// The `GeneratorState` enum returned from this function indicates what @@ -116,7 +120,7 @@ pub trait Generator { /// been returned previously. While generator literals in the language are /// guaranteed to panic on resuming after `Complete`, this is not guaranteed /// for all implementations of the `Generator` trait. - fn resume(&mut self) -> GeneratorState; + unsafe fn resume(&mut self) -> GeneratorState; } #[unstable(feature = "generator_trait", issue = "43122")] @@ -125,7 +129,7 @@ impl<'a, T> Generator for &'a mut T { type Yield = T::Yield; type Return = T::Return; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { (**self).resume() } } diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 2000ebea25d7e..4f36c3888b961 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -2247,7 +2247,7 @@ let mut b = || { yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); }; -b.resume(); +unsafe { b.resume() }; ``` At present, it is not permitted to have a yield that occurs while a @@ -2265,7 +2265,7 @@ let mut b = || { yield (); println!("{}", a); }; -b.resume(); +unsafe { b.resume() }; ``` This is a very simple case, of course. In more complex cases, we may @@ -2283,7 +2283,7 @@ let mut b = || { yield x; // ...when this yield occurs. } }; -b.resume(); +unsafe { b.resume() }; ``` Such cases can sometimes be resolved by iterating "by value" (or using @@ -2298,7 +2298,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -b.resume(); +unsafe { b.resume() }; ``` If taking ownership is not an option, using indices can work too: @@ -2314,7 +2314,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -b.resume(); +unsafe { b.resume() }; // (*) -- Unfortunately, these temporaries are currently required. // See . diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 86d08dec2b9c3..033fb493d735c 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -125,21 +125,13 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { &AggregateKind::Array(..) | &AggregateKind::Tuple | &AggregateKind::Adt(..) => {} - &AggregateKind::Closure(def_id, _) => { + &AggregateKind::Closure(def_id, _) | + &AggregateKind::Generator(def_id, _, _) => { let UnsafetyCheckResult { violations, unsafe_blocks } = self.tcx.unsafety_check_result(def_id); self.register_violations(&violations, &unsafe_blocks); } - &AggregateKind::Generator(def_id, _, interior) => { - let UnsafetyCheckResult { - violations, unsafe_blocks - } = self.tcx.unsafety_check_result(def_id); - self.register_violations(&violations, &unsafe_blocks); - if !interior.movable { - self.require_unsafe("construction of immovable generator") - } - } } } self.super_rvalue(rvalue, location); diff --git a/src/test/run-pass/dynamic-drop.rs b/src/test/run-pass/dynamic-drop.rs index 4d0bd3f3412f1..abbce16b77cf6 100644 --- a/src/test/run-pass/dynamic-drop.rs +++ b/src/test/run-pass/dynamic-drop.rs @@ -178,7 +178,7 @@ fn generator(a: &Allocator, run_count: usize) { ); }; for _ in 0..run_count { - gen.resume(); + unsafe { gen.resume(); } } } diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs index 8329684e1a39b..3d39c46186be3 100644 --- a/src/test/run-pass/generator/conditional-drop.rs +++ b/src/test/run-pass/generator/conditional-drop.rs @@ -42,9 +42,9 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); } @@ -58,8 +58,8 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); } diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs index 60a00b4e46756..09971410e556d 100644 --- a/src/test/run-pass/generator/control-flow.rs +++ b/src/test/run-pass/generator/control-flow.rs @@ -16,7 +16,7 @@ fn finish(mut amt: usize, mut t: T) -> T::Return where T: Generator { loop { - match t.resume() { + match unsafe { t.resume() } { GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), GeneratorState::Complete(ret) => { assert_eq!(amt, 0); diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs index ac42a25899dbb..ef4dc24472e61 100644 --- a/src/test/run-pass/generator/drop-env.rs +++ b/src/test/run-pass/generator/drop-env.rs @@ -37,7 +37,7 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - drop(foo.resume()); + drop(unsafe { foo.resume() }); assert_eq!(A.load(Ordering::SeqCst), n); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); @@ -50,7 +50,7 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - drop(foo.resume()); + drop(unsafe { foo.resume() }); assert_eq!(A.load(Ordering::SeqCst), n + 1); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs index 7cb80ea8b21b7..8ce4fc6affab3 100644 --- a/src/test/run-pass/generator/issue-44197.rs +++ b/src/test/run-pass/generator/issue-44197.rs @@ -35,6 +35,8 @@ fn bar2(baz: String) -> impl Generator { } fn main() { - assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); - assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); + unsafe { + assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); + assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); + } } diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs index 9afe95f9e865c..654b18928c077 100644 --- a/src/test/run-pass/generator/iterator-count.rs +++ b/src/test/run-pass/generator/iterator-count.rs @@ -14,11 +14,13 @@ use std::ops::{GeneratorState, Generator}; struct W(T); +// This impl isn't safe in general, but the generator used in this test is movable +// so it won't cause problems. impl> Iterator for W { type Item = T::Yield; fn next(&mut self) -> Option { - match self.0.resume() { + match unsafe { self.0.resume() } { GeneratorState::Complete(..) => None, GeneratorState::Yielded(v) => Some(v), } diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs index e34b0b3100c32..28e7da232ce09 100644 --- a/src/test/run-pass/generator/live-upvar-across-yield.rs +++ b/src/test/run-pass/generator/live-upvar-across-yield.rs @@ -17,5 +17,5 @@ fn main() { let mut a = || { b(yield); }; - a.resume(); + unsafe { a.resume() }; } diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs index f70d4144a3c9e..29808da85a7a9 100644 --- a/src/test/run-pass/generator/nested_generators.rs +++ b/src/test/run-pass/generator/nested_generators.rs @@ -20,7 +20,7 @@ fn main() { yield 2; }; - match sub_generator.resume() { + match unsafe { sub_generator.resume() } { GeneratorState::Yielded(x) => { yield x; } diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs index 36e401a54bcdd..3d7b60ab6b901 100644 --- a/src/test/run-pass/generator/panic-drops.rs +++ b/src/test/run-pass/generator/panic-drops.rs @@ -42,7 +42,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 0); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); @@ -57,7 +57,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 1); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs index 0d5bae7876bd3..ace5cdde51d85 100644 --- a/src/test/run-pass/generator/panic-safe.rs +++ b/src/test/run-pass/generator/panic-safe.rs @@ -24,13 +24,13 @@ fn main() { }; let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); for _ in 0..10 { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); } diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs index 56511dcd53a6a..06e7615d26191 100644 --- a/src/test/run-pass/generator/resume-after-return.rs +++ b/src/test/run-pass/generator/resume-after-return.rs @@ -23,12 +23,12 @@ fn main() { yield; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } - match panic::catch_unwind(move || foo.resume()) { + match panic::catch_unwind(move || unsafe { foo.resume() }) { Ok(_) => panic!("generator successfully resumed"), Err(_) => {} } diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs index 8693964665d34..7395c8484c169 100644 --- a/src/test/run-pass/generator/smoke.rs +++ b/src/test/run-pass/generator/smoke.rs @@ -24,7 +24,7 @@ fn simple() { } }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -40,7 +40,7 @@ fn return_capture() { a }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -52,11 +52,11 @@ fn simple_yield() { yield; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -69,11 +69,11 @@ fn yield_capture() { yield b; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -86,11 +86,11 @@ fn simple_yield_value() { return String::from("foo") }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "bar" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -104,11 +104,11 @@ fn return_after_yield() { return a }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -156,11 +156,11 @@ fn send_and_sync() { fn send_over_threads() { let mut foo = || { yield }; thread::spawn(move || { - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -169,11 +169,11 @@ fn send_over_threads() { let a = String::from("a"); let mut foo = || { yield a }; thread::spawn(move || { - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "a" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs index 9504414d8b6f5..ebc070eee09c1 100644 --- a/src/test/run-pass/generator/static-generators.rs +++ b/src/test/run-pass/generator/static-generators.rs @@ -13,14 +13,14 @@ use std::ops::{Generator, GeneratorState}; fn main() { - let mut generator = unsafe { - static || { - let a = true; - let b = &a; - yield; - assert_eq!(b as *const _, &a as *const _); - } + let mut generator = static || { + let a = true; + let b = &a; + yield; + assert_eq!(b as *const _, &a as *const _); }; - assert_eq!(generator.resume(), GeneratorState::Yielded(())); - assert_eq!(generator.resume(), GeneratorState::Complete(())); + unsafe { + assert_eq!(generator.resume(), GeneratorState::Yielded(())); + assert_eq!(generator.resume(), GeneratorState::Complete(())); + } } diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs index dff5e08b9c20e..8eeb013314499 100644 --- a/src/test/run-pass/generator/xcrate-reachable.rs +++ b/src/test/run-pass/generator/xcrate-reachable.rs @@ -17,5 +17,5 @@ extern crate xcrate_reachable as foo; use std::ops::Generator; fn main() { - foo::foo().resume(); + unsafe { foo::foo().resume(); } } diff --git a/src/test/run-pass/generator/xcrate.rs b/src/test/run-pass/generator/xcrate.rs index dc7a6fdef9c7e..04791d5135677 100644 --- a/src/test/run-pass/generator/xcrate.rs +++ b/src/test/run-pass/generator/xcrate.rs @@ -19,18 +19,18 @@ use std::ops::{GeneratorState, Generator}; fn main() { let mut foo = xcrate::foo(); - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } let mut foo = xcrate::bar(3); - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(3) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index de10bdef4aee0..e56927d818231 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -15,7 +15,7 @@ use std::ops::Generator; fn main() { let _b = { let a = 3; - (|| yield &a).resume() + unsafe { (|| yield &a).resume() } //~^ ERROR: `a` does not live long enough }; diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr index 2a5de3790ada9..45d950b5aef64 100644 --- a/src/test/ui/generator/borrowing.stderr +++ b/src/test/ui/generator/borrowing.stderr @@ -1,10 +1,10 @@ error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:18:20 + --> $DIR/borrowing.rs:18:29 | -LL | (|| yield &a).resume() - | -- ^ borrowed value does not live long enough - | | - | capture occurs here +LL | unsafe { (|| yield &a).resume() } + | -- ^ borrowed value does not live long enough + | | + | capture occurs here LL | //~^ ERROR: `a` does not live long enough LL | }; | - borrowed value only lives until here diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs index 0b143d7f5143e..b2240fb225f58 100644 --- a/src/test/ui/generator/dropck.rs +++ b/src/test/ui/generator/dropck.rs @@ -23,6 +23,6 @@ fn main() { let _d = ref_.take(); //~ ERROR `ref_` does not live long enough yield; }; - gen.resume(); + unsafe { gen.resume(); } // drops the RefCell and then the Ref, leading to use-after-free } diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs index f38ebf8b94636..a1c8ca77e41e8 100644 --- a/src/test/ui/generator/sized-yield.rs +++ b/src/test/ui/generator/sized-yield.rs @@ -17,5 +17,5 @@ fn main() { let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied yield s[..]; }; - gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied + unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied } diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr index fc99c7e3bd747..957fac172c258 100644 --- a/src/test/ui/generator/sized-yield.stderr +++ b/src/test/ui/generator/sized-yield.stderr @@ -11,10 +11,10 @@ LL | | }; = note: the yield type of a generator must have a statically known size error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied - --> $DIR/sized-yield.rs:20:8 + --> $DIR/sized-yield.rs:20:17 | -LL | gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied - | ^^^^^^ `str` does not have a constant size known at compile-time +LL | unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` 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` diff --git a/src/test/ui/generator/unsafe-immovable.rs b/src/test/ui/generator/unsafe-immovable.rs deleted file mode 100644 index 45acbf50931bc..0000000000000 --- a/src/test/ui/generator/unsafe-immovable.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(generators)] - -fn main() { - static || { //~ ERROR: construction of immovable generator requires unsafe - yield; - }; -} diff --git a/src/test/ui/generator/unsafe-immovable.stderr b/src/test/ui/generator/unsafe-immovable.stderr deleted file mode 100644 index b2add55613d54..0000000000000 --- a/src/test/ui/generator/unsafe-immovable.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: construction of immovable generator requires unsafe function or block - --> $DIR/unsafe-immovable.rs:14:5 - | -LL | / static || { //~ ERROR: construction of immovable generator requires unsafe -LL | | yield; -LL | | }; - | |_____^ construction of immovable generator - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs index bc53448cb08e6..b8a67a0e7b65d 100644 --- a/src/test/ui/generator/yield-while-iterating.rs +++ b/src/test/ui/generator/yield-while-iterating.rs @@ -43,7 +43,7 @@ fn yield_during_iter_borrowed_slice_2() { println!("{:?}", x); } -fn yield_during_iter_borrowed_slice_3() { +unsafe fn yield_during_iter_borrowed_slice_3() { // OK to take a mutable ref to `x` and yield // up pointers from it: let mut x = vec![22_i32]; @@ -55,7 +55,7 @@ fn yield_during_iter_borrowed_slice_3() { b.resume(); } -fn yield_during_iter_borrowed_slice_4() { +unsafe fn yield_during_iter_borrowed_slice_4() { // ...but not OK to do that while reading // from `x` too let mut x = vec![22_i32]; @@ -68,7 +68,7 @@ fn yield_during_iter_borrowed_slice_4() { b.resume(); } -fn yield_during_range_iter() { +unsafe fn yield_during_range_iter() { // Should be OK. let mut b = || { let v = vec![1,2,3]; diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs index 11bd4ed05caca..3dc2650a2ecbf 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.rs +++ b/src/test/ui/generator/yield-while-local-borrowed.rs @@ -15,7 +15,7 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; -fn borrow_local_inline() { +unsafe fn borrow_local_inline() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of @@ -30,7 +30,7 @@ fn borrow_local_inline() { b.resume(); } -fn borrow_local_inline_done() { +unsafe fn borrow_local_inline_done() { // No error here -- `a` is not in scope at the point of `yield`. let mut b = move || { { @@ -41,7 +41,7 @@ fn borrow_local_inline_done() { b.resume(); } -fn borrow_local() { +unsafe fn borrow_local() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs index b9c963ae74077..573dd4377bb2c 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.rs +++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs @@ -13,7 +13,7 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; -fn reborrow_shared_ref(x: &i32) { +unsafe fn reborrow_shared_ref(x: &i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -24,7 +24,7 @@ fn reborrow_shared_ref(x: &i32) { b.resume(); } -fn reborrow_mutable_ref(x: &mut i32) { +unsafe fn reborrow_mutable_ref(x: &mut i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -35,7 +35,7 @@ fn reborrow_mutable_ref(x: &mut i32) { b.resume(); } -fn reborrow_mutable_ref_2(x: &mut i32) { +unsafe fn reborrow_mutable_ref_2(x: &mut i32) { // ...but not OK to go on using `x`. let mut b = || { let a = &mut *x; From 6956bbf61cd0c4e5f0c39ca397085fa040710f56 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 19:36:30 -0500 Subject: [PATCH 168/546] whitelist every target feature for rustdoc --- src/librustc_trans/attributes.rs | 16 ++++++++++++---- src/librustc_trans/llvm_util.rs | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index d5ec8d1b55262..040d9455334bc 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -148,9 +148,17 @@ fn cstr(s: &'static str) -> &CStr { pub fn provide(providers: &mut Providers) { providers.target_features_whitelist = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) - .iter() - .map(|c| c.to_string()) - .collect()) + if tcx.sess.opts.actually_rustdoc { + // rustdoc needs to be able to document functions that use all the features, so + // whitelist them all + Lrc::new(llvm_util::all_known_features() + .map(|c| c.to_string()) + .collect()) + } else { + Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) + .iter() + .map(|c| c.to_string()) + .collect()) + } }; } diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index dd8b44c96b90c..5113b65a5c470 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -107,6 +107,20 @@ const POWERPC_WHITELIST: &'static [&'static str] = &["altivec", const MIPS_WHITELIST: &'static [&'static str] = &["fp64", "msa"]; +/// When rustdoc is running, provide a list of all known features so that all their respective +/// primtives may be documented. +/// +/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this +/// iterator! +pub fn all_known_features() -> impl Iterator { + ARM_WHITELIST.iter().cloned() + .chain(AARCH64_WHITELIST.iter().cloned()) + .chain(X86_WHITELIST.iter().cloned()) + .chain(HEXAGON_WHITELIST.iter().cloned()) + .chain(POWERPC_WHITELIST.iter().cloned()) + .chain(MIPS_WHITELIST.iter().cloned()) +} + pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { let arch = if sess.target.target.arch == "x86_64" { "x86" From 1937661961fa54aa2bce8c301d85536916224a74 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 22:45:35 -0500 Subject: [PATCH 169/546] Revert "Stabilize termination_trait in 1.25, not 1.26" This reverts commit e5a55e74405dedf8bc0744300a8c506eea94bc18. --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e71726bcebdc9..781071b7f7f07 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From 66d120cd263ea77a44fcde9409a71ac673a5262c Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Wed, 21 Mar 2018 07:25:32 +0200 Subject: [PATCH 170/546] Revert "remove FIXME(#33435) and remove the spurious failures counter measure" This reverts commit be73a1f963e7830de2dbfbea6b362673ab7e6ded. --- src/tools/compiletest/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index cf87062f6bee2..e65c03a6e571c 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -452,6 +452,11 @@ pub fn run_tests(config: &Config) { _ => { /* proceed */ } } + // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests. + if let Mode::CodegenUnits = config.mode { + let _ = fs::remove_dir_all("tmp/partitioning-tests"); + } + let opts = test_opts(config); let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in From 94bdeb64f96b266d990ba7b76cd78a1e2ed1977f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 23:01:42 -0500 Subject: [PATCH 171/546] termination_trait: Add () example to error message --- src/libstd/process.rs | 2 +- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831f..a6aa3502f26bb 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] + "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 67ee39d10d91c..ffff33da581bf 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` +// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index d09aac3ac2f27..24371c27742d2 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` | = help: the trait `std::process::Termination` is not implemented for `char` From 2cdc7af41366182259a05435e325d7444653a3e8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 00:24:06 -0500 Subject: [PATCH 172/546] Use NOTE instead of error-pattern directive --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ffff33da581bf..053d6bbf93a2d 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { +//~^ ERROR `i32: std::process::Termination` is not satisfied +//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` 0 } From 5201e7cf8ac0c78bc8e4f0feb8f97e91b957a19e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 21 Mar 2018 07:31:39 +0100 Subject: [PATCH 173/546] document format_args! behavior wrt. Display and Debug --- src/libcore/fmt/mod.rs | 72 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3ecd73873c091..0363714c31b5c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -406,6 +406,18 @@ impl<'a> Arguments<'a> { /// macro validates the format string at compile-time so usage of the [`write`] /// and [`format`] functions can be safely performed. /// +/// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug` +/// and `Display` contexts as seen below. The example also shows that `Debug` +/// and `Display` format to the same thing: the interpolated format string +/// in `format_args!`. +/// +/// ```rust +/// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); +/// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); +/// assert_eq!("1 foo 2", display); +/// assert_eq!(display, debug); +/// ``` +/// /// [`format_args!`]: ../../std/macro.format_args.html /// [`format`]: ../../std/fmt/fn.format.html /// [`write`]: ../../std/fmt/fn.write.html @@ -1553,10 +1565,12 @@ impl<'a> Formatter<'a> { /// /// ```rust /// use std::fmt; + /// use std::net::Ipv4Addr; /// /// struct Foo { /// bar: i32, /// baz: String, + /// addr: Ipv4Addr, /// } /// /// impl fmt::Debug for Foo { @@ -1564,12 +1578,19 @@ impl<'a> Formatter<'a> { /// fmt.debug_struct("Foo") /// .field("bar", &self.bar) /// .field("baz", &self.baz) + /// .field("addr", &format_args!("{}", self.addr)) /// .finish() /// } /// } /// - /// // prints "Foo { bar: 10, baz: "Hello World" }" - /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); + /// assert_eq!( + /// "Foo { bar: 10, baz: \"Hello World\", addr: 127.0.0.1 }", + /// format!("{:?}", Foo { + /// bar: 10, + /// baz: "Hello World".to_string(), + /// addr: Ipv4Addr::new(127, 0, 0, 1), + /// }) + /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> { @@ -1583,20 +1604,24 @@ impl<'a> Formatter<'a> { /// /// ```rust /// use std::fmt; + /// use std::marker::PhantomData; /// - /// struct Foo(i32, String); + /// struct Foo(i32, String, PhantomData); /// - /// impl fmt::Debug for Foo { + /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_tuple("Foo") /// .field(&self.0) /// .field(&self.1) + /// .field(&format_args!("_")) /// .finish() /// } /// } /// - /// // prints "Foo(10, "Hello World")" - /// println!("{:?}", Foo(10, "Hello World".to_string())); + /// assert_eq!( + /// "Foo(10, \"Hello\", _)", + /// format!("{:?}", Foo(10, "Hello".to_string(), PhantomData::)) + /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> { @@ -1646,6 +1671,41 @@ impl<'a> Formatter<'a> { /// // prints "{10, 11}" /// println!("{:?}", Foo(vec![10, 11])); /// ``` + /// + /// [`format_args!`]: ../../std/macro.format_args.html + /// + /// In this more complex example, we use [`format_args!`] and `.debug_set()` + /// to build a list of match arms: + /// + /// ```rust + /// use std::fmt; + /// + /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R)); + /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V); + /// + /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R> + /// where + /// L: 'a + fmt::Debug, R: 'a + fmt::Debug + /// { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// L::fmt(&(self.0).0, fmt)?; + /// fmt.write_str(" => ")?; + /// R::fmt(&(self.0).1, fmt) + /// } + /// } + /// + /// impl<'a, K, V> fmt::Debug for Table<'a, K, V> + /// where + /// K: 'a + fmt::Debug, V: 'a + fmt::Debug + /// { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_set() + /// .entries(self.0.iter().map(Arm)) + /// .entry(&Arm(&(format_args!("_"), &self.1))) + /// .finish() + /// } + /// } + /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { builders::debug_set_new(self) From afff64e7a4c88b39402c95f1368c880b17cdf793 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 21 Mar 2018 07:55:09 +0100 Subject: [PATCH 174/546] document format_args! further wrt. Debug & Display" --- src/libstd/macros.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 000f971361530..47609f17221ef 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -335,6 +335,18 @@ pub mod builtin { /// proxied through this one. `format_args!`, unlike its derived macros, avoids /// heap allocations. /// + /// You can use the [`fmt::Arguments`] value that `format_args!` returns + /// in `Debug` and `Display` contexts as seen below. The example also shows + /// that `Debug` and `Display` format to the same thing: the interpolated + /// format string in `format_args!`. + /// + /// ```rust + /// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); + /// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); + /// assert_eq!("1 foo 2", display); + /// assert_eq!(display, debug); + /// ``` + /// /// For more information, see the documentation in [`std::fmt`]. /// /// [`Display`]: ../std/fmt/trait.Display.html From 06f81032955e4dd92cb6be3d67f9a56c375c7313 Mon Sep 17 00:00:00 2001 From: Bastien Orivel Date: Wed, 21 Mar 2018 03:04:09 +0100 Subject: [PATCH 175/546] Bump racer and home This removes 10 dependencies from the build :tada: --- src/Cargo.lock | 114 ++++++------------------------------------------- 1 file changed, 12 insertions(+), 102 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 675457905eade..b452e83870a2c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1,20 +1,3 @@ -[[package]] -name = "advapi32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aho-corasick" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aho-corasick" version = "0.6.4" @@ -199,7 +182,7 @@ dependencies = [ "git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -567,15 +550,6 @@ dependencies = [ "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "env_logger" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "env_logger" version = "0.5.5" @@ -774,14 +748,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "home" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1053,14 +1025,6 @@ dependencies = [ "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "memchr" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "memchr" version = "2.0.1" @@ -1319,13 +1283,13 @@ dependencies = [ [[package]] name = "racer" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1392,18 +1356,6 @@ version = "0.1.0" name = "reformat_with_range" version = "0.1.0" -[[package]] -name = "regex" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "regex" version = "0.2.7" @@ -1416,11 +1368,6 @@ dependencies = [ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "regex-syntax" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "regex-syntax" version = "0.5.0" @@ -1461,7 +1408,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1525,7 +1472,7 @@ name = "rls-vfs" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2094,11 +2041,6 @@ name = "scoped-tls" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "scopeguard" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "scopeguard" version = "0.3.3" @@ -2416,23 +2358,6 @@ dependencies = [ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "thread-id" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" version = "0.3.5" @@ -2583,11 +2508,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "utf8-ranges" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "utf8-ranges" version = "1.0.0" @@ -2680,8 +2600,6 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" -"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31" @@ -2720,7 +2638,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834" "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" @@ -2741,7 +2658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc" -"checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" +"checksum home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f94f6fbdc000a6eba0c8cf08632b2091bb59141d36ac321a2a96d6365e5e4dc" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" @@ -2767,7 +2684,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fef236caad7ba3b5b3944df946f19ab3e190bca53c111dd00fe05fa8d879f2fd" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" @@ -2796,16 +2712,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" -"checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4" +"checksum racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "40d44bc30fc8d403b665286b2c9a83466ddbf69297668fb02b785c3e58eb8e0d" "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3" -"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" "checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d" @@ -2825,7 +2739,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" -"checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" @@ -2854,8 +2767,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" @@ -2873,7 +2784,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3" -"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" From e0165af94b034dacde7f9a598c5e72b9c1a1898c Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 21 Mar 2018 10:32:53 +0100 Subject: [PATCH 176/546] fix vector fmin/fmax non-fast/fast intrinsics NaN handling --- src/librustc_trans/builder.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 3f5a9a54ff1ea..91eabb9998f4a 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true); + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); } @@ -1046,7 +1046,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true); + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); } @@ -1056,7 +1056,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); } @@ -1067,7 +1067,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); } From fc3c90cf8af1a2c0e9e6167daed956905b5951a2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 05:10:42 -0400 Subject: [PATCH 177/546] report an error if we see an unexpected lifetime in impl Trait But leave closure substs alone. --- src/librustc/diagnostics.rs | 48 +++++ src/librustc/infer/anon_types/mod.rs | 188 ++++++++++++++---- .../region-escape-via-bound-contravariant.rs | 35 ++++ .../ui/impl-trait/region-escape-via-bound.rs | 34 ++++ .../impl-trait/region-escape-via-bound.stderr | 20 ++ 5 files changed, 291 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs create mode 100644 src/test/ui/impl-trait/region-escape-via-bound.rs create mode 100644 src/test/ui/impl-trait/region-escape-via-bound.stderr diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b3a904f2f5fec..fad1803259286 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2074,6 +2074,54 @@ a (non-transparent) struct containing a single float, while `Grams` is a transparent wrapper around a float. This can make a difference for the ABI. "##, +E0909: r##" +The `impl Trait` return type captures lifetime parameters that do not +appear within the `impl Trait` itself. + +Erroneous code example: + +```compile-fail,E0909 +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> +where 'x: 'y +{ + x +} +``` + +Here, the function `foo` returns a value of type `Cell<&'x u32>`, +which references the lifetime `'x`. However, the return type is +declared as `impl Trait<'y>` -- this indicates that `foo` returns +"some type that implements `Trait<'y>`", but it also indicates that +the return type **only captures data referencing the lifetime `'y`**. +In this case, though, we are referencing data with lifetime `'x`, so +this function is in error. + +To fix this, you must reference the lifetime `'x` from the return +type. For example, changing the return type to `impl Trait<'y> + 'x` +would work: + +``` +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x +where 'x: 'y +{ + x +} +``` +"##, + + } diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index 6a4f4072f53dc..93e8745af1b57 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -17,7 +17,7 @@ use traits::{self, PredicateObligation}; use ty::{self, Ty, TyCtxt}; use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; use ty::outlives::Component; -use ty::subst::{Kind, UnpackedKind, Substs}; +use ty::subst::{Kind, Substs, UnpackedKind}; use util::nodemap::DefIdMap; pub type AnonTypeMap<'tcx> = DefIdMap>; @@ -113,10 +113,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> InferOk<'tcx, (T, AnonTypeMap<'tcx>)> { debug!( "instantiate_anon_types(value={:?}, parent_def_id={:?}, body_id={:?}, param_env={:?})", - value, - parent_def_id, - body_id, - param_env, + value, parent_def_id, body_id, param_env, ); let mut instantiator = Instantiator { infcx: self, @@ -458,7 +455,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper { tcx: self.tcx, map }); + let definition_ty = + instantiated_ty.fold_with(&mut ReverseMapper::new( + self.tcx, + self.is_tainted_by_errors(), + def_id, + map, + instantiated_ty, + )); debug!( "infer_anon_definition_from_instantiation: definition_ty={:?}", definition_ty @@ -475,7 +479,49 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { struct ReverseMapper<'cx, 'gcx: 'tcx, 'tcx: 'cx> { tcx: TyCtxt<'cx, 'gcx, 'tcx>, - map: FxHashMap, Kind<'gcx>> + + /// If errors have already been reported in this fn, we suppress + /// our own errors because they are sometimes derivative. + tainted_by_errors: bool, + + anon_type_def_id: DefId, + map: FxHashMap, Kind<'gcx>>, + map_missing_regions_to_empty: bool, + + /// initially `Some`, set to `None` once error has been reported + hidden_ty: Option>, +} + +impl<'cx, 'gcx, 'tcx> ReverseMapper<'cx, 'gcx, 'tcx> { + fn new( + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + tainted_by_errors: bool, + anon_type_def_id: DefId, + map: FxHashMap, Kind<'gcx>>, + hidden_ty: Ty<'tcx>, + ) -> Self { + Self { + tcx, + tainted_by_errors, + anon_type_def_id, + map, + map_missing_regions_to_empty: false, + hidden_ty: Some(hidden_ty), + } + } + + fn fold_kind_mapping_missing_regions_to_empty(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> { + assert!(!self.map_missing_regions_to_empty); + self.map_missing_regions_to_empty = true; + let kind = kind.fold_with(self); + self.map_missing_regions_to_empty = false; + kind + } + + fn fold_kind_normally(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> { + assert!(!self.map_missing_regions_to_empty); + kind.fold_with(self) + } } impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> { @@ -484,33 +530,105 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - // ignore bound regions that appear in the type (e.g., this - // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. - if let ty::ReLateBound(..) = *r { - return r; + match r { + // ignore bound regions that appear in the type (e.g., this + // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. + ty::ReLateBound(..) => return r, + + // ignore `'static`, as that can appear anywhere + ty::ReStatic => return r, + + _ => { } } match self.map.get(&r.into()).map(|k| k.unpack()) { Some(UnpackedKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), None => { - // 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. + if !self.map_missing_regions_to_empty && !self.tainted_by_errors { + if let Some(hidden_ty) = self.hidden_ty.take() { + let span = self.tcx.def_span(self.anon_type_def_id); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0909, + "hidden type for `impl Trait` captures lifetime that \ + does not appear in bounds", + ); + + // Assuming regionck succeeded, then we must + // be capturing *some* region from the fn + // header, and hence it must be free, so it's + // ok to invoke this fn (which doesn't accept + // all regions, and would ICE if an + // inappropriate region is given). We check + // `is_tainted_by_errors` by errors above, so + // we don't get in here unless regionck + // succeeded. (Note also that if regionck + // failed, then the regions we are attempting + // to map here may well be giving errors + // *because* the constraints were not + // satisfiable.) + self.tcx.note_and_explain_free_region( + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + r, + "" + ); + + err.emit(); + } + } + self.tcx.types.re_empty + }, + } + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.sty { + ty::TyClosure(def_id, substs) => { + // I am a horrible monster and I pray for death. When + // we encounter a closure here, it is always a closure + // from within the function that we are currently + // type-checking -- one that is now being encapsulated + // in an existential abstract type. Ideally, we would + // go through the types/lifetimes that it references + // and treat them just like we would any other type, + // which means we would error out if we find any + // reference to a type/region that is not in the + // "reverse map". // - // 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, + // **However,** in the case of closures, there 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. - self.tcx.types.re_empty + // 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. + + let generics = self.tcx.generics_of(def_id); + let parent_len = generics.parent_count(); + let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map( + |(index, &kind)| { + if index < parent_len { + // Accommodate missing regions in the parent kinds... + self.fold_kind_mapping_missing_regions_to_empty(kind) + } else { + // ...but not elsewhere. + self.fold_kind_normally(kind) + } + }, + )); + + self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs }) } + + _ => ty.super_fold_with(self), } } } @@ -573,12 +691,13 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { return self.fold_anon_ty(ty, def_id, substs); } - debug!("instantiate_anon_types_in_map: \ - encountered anon with wrong parent \ - def_id={:?} \ - anon_parent_def_id={:?}", - def_id, - anon_parent_def_id); + debug!( + "instantiate_anon_types_in_map: \ + encountered anon with wrong parent \ + def_id={:?} \ + anon_parent_def_id={:?}", + def_id, anon_parent_def_id + ); } } @@ -598,8 +717,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { debug!( "instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})", - def_id, - substs + def_id, substs ); // Use the same type variable if the exact same TyAnon appears more @@ -608,8 +726,10 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { return anon_defn.concrete_ty; } let span = tcx.def_span(def_id); - let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)); + let ty_var = infcx.next_ty_var( + ty::UniverseIndex::ROOT, + TypeVariableOrigin::TypeInference(span), + ); let predicates_of = tcx.predicates_of(def_id); let bounds = predicates_of.instantiate(tcx, substs); diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs new file mode 100644 index 0000000000000..416bdae517845 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs @@ -0,0 +1,35 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +trait Trait<'a> { } + +impl Trait<'b> for &'a u32 { } + +fn foo(x: &'x u32) -> impl Trait<'y> +where 'x: 'y +{ + x +} + +fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs new file mode 100644 index 0000000000000..38c18ce61044e --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -0,0 +1,34 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we do not allow the region `'x` to escape in the impl +// trait **even though** `'y` escapes, which outlives `'x`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909] +where 'x: 'y +{ + x +} + +fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr new file mode 100644 index 0000000000000..5659fee9bedc6 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -0,0 +1,20 @@ +error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/region-escape-via-bound.rs:27:29 + | +LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + | ^^^^^^^^^^^^^^ + | +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 27:1 + --> $DIR/region-escape-via-bound.rs:27:1 + | +LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y> +LL | | //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909] +LL | | where 'x: 'y +LL | | { +LL | | x +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0909`. From f71de45b230954c25f2337272852be1146d26136 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 10:49:05 -0400 Subject: [PATCH 178/546] use subtyping when we create a closure instead of for upvar types We used to make the upvar types in the closure `==` but that was stronger than we needed. Subtyping suffices, since we are copying the upvar value into the closure field. This in turn allows us to infer smaller lifetimes in captured values in some cases (like the example here), avoiding errors. --- src/librustc_typeck/check/upvar.rs | 2 +- .../ui/generator/auto-trait-regions.stderr | 6 ++-- ...-escape-via-bound-contravariant-closure.rs | 31 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index ab148afafbe09..4fc3344dab2a9 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -217,7 +217,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .upvar_tys(closure_def_id, self.tcx) .zip(final_upvar_tys) { - self.demand_eqtype(span, final_upvar_ty, upvar_ty); + self.demand_suptype(span, upvar_ty, final_upvar_ty); } // If we are also inferred the closure kind here, diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index cd83915fe82d3..dd78baf927509 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -1,15 +1,15 @@ -error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` +error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` --> $DIR/auto-trait-regions.rs:40:5 | LL | assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied - | ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No` + | ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No` | = help: the following implementations were found: = note: required because it appears within the type `OnlyFooIfStaticRef` = note: required because it appears within the type `&OnlyFooIfStaticRef` = note: required because it appears within the type `for<'r> {&'r OnlyFooIfStaticRef, ()}` - = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` + = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` note: required by `assert_foo` --> $DIR/auto-trait-regions.rs:30:1 | diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs new file mode 100644 index 0000000000000..f554efe903613 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs @@ -0,0 +1,31 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +fn foo(x: &'x u32) -> impl Fn() -> &'y u32 +where 'x: 'y +{ + move || x +} + +fn main() { } From 9d5ec9ef1a03d343d01bde68ed6e6affc32ae492 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 16:17:27 -0400 Subject: [PATCH 179/546] work around fallout from these changes in rustc --- src/librustc/infer/canonical.rs | 3 ++- src/librustc/lib.rs | 1 + .../traits/specialize/specialization_graph.rs | 18 ++++++++++------ src/librustc/ty/mod.rs | 21 ++++++++++++------- src/librustc/ty/sty.rs | 11 ++++++---- src/librustc/util/captures.rs | 18 ++++++++++++++++ src/librustc_metadata/decoder.rs | 6 +++++- src/librustc_typeck/collect.rs | 5 +++-- 8 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 src/librustc/util/captures.rs diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 4e0cf59e8a7fd..22526c7751d50 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -40,6 +40,7 @@ use traits::{Obligation, ObligationCause, PredicateObligation}; use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags}; use ty::subst::{Kind, UnpackedKind}; use ty::fold::{TypeFoldable, TypeFolder}; +use util::captures::Captures; use util::common::CellUsizeExt; use rustc_data_structures::indexed_vec::IndexVec; @@ -382,7 +383,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>, result_subst: &'a CanonicalVarValues<'tcx>, - ) -> impl Iterator> + 'a { + ) -> impl Iterator> + Captures<'gcx> + 'a { let QueryRegionConstraints { region_outlives, ty_outlives, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 77259f156e5e2..22b07c8cc044f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -157,6 +157,7 @@ pub mod traits; pub mod ty; pub mod util { + pub mod captures; pub mod common; pub mod ppaux; pub mod nodemap; diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index e0d662657b7de..e56a8662f3eb4 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -19,6 +19,7 @@ use ty::{self, TyCtxt, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; use rustc_data_structures::sync::Lrc; use syntax::ast::Name; +use util::captures::Captures; use util::nodemap::{DefIdMap, FxHashMap}; /// A per-trait graph of impls in specialization order. At the moment, this @@ -313,9 +314,10 @@ impl<'a, 'gcx, 'tcx> Node { } /// Iterate over the items defined directly by the given (impl or trait) node. - #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. - pub fn items(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) - -> impl Iterator + 'a { + pub fn items( + &self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator + 'a { tcx.associated_items(self.def_id()) } @@ -367,9 +369,13 @@ impl<'a, 'gcx, 'tcx> Ancestors { /// Search the items from the given ancestors, returning each definition /// with the given name and the given kind. #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. - pub fn defs(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_item_name: Name, - trait_item_kind: ty::AssociatedKind, trait_def_id: DefId) - -> impl Iterator> + 'a { + pub fn defs( + self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + trait_item_name: Name, + trait_item_kind: ty::AssociatedKind, + trait_def_id: DefId, + ) -> impl Iterator> + Captures<'gcx> + Captures<'tcx> + 'a { self.flat_map(move |node| { node.items(tcx).filter(move |impl_item| { impl_item.kind == trait_item_kind && diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c915022351925..95c5cd377d71f 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -34,6 +34,7 @@ use ty; use ty::subst::{Subst, Substs}; use ty::util::{IntTypeExt, Discr}; use ty::walk::TypeWalker; +use util::captures::Captures; use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use serialize::{self, Encodable, Encoder}; @@ -1942,8 +1943,10 @@ impl<'a, 'gcx, 'tcx> AdtDef { } #[inline] - pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>) - -> impl Iterator> + 'a { + pub fn discriminants( + &'a self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator> + Captures<'gcx> + 'a { let repr_type = self.repr.discr_type(); let initial = repr_type.initial_discriminant(tcx.global_tcx()); let mut prev_discr = None::>; @@ -2290,7 +2293,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns an iterator of the def-ids for all body-owners in this /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir.krate().body_ids.iter()`. - pub fn body_owners(self) -> impl Iterator + 'a { + pub fn body_owners( + self, + ) -> impl Iterator + Captures<'tcx> + Captures<'gcx> + 'a { self.hir.krate() .body_ids .iter() @@ -2394,11 +2399,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. - pub fn associated_items(self, def_id: DefId) - -> impl Iterator + 'a { + pub fn associated_items( + self, + def_id: DefId, + ) -> impl Iterator + 'a { let def_ids = self.associated_item_def_ids(def_id); - (0..def_ids.len()).map(move |i| self.associated_item(def_ids[i])) + Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))) + as Box + 'a> } /// Returns true if the impls are the same polarity and are implementing diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bb5c7b5fd2a5e..d7ab6e39ac5f0 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -18,6 +18,7 @@ use rustc_data_structures::indexed_vec::Idx; use ty::subst::{Substs, Subst, Kind, UnpackedKind}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS}; +use util::captures::Captures; use std::iter; use std::cmp::Ordering; @@ -384,9 +385,11 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { /// This returns the types of the MIR locals which had to be stored across suspension points. /// It is calculated in rustc_mir::transform::generator::StateTransform. /// All the types here must be in the tuple in GeneratorInterior. - pub fn state_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> - impl Iterator> + 'a - { + pub fn state_tys( + self, + def_id: DefId, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator> + Captures<'gcx> + 'a { let state = tcx.generator_layout(def_id).fields.iter(); state.map(move |d| d.ty.subst(tcx, self.substs)) } @@ -403,7 +406,7 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { /// This is the types of all the fields stored in a generator. /// It includes the upvars, state types and the state discriminant which is u32. pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> - impl Iterator> + 'a + impl Iterator> + Captures<'gcx> + 'a { self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx)) } diff --git a/src/librustc/util/captures.rs b/src/librustc/util/captures.rs new file mode 100644 index 0000000000000..b68cfd278fa9e --- /dev/null +++ b/src/librustc/util/captures.rs @@ -0,0 +1,18 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// "Signaling" trait used in impl trait to tag lifetimes that you may +/// need to capture but don't really need for other reasons. +/// Basically a workaround; see [this comment] for details. +/// +/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 +pub trait Captures<'a> { } + +impl<'a, T: ?Sized> Captures<'a> for T { } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e1c17e8260a79..b0c945fbf2a05 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -29,6 +29,7 @@ use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; use rustc::mir::Mir; +use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; use std::collections::BTreeMap; @@ -146,7 +147,10 @@ impl<'a, 'tcx: 'a, T: Decodable> Lazy { } impl<'a, 'tcx: 'a, T: Decodable> LazySeq { - pub fn decode>(self, meta: M) -> impl Iterator + 'a { + pub fn decode>( + self, + meta: M, + ) -> impl Iterator + Captures<'tcx> + 'a { let mut dcx = meta.decoder(self.position); dcx.lazy_state = LazyState::NodeStart(self.position); (0..self.len).map(move |_| T::decode(&mut dcx).unwrap()) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a17b35dec42d7..6f24d06844bb4 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -35,8 +35,9 @@ use rustc::ty::{ToPredicate, ReprOptions}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc::ty::util::IntTypeExt; -use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::ty::util::Discr; +use rustc::util::captures::Captures; +use rustc::util::nodemap::{FxHashSet, FxHashMap}; use syntax::{abi, ast}; use syntax::ast::MetaItemKind; @@ -1281,7 +1282,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, fn early_bound_lifetimes_from_generics<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, ast_generics: &'a hir::Generics) - -> impl Iterator + -> impl Iterator + Captures<'tcx> { ast_generics .lifetimes() From 94eebaa32505919a17c0848ad0663d49bcddfa80 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 09:24:32 -0400 Subject: [PATCH 180/546] WIP fix mir-opt-end-region-8 --- src/test/mir-opt/end_region_8.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 405864aba9436..d621cdb4d58f8 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -36,7 +36,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _2: &'21_1rs D; // ... // let mut _3: (); -// let mut _4: [closure@NodeId(22) r:&'21_1rs D]; +// let mut _4: [closure@NodeId(22) r:&'19s D]; // let mut _5: &'21_1rs D; // bb0: { // StorageLive(_1); @@ -54,6 +54,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // resume; // } // bb2: { +// EndRegion('19s); // StorageDead(_4); // _0 = (); // EndRegion('21_1rs); @@ -61,6 +62,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { +// EndRegion('19s); // EndRegion('21_1rs); // drop(_1) -> bb1; // } @@ -72,7 +74,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'21_1rs D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'19s D]) -> i32 { // let mut _0: i32; // let mut _2: i32; // From 5aa29c4c823cbe02a2d84080eefe3eb1aecf0a06 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 21 Mar 2018 14:34:46 +0100 Subject: [PATCH 181/546] Fix test error --- src/librustc_mir/interpret/const_eval.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b033..47f6f61072e13 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -339,6 +339,14 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator { ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, cid: GlobalId<'tcx>, ) -> EvalResult<'tcx, AllocId> { + let alloc = ecx + .tcx + .interpret_interner + .get_cached(cid.instance.def_id()); + // Don't evaluate when already cached to prevent cycles + if let Some(alloc) = alloc { + return Ok(alloc) + } // ensure the static is computed ecx.const_eval(cid)?; Ok(ecx From c7bdd371a64ff5b9b86680fd77dd56d1eeabb76c Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 21 Mar 2018 22:03:24 +0800 Subject: [PATCH 182/546] Revert "Apply a fix to travis-ci/dpl#788 manually until dpl 1.9.5 is released." This reverts commit 20e65f11f3bb0538c5676425e74b593676bd0f12. --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index b2aba305aedc4..41ea0c9afa87c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -318,8 +318,6 @@ before_deploy: deploy: - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -336,8 +334,6 @@ deploy: # this is the same as the above deployment provider except that it uploads to # a slightly different directory and has a different trigger - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -355,8 +351,6 @@ deploy: # try branch. Travis does not appear to provide a way to use "or" in these # conditions. - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -371,8 +365,6 @@ deploy: condition: $DEPLOY = 1 - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy From 75dcc61d3c1cce7b4428dd85bb588e99d9faf7a9 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Wed, 21 Mar 2018 23:12:24 +0900 Subject: [PATCH 183/546] Cargo fmt libtest --- src/libtest/formatters/json.rs | 49 ++--- src/libtest/formatters/pretty.rs | 9 +- src/libtest/formatters/terse.rs | 9 +- src/libtest/lib.rs | 325 ++++++++++++++----------------- src/libtest/stats.rs | 23 ++- 5 files changed, 182 insertions(+), 233 deletions(-) diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs index d323d50f702ba..89235d897bde6 100644 --- a/src/libtest/formatters/json.rs +++ b/src/libtest/formatters/json.rs @@ -36,17 +36,12 @@ impl JsonFormatter { if let Some(extras) = extra { self.write_message(&*format!( r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#, - ty, - name, - evt, - extras + ty, name, evt, extras )) } else { self.write_message(&*format!( r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#, - ty, - name, - evt + ty, name, evt )) } } @@ -89,14 +84,12 @@ impl OutputFormatter for JsonFormatter { self.write_event("test", desc.name.as_slice(), "failed", extra_data) } - TrFailedMsg(ref m) => { - self.write_event( - "test", - desc.name.as_slice(), - "failed", - Some(format!(r#""message": "{}""#, EscapedString(m))), - ) - } + TrFailedMsg(ref m) => self.write_event( + "test", + desc.name.as_slice(), + "failed", + Some(format!(r#""message": "{}""#, EscapedString(m))), + ), TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None), @@ -116,13 +109,10 @@ impl OutputFormatter for JsonFormatter { let line = format!( "{{ \"type\": \"bench\", \ - \"name\": \"{}\", \ - \"median\": {}, \ - \"deviation\": {}{} }}", - desc.name, - median, - deviation, - mbps + \"name\": \"{}\", \ + \"median\": {}, \ + \"deviation\": {}{} }}", + desc.name, median, deviation, mbps ); self.write_message(&*line) @@ -138,16 +128,15 @@ impl OutputFormatter for JsonFormatter { } fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result { - self.write_message(&*format!( "{{ \"type\": \"suite\", \ - \"event\": \"{}\", \ - \"passed\": {}, \ - \"failed\": {}, \ - \"allowed_fail\": {}, \ - \"ignored\": {}, \ - \"measured\": {}, \ - \"filtered_out\": \"{}\" }}", + \"event\": \"{}\", \ + \"passed\": {}, \ + \"failed\": {}, \ + \"allowed_fail\": {}, \ + \"ignored\": {}, \ + \"measured\": {}, \ + \"filtered_out\": \"{}\" }}", if state.failed == 0 { "ok" } else { "failed" }, state.passed, state.failed + state.allowed_fail, diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs index f2064deefce62..8e5fa00b5f27d 100644 --- a/src/libtest/formatters/pretty.rs +++ b/src/libtest/formatters/pretty.rs @@ -196,8 +196,7 @@ impl OutputFormatter for PrettyFormatter { self.write_plain(&format!( "test {} has been running for over {} seconds\n", - desc.name, - TEST_WARN_TIMEOUT_S + desc.name, TEST_WARN_TIMEOUT_S )) } @@ -232,11 +231,7 @@ impl OutputFormatter for PrettyFormatter { } else { format!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n", - state.passed, - state.failed, - state.ignored, - state.measured, - state.filtered_out + state.passed, state.failed, state.ignored, state.measured, state.filtered_out ) }; diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs index 88689485144c0..85286027d6921 100644 --- a/src/libtest/formatters/terse.rs +++ b/src/libtest/formatters/terse.rs @@ -195,8 +195,7 @@ impl OutputFormatter for TerseFormatter { fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { self.write_plain(&format!( "test {} has been running for over {} seconds\n", - desc.name, - TEST_WARN_TIMEOUT_S + desc.name, TEST_WARN_TIMEOUT_S )) } @@ -231,11 +230,7 @@ impl OutputFormatter for TerseFormatter { } else { format!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n", - state.passed, - state.failed, - state.ignored, - state.measured, - state.filtered_out + state.passed, state.failed, state.ignored, state.measured, state.filtered_out ) }; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 59d701dd0fbc8..b8be1aeff1742 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -30,10 +30,8 @@ #![unstable(feature = "test", issue = "27812")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", - test(attr(deny(warnings))))] + html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] #![deny(warnings)] - #![feature(asm)] #![feature(fnbox)] #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] @@ -43,10 +41,10 @@ #![feature(termination_trait_lib)] extern crate getopts; -extern crate term; #[cfg(any(unix, target_os = "cloudabi"))] extern crate libc; extern crate panic_unwind; +extern crate term; pub use self::TestFn::*; pub use self::ColorConfig::*; @@ -72,7 +70,7 @@ use std::process::Termination; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use std::borrow::Cow; use std::process; @@ -81,16 +79,16 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu // to be used by rustc to compile tests in libtest pub mod test { - pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed, - TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName, - DynTestName, DynTestFn, assert_test_result, run_test, test_main, test_main_static, - filter_tests, parse_opts, StaticBenchFn, ShouldPanic, Options}; + pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, + Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, ShouldPanic, + StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, + TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}; } pub mod stats; mod formatters; -use formatters::{OutputFormatter, PrettyFormatter, TerseFormatter, JsonFormatter}; +use formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter}; // The name of a test. By convention this follows the rules for rust // paths; i.e. it should be a series of identifiers separated by double @@ -255,7 +253,9 @@ pub struct Options { impl Options { pub fn new() -> Options { - Options { display_output: false } + Options { + display_output: false, + } } pub fn display_output(mut self, display_output: bool) -> Options { @@ -272,7 +272,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Options) { Some(Err(msg)) => { eprintln!("error: {}", msg); process::exit(101); - }, + } None => return, }; @@ -289,7 +289,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Options) { Err(e) => { eprintln!("error: io error when listing tests: {:?}", e); process::exit(101); - }, + } } } } @@ -306,18 +306,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) { let owned_tests = tests .iter() .map(|t| match t.testfn { - StaticTestFn(f) => { - TestDescAndFn { - testfn: StaticTestFn(f), - desc: t.desc.clone(), - } - } - StaticBenchFn(f) => { - TestDescAndFn { - testfn: StaticBenchFn(f), - desc: t.desc.clone(), - } - } + StaticTestFn(f) => TestDescAndFn { + testfn: StaticTestFn(f), + desc: t.desc.clone(), + }, + StaticBenchFn(f) => TestDescAndFn { + testfn: StaticBenchFn(f), + desc: t.desc.clone(), + }, _ => panic!("non-static tests passed to test::test_main_static"), }) .collect(); @@ -397,34 +393,34 @@ fn optgroups() -> getopts::Options { "", "logfile", "Write logs to the specified file instead \ - of stdout", + of stdout", "PATH", ) .optflag( "", "nocapture", "don't capture stdout/stderr of each \ - task, allow printing directly", + task, allow printing directly", ) .optopt( "", "test-threads", "Number of threads used for running tests \ - in parallel", + in parallel", "n_threads", ) .optmulti( "", "skip", "Skip tests whose names contain FILTER (this flag can \ - be used multiple times)", + be used multiple times)", "FILTER", ) .optflag( "q", "quiet", "Display one character per test instead of one line. \ - Alias to --format=terse", + Alias to --format=terse", ) .optflag( "", @@ -516,8 +512,7 @@ pub fn parse_opts(args: &[String]) -> Option { if let Some(opt) = matches.opt_str("Z") { if !is_nightly() { return Some(Err( - "the option `Z` is only accepted on the nightly compiler" - .into(), + "the option `Z` is only accepted on the nightly compiler".into(), )); } @@ -562,19 +557,17 @@ pub fn parse_opts(args: &[String]) -> Option { } let test_threads = match matches.opt_str("test-threads") { - Some(n_str) => { - match n_str.parse::() { - Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))), - Ok(n) => Some(n), - Err(e) => { - return Some(Err(format!( - "argument for --test-threads must be a number > 0 \ - (error: {})", - e - ))) - } + Some(n_str) => match n_str.parse::() { + Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))), + Ok(n) => Some(n), + Err(e) => { + return Some(Err(format!( + "argument for --test-threads must be a number > 0 \ + (error: {})", + e + ))) } - } + }, None => None, }; @@ -586,7 +579,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some(v) => { return Some(Err(format!( "argument for --color must be auto, always, or never (was \ - {})", + {})", v ))) } @@ -599,8 +592,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some("json") => { if !allow_unstable { return Some(Err( - "The \"json\" format is only accepted on the nightly compiler" - .into(), + "The \"json\" format is only accepted on the nightly compiler".into(), )); } OutputFormat::Json @@ -609,7 +601,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some(v) => { return Some(Err(format!( "argument for --format must be pretty, terse, or json (was \ - {})", + {})", v ))) } @@ -811,8 +803,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res ntest += 1; "test" } - StaticBenchFn(..) | - DynBenchFn(..) => { + StaticBenchFn(..) | DynBenchFn(..) => { nbench += 1; "benchmark" } @@ -834,7 +825,8 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res writeln!(output, "")?; } - writeln!(output, + writeln!( + output, "{}, {}", plural(ntest, "test"), plural(nbench, "benchmark") @@ -851,7 +843,6 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu st: &mut ConsoleTestState, out: &mut OutputFormatter, ) -> io::Result<()> { - match (*event).clone() { TeFiltered(ref filtered_tests) => { st.total = filtered_tests.len(); @@ -989,8 +980,7 @@ fn use_color(opts: &TestOpts) -> bool { } } -#[cfg(any(target_os = "cloudabi", - target_os = "redox", +#[cfg(any(target_os = "cloudabi", target_os = "redox", all(target_arch = "wasm32", not(target_os = "emscripten"))))] fn stdout_isatty() -> bool { // FIXME: Implement isatty on Redox @@ -1089,10 +1079,12 @@ where let now = Instant::now(); let timed_out = running_tests .iter() - .filter_map(|(desc, timeout)| if &now >= timeout { - Some(desc.clone()) - } else { - None + .filter_map(|(desc, timeout)| { + if &now >= timeout { + Some(desc.clone()) + } else { + None + } }) .collect(); for test in &timed_out { @@ -1174,12 +1166,10 @@ fn get_concurrency() -> usize { let opt_n: Option = s.parse().ok(); match opt_n { Some(n) if n > 0 => n, - _ => { - panic!( - "RUST_TEST_THREADS is `{}`, should be a positive integer.", - s - ) - } + _ => panic!( + "RUST_TEST_THREADS is `{}`, should be a positive integer.", + s + ), } } Err(..) => num_cpus(), @@ -1223,20 +1213,15 @@ fn get_concurrency() -> usize { 1 } - #[cfg(any(target_os = "android", - target_os = "cloudabi", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "solaris"))] + #[cfg(any(target_os = "android", target_os = "cloudabi", target_os = "emscripten", + target_os = "fuchsia", target_os = "ios", target_os = "linux", + target_os = "macos", target_os = "solaris"))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } } #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", - target_os = "netbsd"))] + target_os = "netbsd"))] fn num_cpus() -> usize { use std::ptr; @@ -1308,26 +1293,28 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec filtered, - Some(ref filter) => { - filtered - .into_iter() - .filter(|test| if opts.filter_exact { + Some(ref filter) => filtered + .into_iter() + .filter(|test| { + if opts.filter_exact { test.desc.name.as_slice() == &filter[..] } else { test.desc.name.as_slice().contains(&filter[..]) - }) - .collect() - } + } + }) + .collect(), }; // Skip tests that match any of the skip filters filtered = filtered .into_iter() .filter(|t| { - !opts.skip.iter().any(|sf| if opts.filter_exact { - t.desc.name.as_slice() == &sf[..] - } else { - t.desc.name.as_slice().contains(&sf[..]) + !opts.skip.iter().any(|sf| { + if opts.filter_exact { + t.desc.name.as_slice() == &sf[..] + } else { + t.desc.name.as_slice().contains(&sf[..]) + } }) }) .collect(); @@ -1354,31 +1341,23 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec) -> Vec { // convert benchmarks to tests, if we're not benchmarking them - tests.into_iter().map(|x| { - let testfn = match x.testfn { - DynBenchFn(bench) => { - DynTestFn(Box::new(move || { - bench::run_once(|b| { - __rust_begin_short_backtrace(|| bench.run(b)) - }) - })) - } - StaticBenchFn(benchfn) => { - DynTestFn(Box::new(move || { - bench::run_once(|b| { - __rust_begin_short_backtrace(|| benchfn(b)) - }) - })) - } + tests + .into_iter() + .map(|x| { + let testfn = match x.testfn { + DynBenchFn(bench) => DynTestFn(Box::new(move || { + bench::run_once(|b| __rust_begin_short_backtrace(|| bench.run(b))) + })), + StaticBenchFn(benchfn) => DynTestFn(Box::new(move || { + bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b))) + })), f => f, }; TestDescAndFn { @@ -1395,22 +1374,22 @@ pub fn run_test( test: TestDescAndFn, monitor_ch: Sender, ) { - let TestDescAndFn { desc, testfn } = test; - let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && - !cfg!(target_os = "emscripten") && - desc.should_panic != ShouldPanic::No; + let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && !cfg!(target_os = "emscripten") + && desc.should_panic != ShouldPanic::No; if force_ignore || desc.ignore || ignore_because_panic_abort { monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap(); return; } - fn run_test_inner(desc: TestDesc, - monitor_ch: Sender, - nocapture: bool, - testfn: Box) { + fn run_test_inner( + desc: TestDesc, + monitor_ch: Sender, + nocapture: bool, + testfn: Box, + ) { // Buffer for capturing standard I/O let data = Arc::new(Mutex::new(Vec::new())); let data2 = data.clone(); @@ -1440,7 +1419,6 @@ pub fn run_test( .unwrap(); }; - // If the platform is single-threaded we're just going to run // the test synchronously, regardless of the concurrency // level. @@ -1455,27 +1433,25 @@ pub fn run_test( match testfn { DynBenchFn(bencher) => { - ::bench::benchmark(desc, - monitor_ch, - opts.nocapture, - |harness| bencher.run(harness)); + ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + bencher.run(harness) + }); } StaticBenchFn(benchfn) => { - ::bench::benchmark(desc, - monitor_ch, - opts.nocapture, - |harness| (benchfn.clone())(harness)); + ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + (benchfn.clone())(harness) + }); } DynTestFn(f) => { - let cb = move || { - __rust_begin_short_backtrace(f) - }; + let cb = move || __rust_begin_short_backtrace(f); run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb)) } - StaticTestFn(f) => { - run_test_inner(desc, monitor_ch, opts.nocapture, - Box::new(move || __rust_begin_short_backtrace(f))) - } + StaticTestFn(f) => run_test_inner( + desc, + monitor_ch, + opts.nocapture, + Box::new(move || __rust_begin_short_backtrace(f)), + ), } } @@ -1487,8 +1463,7 @@ fn __rust_begin_short_backtrace(f: F) { fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> TestResult { match (&desc.should_panic, task_result) { - (&ShouldPanic::No, Ok(())) | - (&ShouldPanic::Yes, Err(_)) => TrOk, + (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { if err.downcast_ref::() .map(|e| &**e) @@ -1545,7 +1520,6 @@ impl MetricMap { } } - // Benchmarking /// A function that is opaque to the optimizer, to allow benchmarks to @@ -1566,7 +1540,6 @@ pub fn black_box(dummy: T) -> T { dummy } - impl Bencher { /// Callback for benchmark functions to run in their body. pub fn iter(&mut self, mut inner: F) @@ -1605,7 +1578,6 @@ where return ns_from_dur(start.elapsed()); } - pub fn iter(inner: &mut F) -> stats::Summary where F: FnMut() -> T, @@ -1649,8 +1621,8 @@ where // If we've run for 100ms and seem to have converged to a // stable median. - if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 && - summ.median - summ5.median < summ5.median_abs_dev + if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 + && summ.median - summ5.median < summ5.median_abs_dev { return summ5; } @@ -1680,7 +1652,7 @@ pub mod bench { use std::io; use std::sync::{Arc, Mutex}; use stats; - use super::{Bencher, BenchSamples, BenchMode, Sink, MonitorMsg, TestDesc, Sender, TestResult}; + use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult}; pub fn benchmark(desc: TestDesc, monitor_ch: Sender, nocapture: bool, f: F) where @@ -1711,7 +1683,8 @@ pub mod bench { io::set_panic(panicio); }; - let test_result = match result { //bs.bench(f) { + let test_result = match result { + //bs.bench(f) { Ok(Some(ns_iter_summ)) => { let ns_iter = cmp::max(ns_iter_summ.median as u64, 1); let mb_s = bs.bytes * 1000 / ns_iter; @@ -1732,9 +1705,7 @@ pub mod bench { }; TestResult::TrBench(bs) } - Err(_) => { - TestResult::TrFailed - } + Err(_) => TestResult::TrFailed, }; let stdout = data.lock().unwrap().to_vec(); @@ -1756,9 +1727,9 @@ pub mod bench { #[cfg(test)] mod tests { - use test::{TrFailed, TrFailedMsg, TrIgnored, TrOk, filter_tests, parse_opts, TestDesc, - TestDescAndFn, TestOpts, run_test, MetricMap, StaticTestName, DynTestName, - DynTestFn, ShouldPanic}; + use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, ShouldPanic, + StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, + TrIgnored, TrOk}; use std::sync::mpsc::channel; use bench; use Bencher; @@ -1904,25 +1875,26 @@ mod tests { opts.run_tests = true; opts.run_ignored = true; - let tests = - vec![TestDescAndFn { - desc: TestDesc { - name: StaticTestName("1"), - ignore: true, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }, - TestDescAndFn { - desc: TestDesc { - name: StaticTestName("2"), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }]; + let tests = vec![ + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("1"), + ignore: true, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("2"), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + ]; let filtered = filter_tests(&opts, tests); assert_eq!(filtered.len(), 1); @@ -1935,17 +1907,16 @@ mod tests { fn tests() -> Vec { vec!["base", "base::test", "base::test1", "base::test2"] .into_iter() - .map(|name| { - TestDescAndFn { - desc: TestDesc { - name: StaticTestName(name), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})) - } - }).collect() + .map(|name| TestDescAndFn { + desc: TestDesc { + name: StaticTestName(name), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }) + .collect() } let substr = filter_tests( @@ -2127,10 +2098,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, - tx, - true, - f); + ::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } @@ -2149,10 +2117,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, - tx, - true, - f); + ::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } } diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index e22fdf77fc171..ddb5dcf2a1cd3 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -279,7 +279,6 @@ impl Stats for [f64] { } } - // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using // linear interpolation. If samples are not sorted, return nonsensical value. fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 { @@ -304,7 +303,6 @@ fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 { lo + (hi - lo) * d } - /// Winsorize a set of samples, replacing values above the `100-pct` percentile /// and below the `pct` percentile with those percentiles themselves. This is a /// way of minimizing the effect of outliers, at the cost of biasing the sample. @@ -338,15 +336,18 @@ mod tests { use std::io; macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => ({ + ($a: expr, $b: expr) => {{ let (a, b) = (&$a, &$b); - assert!((*a - *b).abs() < 1.0e-6, - "{} is not approximately equal to {}", *a, *b); - }) + assert!( + (*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", + *a, + *b + ); + }}; } fn check(samples: &[f64], summ: &Summary) { - let summ2 = Summary::new(samples); let mut w = io::sink(); @@ -911,14 +912,18 @@ mod bench { #[bench] pub fn sum_three_items(b: &mut Bencher) { - b.iter(|| { [1e20f64, 1.5f64, -1e20f64].sum(); }) + b.iter(|| { + [1e20f64, 1.5f64, -1e20f64].sum(); + }) } #[bench] pub fn sum_many_f64(b: &mut Bencher) { let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60]; let v = (0..500).map(|i| nums[i % 5]).collect::>(); - b.iter(|| { v.sum(); }) + b.iter(|| { + v.sum(); + }) } #[bench] From b996f9d60fdb1db6bd870fc7f600be4c7660f3a2 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 09:52:18 -0500 Subject: [PATCH 184/546] review comments --- src/doc/rustdoc/src/unstable-features.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index ac69cc1007d80..16356c20c7069 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -33,7 +33,7 @@ extern { fn some_func(x: T); } This is used by the error index to ensure that the samples that correspond to a given error number properly emit that error code. However, these error codes aren't guaranteed to be the only thing -that a piece of code emits from version to version, so this in unlikely to be stabilized in the +that a piece of code emits from version to version, so this is unlikely to be stabilized in the future. Attempting to use these error numbers on stable will result in the code sample being interpreted as @@ -134,9 +134,9 @@ pub struct UnixToken; In this sample, the tokens will only appear on their respective platforms, but they will both appear in documentation. -`#[doc(cfg(...))]` was introduced to be used by the standard library and is currently controlled by -a feature gate. For more information, see [its chapter in the Unstable Book][unstable-doc-cfg] and -[its tracking issue][issue-doc-cfg]. +`#[doc(cfg(...))]` was introduced to be used by the standard library and currently requires the +`#![feature(doc_cfg)]` feature gate. For more information, see [its chapter in the Unstable +Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg]. [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 @@ -155,8 +155,9 @@ In the standard library, the traits that qualify for inclusion are `Iterator`, ` special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this attribute to your own trait to include it in the "Important Traits" dialog in documentation. -The `#[doc(spotlight)]` attribute is controlled by a feature gate. For more information, see [its -chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue-spotlight]. +The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate. +For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking +issue][issue-spotlight]. [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 @@ -174,9 +175,9 @@ To prevent internal types from being included in documentation, the standard lib attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" types from these crates when building lists of trait implementations. -The `#[doc(masked)]` attribute is intended to be used internally, and is controlled by a feature -gate. For more information, see [its chapter in the Unstable Book][unstable-masked] and [its -tracking issue][issue-masked]. +The `#[doc(masked)]` attribute is intended to be used internally, and requires the +`#![feature(doc_masked)]` feature gate. For more information, see [its chapter in the Unstable +Book][unstable-masked] and [its tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 @@ -191,8 +192,9 @@ as if it were written inline. [RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 -`#[doc(include = "...")]` is currently controlled by a feature gate. For more information, see [its -chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-include]. +`#[doc(include = "...")]` currently requires the `#![feature(external_doc)]` feature gate. For more +information, see [its chapter in the Unstable Book][unstable-include] and [its tracking +issue][issue-include]. [unstable-include]: ../unstable-book/language-features/external-doc.html [issue-include]: https://github.com/rust-lang/rust/issues/44732 From c09b9f937250db0f51b705a3110f8cffdad083bb Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 12:15:24 +0100 Subject: [PATCH 185/546] Deprecate the AsciiExt trait in favor of inherent methods The trait and some of its methods are stable and will remain. Some of the newer methods are unstable and can be removed later. Fixes https://github.com/rust-lang/rust/issues/39658 --- src/libcore/tests/ascii.rs | 3 --- src/libstd/ascii.rs | 17 +++++++++++++++++ src/libstd/sys/windows/process.rs | 1 - src/libstd/sys_common/wtf8.rs | 17 +++++++---------- src/test/run-pass/issue-10683.rs | 2 -- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index 4d43067ad2cf3..950222dbcfa3f 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -9,7 +9,6 @@ // except according to those terms. use core::char::from_u32; -use std::ascii::AsciiExt; #[test] fn test_is_ascii() { @@ -143,8 +142,6 @@ macro_rules! assert_all { stringify!($what), b); } } - assert!($str.$what()); - assert!($str.as_bytes().$what()); )+ }}; ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 0837ff91c142d..6472edb0aa7d3 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -52,6 +52,7 @@ pub use core::ascii::{EscapeDefault, escape_default}; /// /// [combining character]: https://en.wikipedia.org/wiki/Combining_character #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] pub trait AsciiExt { /// Container type for copied ASCII characters. #[stable(feature = "rust1", since = "1.0.0")] @@ -84,6 +85,7 @@ pub trait AsciiExt { /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase #[stable(feature = "rust1", since = "1.0.0")] + #[allow(deprecated)] fn to_ascii_uppercase(&self) -> Self::Owned; /// Makes a copy of the value in its ASCII lower case equivalent. @@ -104,6 +106,7 @@ pub trait AsciiExt { /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase #[stable(feature = "rust1", since = "1.0.0")] + #[allow(deprecated)] fn to_ascii_lowercase(&self) -> Self::Owned; /// Checks that two values are an ASCII case-insensitive match. @@ -162,6 +165,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII uppercase character: @@ -174,6 +178,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_uppercase(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII lowercase character: @@ -186,6 +191,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_lowercase(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII alphanumeric character: @@ -199,6 +205,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII decimal digit: @@ -211,6 +218,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_digit(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII hexadecimal digit: @@ -224,6 +232,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII punctuation character: @@ -241,6 +250,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_punctuation(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII graphic character: @@ -253,6 +263,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_graphic(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII whitespace character: @@ -282,6 +293,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_whitespace(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII control character: @@ -294,6 +306,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_control(&self) -> bool { unimplemented!(); } } @@ -354,6 +367,7 @@ macro_rules! delegating_ascii_ctype_methods { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for u8 { type Owned = u8; @@ -362,6 +376,7 @@ impl AsciiExt for u8 { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for char { type Owned = char; @@ -370,6 +385,7 @@ impl AsciiExt for char { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for [u8] { type Owned = Vec; @@ -427,6 +443,7 @@ impl AsciiExt for [u8] { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for str { type Owned = String; diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index f1ab9c4760965..afa8e3e136935 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -10,7 +10,6 @@ #![unstable(feature = "process_internals", issue = "0")] -use ascii::AsciiExt; use collections::BTreeMap; use env::split_paths; use env; diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 9fff8b91f96f3..78b2bb5fe6e2f 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -27,7 +27,6 @@ use core::str::next_code_point; -use ascii::*; use borrow::Cow; use char; use fmt; @@ -871,24 +870,22 @@ impl Hash for Wtf8 { } } -impl AsciiExt for Wtf8 { - type Owned = Wtf8Buf; - - fn is_ascii(&self) -> bool { +impl Wtf8 { + pub fn is_ascii(&self) -> bool { self.bytes.is_ascii() } - fn to_ascii_uppercase(&self) -> Wtf8Buf { + pub fn to_ascii_uppercase(&self) -> Wtf8Buf { Wtf8Buf { bytes: self.bytes.to_ascii_uppercase() } } - fn to_ascii_lowercase(&self) -> Wtf8Buf { + pub fn to_ascii_lowercase(&self) -> Wtf8Buf { Wtf8Buf { bytes: self.bytes.to_ascii_lowercase() } } - fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool { + pub fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool { self.bytes.eq_ignore_ascii_case(&other.bytes) } - fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() } - fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() } + pub fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() } + pub fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() } } #[cfg(test)] diff --git a/src/test/run-pass/issue-10683.rs b/src/test/run-pass/issue-10683.rs index eb2177202a22b..d3ba477fa573e 100644 --- a/src/test/run-pass/issue-10683.rs +++ b/src/test/run-pass/issue-10683.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -use std::ascii::AsciiExt; - static NAME: &'static str = "hello world"; fn main() { From 4b673249f86604ad33d51ad9d8c7744dc5ad341b Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Mar 2018 18:01:51 +0000 Subject: [PATCH 186/546] Fix type_dependent_defs ICE on method calls --- src/librustc_passes/rvalue_promotion.rs | 12 ++++++++---- .../type-dependent-def-issue-49241.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/test/compile-fail/type-dependent-def-issue-49241.rs diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 356ad9ec11bb7..76cbc67096988 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -373,10 +373,14 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprMethodCall(..) => { - let def_id = v.tables.type_dependent_defs()[e.hir_id].def_id(); - match v.tcx.associated_item(def_id).container { - ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty), - ty::TraitContainer(_) => v.promotable = false + if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) { + let def_id = def.def_id(); + match v.tcx.associated_item(def_id).container { + ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty), + ty::TraitContainer(_) => v.promotable = false + } + } else { + v.tcx.sess.delay_span_bug(e.span, "no type-dependent def for method call"); } } hir::ExprStruct(..) => { diff --git a/src/test/compile-fail/type-dependent-def-issue-49241.rs b/src/test/compile-fail/type-dependent-def-issue-49241.rs new file mode 100644 index 0000000000000..64264999fd2f1 --- /dev/null +++ b/src/test/compile-fail/type-dependent-def-issue-49241.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let v = vec![0]; + const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error +} From b6934c91b23517c4e17d8016b6c46ffd0703eded Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 13:32:46 -0500 Subject: [PATCH 187/546] termination_trait: Put examples in error help, not label --- src/librustc/traits/error_reporting.rs | 23 +++++++++++-------- src/libstd/process.rs | 2 +- .../termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7e5dc02798dff..8572c4077142b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,20 +585,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); + let explanation = match obligation.cause.code { + ObligationCauseCode::MainFunctionType => { + "consider using `()`, or a `Result`".to_owned() + } + _ => { + format!("{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref, + trait_ref.self_ty()) + } + }; + if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" // error message, let's display it as the label! err.span_label(span, s.as_str()); - err.help(&format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.help(&explanation); } else { - err.span_label(span, - &*format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.span_label(span, explanation); } if let Some(ref s) = note { // If it has a custom "#[rustc_on_unimplemented]" note, let's display it diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a6aa3502f26bb..d5ac2d19e831f 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] + "`main` can only return types that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 053d6bbf93a2d..2cf9fdcfb4dbd 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -10,6 +10,6 @@ fn main() -> i32 { //~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` +//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 24371c27742d2..211247757cbc1 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,9 +2,9 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` | - = help: the trait `std::process::Termination` is not implemented for `char` + = help: consider using `()`, or a `Result` error: aborting due to previous error From 178652a2988d9ecd478a4116237e1d7ea6b777f7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:06:38 +0000 Subject: [PATCH 188/546] Add support to rustbuild for a 'rustc docs' component tarball --- src/bootstrap/builder.rs | 12 ++-- src/bootstrap/dist.rs | 69 +++++++++++++++++--- src/bootstrap/doc.rs | 133 ++++++++++++++++++++++++++++++--------- src/bootstrap/lib.rs | 5 ++ 4 files changed, 178 insertions(+), 41 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437eef..9f779da6f65b3 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -316,11 +316,13 @@ impl<'a> Builder<'a> { test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, - doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, - doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook), - Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts, - dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo, - dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign), + doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc, + doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample, + doc::CargoBook), + Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc, + dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src, + dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended, + dist::HashSign), Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls, install::Rustfmt, install::Analysis, install::Src, install::Rustc), } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dcb572416594e..e25a7e1852586 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -102,7 +102,7 @@ impl Step for Docs { let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); - let src = build.out.join(host).join("doc"); + let src = build.doc_out(host); cp_r(&src, &dst); let mut cmd = rust_installer(builder); @@ -120,14 +120,69 @@ impl Step for Docs { build.run(&mut cmd); t!(fs::remove_dir_all(&image)); - // As part of this step, *also* copy the docs directory to a directory which - // buildbot typically uploads. - if host == build.build { - let dst = distdir(build).join("doc").join(build.rust_package_vers()); - t!(fs::create_dir_all(&dst)); - cp_r(&src, &dst); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustcDocs { + pub stage: u32, + pub host: Interned, +} + +impl Step for RustcDocs { + type Output = PathBuf; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("src/librustc") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(RustcDocs { + stage: run.builder.top_stage, + host: run.target, + }); + } + + /// Builds the `rustc-docs` installer component. + fn run(self, builder: &Builder) -> PathBuf { + let build = builder.build; + let host = self.host; + + let name = pkgname(build, "rustc-docs"); + + println!("Dist compiler docs ({})", host); + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return distdir(build).join(format!("{}-{}.tar.gz", name, host)); } + builder.default_doc(None); + + let image = tmpdir(build).join(format!("{}-{}-image", name, host)); + let _ = fs::remove_dir_all(&image); + + let dst = image.join("share/doc/rustc/html"); + t!(fs::create_dir_all(&dst)); + let src = build.compiler_doc_out(host); + cp_r(&src, &dst); + + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rustc-Documentation") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rustc-documentation-is-installed.") + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rustc-docs") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--bulk-dirs=share/doc/rustc/html"); + build.run(&mut cmd); + t!(fs::remove_dir_all(&image)); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) } } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5bc582b3507bb..ca45adb4649af 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -483,21 +483,17 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc"); compile::std_cargo(builder, &compiler, target, &mut cargo); - // We don't want to build docs for internal std dependencies unless - // in compiler-docs mode. When not in that mode, we whitelist the crates - // for which docs must be built. - if !build.config.compiler_docs { - cargo.arg("--no-deps"); - for krate in &["alloc", "core", "std", "std_unicode"] { - cargo.arg("-p").arg(krate); - // Create all crate output directories first to make sure rustdoc uses - // relative links. - // FIXME: Cargo should probably do this itself. - t!(fs::create_dir_all(out_dir.join(krate))); - } + // Keep a whitelist so we do not build internal stdlib crates, these will be + // build by the rustc step later if enabled. + cargo.arg("--no-deps"); + for krate in &["alloc", "core", "std", "std_unicode"] { + cargo.arg("-p").arg(krate); + // Create all crate output directories first to make sure rustdoc uses + // relative links. + // FIXME: Cargo should probably do this itself. + t!(fs::create_dir_all(out_dir.join(krate))); } - build.run(&mut cargo); cp_r(&my_out, &out); } @@ -563,6 +559,81 @@ impl Step for Test { } } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct WhitelistedRustc { + stage: u32, + target: Interned, +} + +impl Step for WhitelistedRustc { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + let builder = run.builder; + run.krate("rustc-main").default_condition(builder.build.config.docs) + } + + fn make_run(run: RunConfig) { + run.builder.ensure(WhitelistedRustc { + stage: run.builder.top_stage, + target: run.target, + }); + } + + /// Generate whitelisted compiler crate documentation. + /// + /// This will generate all documentation for crates that are whitelisted + /// to be included in the standard documentation. This documentation is + /// included in the standard Rust documentation, so we should always + /// document it and symlink to merge with the rest of the std and test + /// documentation. We don't build other compiler documentation + /// here as we want to be able to keep it separate from the standard + /// documentation. This is largely just a wrapper around `cargo doc`. + fn run(self, builder: &Builder) { + let build = builder.build; + let stage = self.stage; + let target = self.target; + println!("Documenting stage{} whitelisted compiler ({})", stage, target); + let out = build.doc_out(target); + t!(fs::create_dir_all(&out)); + let compiler = builder.compiler(stage, build.build); + let rustdoc = builder.rustdoc(compiler.host); + let compiler = if build.force_use_stage1(compiler, target) { + builder.compiler(1, compiler.host) + } else { + compiler + }; + + // Build libstd docs so that we generate relative links + builder.ensure(Std { stage, target }); + + builder.ensure(compile::Rustc { compiler, target }); + let out_dir = build.stage_out(compiler, Mode::Librustc) + .join(target).join("doc"); + + // See docs in std above for why we symlink + let my_out = build.crate_doc_out(target); + build.clear_if_dirty(&my_out, &rustdoc); + t!(symlink_dir_force(&my_out, &out_dir)); + + let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); + compile::rustc_cargo(build, &mut cargo); + + // We don't want to build docs for internal compiler dependencies in this + // step (there is another step for that). Therefore, we whitelist the crates + // for which docs must be built. + cargo.arg("--no-deps"); + for krate in &["proc_macro"] { + cargo.arg("-p").arg(krate); + } + + build.run(&mut cargo); + cp_r(&my_out, &out); + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustc { stage: u32, @@ -586,16 +657,18 @@ impl Step for Rustc { }); } - /// Generate all compiler documentation. + /// Generate compiler documentation. /// - /// This will generate all documentation for the compiler libraries and their - /// dependencies. This is largely just a wrapper around `cargo doc`. + /// This will generate all documentation for compiler and dependencies. + /// Compiler documentation is distributed separately, so we make sure + /// we do not merge it with the other documentation from std, test and + /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder) { let build = builder.build; let stage = self.stage; let target = self.target; println!("Documenting stage{} compiler ({})", stage, target); - let out = build.doc_out(target); + let out = build.compiler_doc_out(target); t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, build.build); let rustdoc = builder.rustdoc(compiler.host); @@ -605,6 +678,11 @@ impl Step for Rustc { compiler }; + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return; + } + // Build libstd docs so that we generate relative links builder.ensure(Std { stage, target }); @@ -613,6 +691,12 @@ impl Step for Rustc { .join(target).join("doc"); // See docs in std above for why we symlink + // + // This step must happen after other documentation steps. This + // invariant ensures that compiler documentation is not included + // in the standard documentation tarballs but that all the + // documentation from the standard documentation tarballs is included + // in the compiler documentation tarball. let my_out = build.crate_doc_out(target); build.clear_if_dirty(&my_out, &rustdoc); t!(symlink_dir_force(&my_out, &out_dir)); @@ -620,18 +704,9 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - if build.config.compiler_docs { - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); - } else { - // Like with libstd above if compiler docs aren't enabled then we're not - // documenting internal dependencies, so we have a whitelist. - cargo.arg("--no-deps"); - for krate in &["proc_macro"] { - cargo.arg("-p").arg(krate); - } - } + // src/rustc/Cargo.toml contains a bin crate called rustc which + // would otherwise overwrite the docs for the real rustc lib crate. + cargo.arg("-p").arg("rustc_driver"); build.run(&mut cargo); cp_r(&my_out, &out); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b778ba33d89cc..b2c8ac24d72d8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -511,6 +511,11 @@ impl Build { self.out.join(&*target).join("doc") } + /// Output directory for all documentation for a target + fn compiler_doc_out(&self, target: Interned) -> PathBuf { + self.out.join(&*target).join("compiler-doc") + } + /// Output directory for some generated md crate documentation for a target (temporary) fn md_doc_out(&self, target: Interned) -> Interned { INTERNER.intern_path(self.out.join(&*target).join("md-doc")) From 1392179cdc9c96e75353771959c246553b918d57 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:07:16 +0000 Subject: [PATCH 189/546] Configure the dist-x86_64-linux builder to produce compiler documentation --- src/ci/docker/dist-x86_64-linux/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index 3b98b0aa926bd..28c97e8c6dbf9 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -84,7 +84,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-sanitizers \ - --enable-profiler + --enable-profiler \ + --enable-compiler-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs From 395570857686648f76ba801d3cde24e4cb906934 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 16:31:20 -0400 Subject: [PATCH 190/546] WIP tweak example to include feature gate --- src/librustc/diagnostics.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index fad1803259286..4c2dd8c271862 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2081,6 +2081,8 @@ appear within the `impl Trait` itself. Erroneous code example: ```compile-fail,E0909 +#![feature(conservative_impl_trait)] + use std::cell::Cell; trait Trait<'a> { } From 2ba41e9d7943912dafe2f508c97d4083249d97a4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 15:43:06 -0500 Subject: [PATCH 191/546] update stdsimd --- src/stdsimd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdsimd b/src/stdsimd index ab9356f2af650..bcb720e55861c 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit ab9356f2af650815d339d77306f0d09c44d531ad +Subproject commit bcb720e55861c38db47f2ebdf26b7198338cb39d From 3272b63f3458c9ca7a4680b512cc0dfd79e763e3 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Mar 2018 21:00:38 +0000 Subject: [PATCH 192/546] Moved test to ui --- .../type-dependent-def-issue-49241.rs | 0 .../ui/type-dependent-def-issue-49241.stderr | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+) rename src/test/{compile-fail => ui}/type-dependent-def-issue-49241.rs (100%) create mode 100644 src/test/ui/type-dependent-def-issue-49241.stderr diff --git a/src/test/compile-fail/type-dependent-def-issue-49241.rs b/src/test/ui/type-dependent-def-issue-49241.rs similarity index 100% rename from src/test/compile-fail/type-dependent-def-issue-49241.rs rename to src/test/ui/type-dependent-def-issue-49241.rs diff --git a/src/test/ui/type-dependent-def-issue-49241.stderr b/src/test/ui/type-dependent-def-issue-49241.stderr new file mode 100644 index 0000000000000..f00edccae5d50 --- /dev/null +++ b/src/test/ui/type-dependent-def-issue-49241.stderr @@ -0,0 +1,18 @@ +error[E0434]: can't capture dynamic environment in a fn item + --> $DIR/type-dependent-def-issue-49241.rs:13:22 + | +LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + | ^ + | + = help: use the `|| { ... }` closure form instead + +error[E0080]: constant evaluation error + --> $DIR/type-dependent-def-issue-49241.rs:14:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error + | ^ encountered constants with type errors, stopping evaluation + +error: aborting due to 2 previous errors + +Some errors occurred: E0080, E0434. +For more information about an error, try `rustc --explain E0080`. From 78bcbb0f96e3c65742fe3f6c5fb4c68f28dcf99c Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 02:29:01 +0800 Subject: [PATCH 193/546] Download the GCC artifacts from the HTTP server instead of FTP server. The former seems much more stable, in case the cache becomes invalidated. --- src/ci/docker/dist-i686-linux/build-gcc.sh | 17 +++++++++++++++++ src/ci/docker/dist-x86_64-linux/build-gcc.sh | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/ci/docker/dist-i686-linux/build-gcc.sh b/src/ci/docker/dist-i686-linux/build-gcc.sh index 6b991bb59e4b0..08020e533ff19 100755 --- a/src/ci/docker/dist-i686-linux/build-gcc.sh +++ b/src/ci/docker/dist-i686-linux/build-gcc.sh @@ -17,6 +17,23 @@ GCC=4.8.5 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf - cd gcc-$GCC + +# FIXME(#49246): Remove the `sed` below. +# +# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this +# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue: +# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection +# timed out" error, and even when the download completed, the file is usually corrupted. This causes +# nothing to be landed that day. +# +# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability +# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third +# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the +# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server +# instead here. +# +sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites + ./contrib/download_prerequisites mkdir ../gcc-build cd ../gcc-build diff --git a/src/ci/docker/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/dist-x86_64-linux/build-gcc.sh index 6b991bb59e4b0..08020e533ff19 100755 --- a/src/ci/docker/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/dist-x86_64-linux/build-gcc.sh @@ -17,6 +17,23 @@ GCC=4.8.5 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf - cd gcc-$GCC + +# FIXME(#49246): Remove the `sed` below. +# +# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this +# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue: +# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection +# timed out" error, and even when the download completed, the file is usually corrupted. This causes +# nothing to be landed that day. +# +# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability +# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third +# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the +# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server +# instead here. +# +sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites + ./contrib/download_prerequisites mkdir ../gcc-build cd ../gcc-build From 56a19a9eec0ae2cd1b1914cfe9854e1c1028f329 Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 04:07:29 +0800 Subject: [PATCH 194/546] Handle redirects correctly. --- src/ci/docker/dist-i686-linux/build-git.sh | 2 +- src/ci/docker/dist-x86_64-linux/build-git.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-i686-linux/build-git.sh b/src/ci/docker/dist-i686-linux/build-git.sh index ff62a68629a8b..aa31f50ba0343 100755 --- a/src/ci/docker/dist-i686-linux/build-git.sh +++ b/src/ci/docker/dist-i686-linux/build-git.sh @@ -12,7 +12,7 @@ set -ex source shared.sh -curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - +curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - cd git-2.10.0 make configure diff --git a/src/ci/docker/dist-x86_64-linux/build-git.sh b/src/ci/docker/dist-x86_64-linux/build-git.sh index ff62a68629a8b..aa31f50ba0343 100755 --- a/src/ci/docker/dist-x86_64-linux/build-git.sh +++ b/src/ci/docker/dist-x86_64-linux/build-git.sh @@ -12,7 +12,7 @@ set -ex source shared.sh -curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - +curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - cd git-2.10.0 make configure From 99b49b532c8fa2b45179ff346089d9527d05a7a6 Mon Sep 17 00:00:00 2001 From: Mrowqa Date: Wed, 21 Mar 2018 23:11:27 +0100 Subject: [PATCH 195/546] Now it compiles --- src/librustc/hir/lowering.rs | 3 ++- src/librustc/ich/impls_hir.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a35af56bd97b1..f6bdfde15fc5f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -809,7 +809,7 @@ impl<'a> LoweringContext<'a> { } } - fn lower_attrs(&mut self, attrs: &Vec) -> hir::HirVec { + fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec { attrs.iter().map(|a| self.lower_attr(a)).collect::>().into() } @@ -1019,6 +1019,7 @@ impl<'a> LoweringContext<'a> { span, pure_wrt_drop: false, synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + attrs: P::new(), }); hir::TyPath(hir::QPath::Resolved(None, P(hir::Path { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index e764cedd658b5..774b1442b7101 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -203,7 +203,8 @@ impl_stable_hash_for!(struct hir::TyParam { default, span, pure_wrt_drop, - synthetic + synthetic, + attrs }); impl_stable_hash_for!(enum hir::GenericParam { From 7c442e5c9b46de225f8903352b7dfc5552b297de Mon Sep 17 00:00:00 2001 From: Murarth Date: Wed, 21 Mar 2018 10:47:03 -0700 Subject: [PATCH 196/546] Stabilize method `String::retain` --- .../src/library-features/string-retain.md | 23 ------------------- src/liballoc/string.rs | 4 +--- 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/string-retain.md diff --git a/src/doc/unstable-book/src/library-features/string-retain.md b/src/doc/unstable-book/src/library-features/string-retain.md deleted file mode 100644 index 049444aa49bdd..0000000000000 --- a/src/doc/unstable-book/src/library-features/string-retain.md +++ /dev/null @@ -1,23 +0,0 @@ -# `string_retain` - -The tracking issue for this feature is: [#43874] - -[#43874]: https://github.com/rust-lang/rust/issues/43874 - ------------------------- - -Retains only the characters specified by the predicate. - -In other words, remove all characters `c` such that `f(c)` returns `false`. -This method operates in place and preserves the order of the retained -characters. - -```rust -#![feature(string_retain)] - -let mut s = String::from("f_o_ob_ar"); - -s.retain(|c| c != '_'); - -assert_eq!(s, "foobar"); -``` diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 9fec90914985d..52ff6357c5b73 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1177,8 +1177,6 @@ impl String { /// # Examples /// /// ``` - /// #![feature(string_retain)] - /// /// let mut s = String::from("f_o_ob_ar"); /// /// s.retain(|c| c != '_'); @@ -1186,7 +1184,7 @@ impl String { /// assert_eq!(s, "foobar"); /// ``` #[inline] - #[unstable(feature = "string_retain", issue = "43874")] + #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(char) -> bool { From 48c4e352d38479a5adcd664bef3a208640ba5cbc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 19:22:41 -0400 Subject: [PATCH 197/546] WIP do not use in-band lifetimes --- src/librustc/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4c2dd8c271862..10156d22501e7 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2087,7 +2087,7 @@ use std::cell::Cell; trait Trait<'a> { } -impl Trait<'b> for Cell<&'a u32> { } +impl<'a, 'b> Trait<'b> for Cell<&'a u32> { } fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> where 'x: 'y From 2e8a1abc2df44d8e71e52bf92b658438707564ea Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 19:23:29 -0400 Subject: [PATCH 198/546] also fix the Fixed code --- src/librustc/diagnostics.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 10156d22501e7..2fd875c344767 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2109,11 +2109,13 @@ type. For example, changing the return type to `impl Trait<'y> + 'x` would work: ``` +#![feature(conservative_impl_trait)] + use std::cell::Cell; trait Trait<'a> { } -impl Trait<'b> for Cell<&'a u32> { } +impl<'a,'b> Trait<'b> for Cell<&'a u32> { } fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x where 'x: 'y From b3fb0d10f03fe7d8f2eaa705a972b0f45e1723db Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 19:57:10 -0500 Subject: [PATCH 199/546] add target_feature items to doc_cfg rustdoc test --- src/test/rustdoc/doc-cfg.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs index 8499e5c741ee0..ea8a13b034beb 100644 --- a/src/test/rustdoc/doc-cfg.rs +++ b/src/test/rustdoc/doc-cfg.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(doc_cfg)] +#![feature(target_feature, cfg_target_feature)] // @has doc_cfg/struct.Portable.html // @!has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' '' @@ -45,3 +46,26 @@ pub mod unix_only { fn unix_and_arm_only_function() {} } } + +// tagging a function with `#[target_feature]` creates a doc(cfg(target_feature)) node for that +// item as well + +// the portability header is different on the module view versus the full view +// @has doc_cfg/index.html +// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\Aavx\Z' + +// @has doc_cfg/fn.uses_target_feature.html +// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// 'This is supported with target feature avx only.' +#[target_feature(enable = "avx")] +pub unsafe fn uses_target_feature() { + content::should::be::irrelevant(); +} + +// @has doc_cfg/fn.uses_cfg_target_feature.html +// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// 'This is supported with target feature avx only.' +#[doc(cfg(target_feature = "avx"))] +pub fn uses_cfg_target_feature() { + uses_target_feature(); +} From c116b0e8296dc4198408a708fae53f47fc1e51c6 Mon Sep 17 00:00:00 2001 From: Maxwell Borden Date: Wed, 21 Mar 2018 18:11:57 -0700 Subject: [PATCH 200/546] Fixed clockwise/counter-clockwise in atan2 documentation in f32 and f64 and included that it returns radians --- src/libstd/f32.rs | 9 +++++---- src/libstd/f64.rs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index a760922115aef..ceb019bc95b4c 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -780,7 +780,7 @@ impl f32 { unsafe { cmath::atanf(self) } } - /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). + /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. /// /// * `x = 0`, `y = 0`: `0` /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` @@ -791,12 +791,13 @@ impl f32 { /// use std::f32; /// /// let pi = f32::consts::PI; - /// // All angles from horizontal right (+x) - /// // 45 deg counter-clockwise + /// // Positive angles measured counter-clockwise + /// // from positive x axis + /// // -pi/4 radians (45 deg clockwise) /// let x1 = 3.0f32; /// let y1 = -3.0f32; /// - /// // 135 deg clockwise + /// // 3pi/4 radians (135 deg counter-clockwise) /// let x2 = -3.0f32; /// let y2 = 3.0f32; /// diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 6f34f176a9711..97adf108b73b0 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -716,7 +716,7 @@ impl f64 { unsafe { cmath::atan(self) } } - /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). + /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. /// /// * `x = 0`, `y = 0`: `0` /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` @@ -727,12 +727,13 @@ impl f64 { /// use std::f64; /// /// let pi = f64::consts::PI; - /// // All angles from horizontal right (+x) - /// // 45 deg counter-clockwise + /// // Positive angles measured counter-clockwise + /// // from positive x axis + /// // -pi/4 radians (45 deg clockwise) /// let x1 = 3.0_f64; /// let y1 = -3.0_f64; /// - /// // 135 deg clockwise + /// // 3pi/4 radians (135 deg counter-clockwise) /// let x2 = -3.0_f64; /// let y2 = 3.0_f64; /// From 9f792e199bc53a75afdad72547a151a0bc86ec5d Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 09:02:51 +0800 Subject: [PATCH 201/546] Temporarily disable dist-ing RLS, Rustfmt and Clippy. Unfortunately we don't have sufficient time to rebuild the cache *and* distribute everything in `dist-x86_64-linux alt`, the debug assertions are really slow. We will re-enable them after the PR has been successfully merged, thus successfully updating the cache (freeing up 40 minutes), giving us enough time to build these tools. --- src/ci/run.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a92..afa6d1fa0aea5 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -105,7 +105,15 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then - sh -x -c "$SCRIPT" + # FIXME(#49246): Re-enable these tools after #49246 has been merged and thus fixing the cache. + if [ "$DEPLOY_ALT" = 1 ]; then + sh -x -c "$SCRIPT \ + --exclude src/tools/rls \ + --exclude src/tools/rustfmt \ + --exclude src/tools/clippy" + else + sh -x -c "$SCRIPT" + fi else do_make() { travis_fold start "make-$1" From 2b13d95da02d318c12814261dd36edd91ae6879e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 23:28:48 -0500 Subject: [PATCH 202/546] termination_trait: Make error message more helpful --- src/librustc/traits/error_reporting.rs | 16 +++++++--------- src/libstd/process.rs | 5 +++-- .../termination-trait-main-i32.rs | 5 +++-- .../termination-trait-not-satisfied.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8572c4077142b..47e6b0feceae3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,17 +585,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); - let explanation = match obligation.cause.code { - ObligationCauseCode::MainFunctionType => { + let explanation = + if obligation.cause.code == ObligationCauseCode::MainFunctionType { "consider using `()`, or a `Result`".to_owned() - } - _ => { + } else { format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty()) - } - }; + pre_message, + trait_ref, + trait_ref.self_ty()) + }; if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831f..c877bf6aa35cd 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1442,8 +1442,9 @@ pub fn id() -> u32 { /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] -#[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] +#[rustc_on_unimplemented( + message="`main` has invalid return type `{Self}`", + label="`main` can only return types that implement {Termination}")] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 2cf9fdcfb4dbd..0e6ddf7c92f1a 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -9,7 +9,8 @@ // except according to those terms. fn main() -> i32 { -//~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` +//~^ ERROR `main` has invalid return type `i32` +//~| NOTE `main` can only return types that implement std::process::Termination +//~| HELP consider using `()`, or a `Result` 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index bab02fc559706..b5f5472b49290 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -10,6 +10,6 @@ struct ReturnType {} -fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied +fn main() -> ReturnType { //~ ERROR `main` has invalid return type `ReturnType` ReturnType {} } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 211247757cbc1..5109d9275c58b 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `char: std::process::Termination` is not satisfied +error[E0277]: `main` has invalid return type `char` --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination | = help: consider using `()`, or a `Result` From b48a26cdd1d086a3ca7ffae35b73b72f9ce85b8f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 09:56:04 +0100 Subject: [PATCH 203/546] Produce nice array lengths on a best effort basis --- src/librustc/traits/error_reporting.rs | 16 ++++++++++--- src/librustc/util/ppaux.rs | 4 ++-- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 2 +- .../ui/unevaluated_fixed_size_array_len.rs | 23 +++++++++++++++++++ .../unevaluated_fixed_size_array_len.stderr | 17 ++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.rs create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ab3c619dcdcd0..79d5cf7935941 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -443,10 +443,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { 4 }; + + let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }); + err.help(&format!("the following implementations were found:{}{}", - &impl_candidates[0..end].iter().map(|candidate| { - format!("\n {:?}", candidate) - }).collect::(), + &impl_candidates[0..end].iter().map(normalize).collect::(), if impl_candidates.len() > 5 { format!("\nand {} others", impl_candidates.len() - 4) } else { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2c3ee1ec285a9..056f1278c47c7 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1177,8 +1177,8 @@ define_print! { ConstVal::Value(Value::ByVal(PrimVal::Bytes(sz))) => { write!(f, "{}", sz)?; } - ConstVal::Unevaluated(_def_id, substs) => { - write!(f, "", &substs[..])?; + ConstVal::Unevaluated(_def_id, _substs) => { + write!(f, "_")?; } _ => { write!(f, "{:?}", sz)?; diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 45dce3d8740d1..169a12ef92e98 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -46,7 +46,7 @@ error[E0223]: ambiguous associated type LL | type A = [u8; 4]::AssocTy; | ^^^^^^^^^^^^^^^^ ambiguous associated type | - = note: specify the type using the syntax `<[u8; ] as Trait>::AssocTy` + = note: specify the type using the syntax `<[u8; _] as Trait>::AssocTy` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:15:10 diff --git a/src/test/ui/unevaluated_fixed_size_array_len.rs b/src/test/ui/unevaluated_fixed_size_array_len.rs new file mode 100644 index 0000000000000..a6ed9f32106fb --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49208 + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() //~ ERROR E0277 +} diff --git a/src/test/ui/unevaluated_fixed_size_array_len.stderr b/src/test/ui/unevaluated_fixed_size_array_len.stderr new file mode 100644 index 0000000000000..6e959da99397b --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied + --> $DIR/unevaluated_fixed_size_array_len.rs:22:5 + | +LL | <[(); 0] as Foo>::foo() //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` + | + = help: the following implementations were found: + <[(); 1] as Foo> +note: required by `Foo::foo` + --> $DIR/unevaluated_fixed_size_array_len.rs:14:5 + | +LL | fn foo(); + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 613fb8bc2c5277b9b9a14bdba3939bb6042d91ec Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 22 Mar 2018 10:06:17 +0100 Subject: [PATCH 204/546] document format_args! - fix trailing whitespace --- src/libcore/fmt/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 0363714c31b5c..62994ed15cc6d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1682,7 +1682,7 @@ impl<'a> Formatter<'a> { /// /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R)); /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V); - /// + /// /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R> /// where /// L: 'a + fmt::Debug, R: 'a + fmt::Debug From b272749197a8a4c949b43d4661909b189066f4ae Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 12:38:40 +0100 Subject: [PATCH 205/546] Fix the conversion between bit representations and i128 representations --- src/librustc/ty/layout.rs | 8 +++- src/librustc/ty/mod.rs | 23 +++-------- src/librustc/ty/util.rs | 46 ++++++++++++--------- src/test/run-pass/ctfe/signed_enum_discr.rs | 27 ++++++++++++ 4 files changed, 66 insertions(+), 38 deletions(-) create mode 100644 src/test/run-pass/ctfe/signed_enum_discr.rs diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 3a3f10cb87db4..029dd6f1fb466 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1544,11 +1544,17 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } let (mut min, mut max) = (i128::max_value(), i128::min_value()); + let discr_type = def.repr.discr_type(); + let bits = Integer::from_attr(tcx, discr_type).size().bits(); for (i, discr) in def.discriminants(tcx).enumerate() { if variants[i].iter().any(|f| f.abi == Abi::Uninhabited) { continue; } - let x = discr.val as i128; + let mut x = discr.val as i128; + if discr_type.is_signed() { + // sign extend the raw representation to be an i128 + x = (x << (128 - bits)) >> (128 - bits); + } if x < min { min = x; } if x > max { max = x; } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c915022351925..9ffdccefae585 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1886,7 +1886,6 @@ impl<'a, 'gcx, 'tcx> AdtDef { ) -> Option> { let param_env = ParamEnv::empty(); let repr_type = self.repr.discr_type(); - let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits(); let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); let instance = ty::Instance::new(expr_did, substs); let cid = GlobalId { @@ -1896,25 +1895,13 @@ impl<'a, 'gcx, 'tcx> AdtDef { match tcx.const_eval(param_env.and(cid)) { Ok(&ty::Const { val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))), - .. + ty, }) => { trace!("discriminants: {} ({:?})", b, repr_type); - let ty = repr_type.to_ty(tcx); - if repr_type.is_signed() { - let val = b as i128; - // sign extend to i128 - let amt = 128 - bit_size; - let val = (val << amt) >> amt; - Some(Discr { - val: val as u128, - ty, - }) - } else { - Some(Discr { - val: b, - ty, - }) - } + Some(Discr { + val: b, + ty, + }) }, Ok(&ty::Const { val: ConstVal::Value(other), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 91d460a96f785..afe977d10baac 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -39,16 +39,24 @@ use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug)] pub struct Discr<'tcx> { + /// bit representation of the discriminant, so `-128i8` is `0xFF_u128` pub val: u128, pub ty: Ty<'tcx> } impl<'tcx> fmt::Display for Discr<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - if self.ty.is_signed() { - write!(fmt, "{}", self.val as i128) - } else { - write!(fmt, "{}", self.val) + match self.ty.sty { + ty::TyInt(ity) => { + let bits = ty::tls::with(|tcx| { + Integer::from_attr(tcx, SignedInt(ity)).size().bits() + }); + let x = self.val as i128; + // sign extend the raw representation to be an i128 + let x = (x << (128 - bits)) >> (128 - bits); + write!(fmt, "{}", x) + }, + _ => write!(fmt, "{}", self.val), } } } @@ -64,15 +72,18 @@ impl<'tcx> Discr<'tcx> { TyUint(uty) => (Integer::from_attr(tcx, UnsignedInt(uty)), false), _ => bug!("non integer discriminant"), }; + + let bit_size = int.size().bits(); + let amt = 128 - bit_size; if signed { - let (min, max) = match int { - Integer::I8 => (i8::min_value() as i128, i8::max_value() as i128), - Integer::I16 => (i16::min_value() as i128, i16::max_value() as i128), - Integer::I32 => (i32::min_value() as i128, i32::max_value() as i128), - Integer::I64 => (i64::min_value() as i128, i64::max_value() as i128), - Integer::I128 => (i128::min_value(), i128::max_value()), + let sext = |u| { + let i = u as i128; + (i << amt) >> amt }; - let val = self.val as i128; + let min = sext(1_u128 << (bit_size - 1)); + let max = i128::max_value() >> amt; + let val = sext(self.val); + assert!(n < (i128::max_value() as u128)); let n = n as i128; let oflo = val > max - n; let val = if oflo { @@ -80,22 +91,19 @@ impl<'tcx> Discr<'tcx> { } else { val + n }; + // zero the upper bits + let val = val as u128; + let val = (val << amt) >> amt; (Self { val: val as u128, ty: self.ty, }, oflo) } else { - let (min, max) = match int { - Integer::I8 => (u8::min_value() as u128, u8::max_value() as u128), - Integer::I16 => (u16::min_value() as u128, u16::max_value() as u128), - Integer::I32 => (u32::min_value() as u128, u32::max_value() as u128), - Integer::I64 => (u64::min_value() as u128, u64::max_value() as u128), - Integer::I128 => (u128::min_value(), u128::max_value()), - }; + let max = u128::max_value() >> amt; let val = self.val; let oflo = val > max - n; let val = if oflo { - min + (n - (max - val) - 1) + n - (max - val) - 1 } else { val + n }; diff --git a/src/test/run-pass/ctfe/signed_enum_discr.rs b/src/test/run-pass/ctfe/signed_enum_discr.rs new file mode 100644 index 0000000000000..7049d28a87085 --- /dev/null +++ b/src/test/run-pass/ctfe/signed_enum_discr.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49181 + +#[derive(Eq, PartialEq)] +#[repr(i8)] +pub enum A { + B = -1, + C = 1, +} + +pub const D: A = A::B; + +fn main() { + match A::C { + D => {}, + _ => {} + } +} From de1c929adaeb5b1e466b6f8485a9f7cf92969185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Thu, 22 Mar 2018 11:27:59 +0100 Subject: [PATCH 206/546] Use GNU version of fgrep/egrep tool if available It is mostly for BSD system. Some tests (run-make/issue-35164 and run-make/cat-and-grep-sanity-check) are failing with BSD fgrep, whereas they pass with gnu version (gfgrep). --- src/etc/cat-and-grep.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/etc/cat-and-grep.sh b/src/etc/cat-and-grep.sh index ef9884d2e980d..361e8d8e60eed 100755 --- a/src/etc/cat-and-grep.sh +++ b/src/etc/cat-and-grep.sh @@ -63,6 +63,11 @@ done shift $((OPTIND - 1)) +# use gnu version of tool if available (for bsd) +if command -v "g${GREPPER}"; then + GREPPER="g${GREPPER}" +fi + LOG=$(mktemp -t cgrep.XXXXXX) trap "rm -f $LOG" EXIT From a1a3bf2b31af680ffbbed4270efc0a2cda80ca87 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 22 Mar 2018 14:38:37 +0100 Subject: [PATCH 207/546] Fix DefKey lookup for proc-macro crates. --- src/librustc_metadata/decoder.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b0c945fbf2a05..1ea009a4e9116 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -14,7 +14,8 @@ use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; use schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; -use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; +use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, + DisambiguatedDefPathData}; use rustc::hir; use rustc::middle::cstore::{LinkagePreference, ExternConstBody, ExternBodyNestedBodies}; @@ -1115,7 +1116,23 @@ impl<'a, 'tcx> CrateMetadata { #[inline] pub fn def_key(&self, index: DefIndex) -> DefKey { - self.def_path_table.def_key(index) + if !self.is_proc_macro(index) { + self.def_path_table.def_key(index) + } else { + // FIXME(#49271) - It would be better if the DefIds were consistent + // with the DefPathTable, but for proc-macro crates + // they aren't. + let name = self.proc_macros + .as_ref() + .unwrap()[index.to_proc_macro_index()].0; + DefKey { + parent: Some(CRATE_DEF_INDEX), + disambiguated_data: DisambiguatedDefPathData { + data: DefPathData::MacroDef(name.as_str()), + disambiguator: 0, + } + } + } } // Returns the path leading to the thing with this `id`. From 9839e5fa103d117cbdb936e8594ba832e1eeb320 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 15:05:12 +0100 Subject: [PATCH 208/546] Remove slow HashSet during miri stack frame creation --- src/librustc_mir/interpret/eval_context.rs | 40 ++++++---------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index c236ce2abc5f0..ee8419404ca47 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::fmt::Write; use rustc::hir::def_id::DefId; @@ -383,40 +382,23 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M ) -> EvalResult<'tcx> { ::log_settings::settings().indentation += 1; - /// Return the set of locals that have a storage annotation anywhere - fn collect_storage_annotations<'mir, 'tcx>(mir: &'mir mir::Mir<'tcx>) -> HashSet { - use rustc::mir::StatementKind::*; - - let mut set = HashSet::new(); - for block in mir.basic_blocks() { - for stmt in block.statements.iter() { - match stmt.kind { - StorageLive(local) | - StorageDead(local) => { - set.insert(local); - } - _ => {} - } - } - } - set - } - // Subtract 1 because `local_decls` includes the ReturnMemoryPointer, but we don't store a local // `Value` for that. let num_locals = mir.local_decls.len() - 1; - let locals = { - let annotated_locals = collect_storage_annotations(mir); - let mut locals = vec![None; num_locals]; - for i in 0..num_locals { - let local = mir::Local::new(i + 1); - if !annotated_locals.contains(&local) { - locals[i] = Some(Value::ByVal(PrimVal::Undef)); + let mut locals = vec![Some(Value::ByVal(PrimVal::Undef)); num_locals]; + trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); + for block in mir.basic_blocks() { + for stmt in block.statements.iter() { + use rustc::mir::StatementKind::{StorageDead, StorageLive}; + match stmt.kind { + StorageLive(local) | StorageDead(local) => if local.index() > 0 { + locals[local.index() - 1] = None; + }, + _ => {} } } - locals - }; + } self.stack.push(Frame { mir, From a4bc8590117f313ab2c895ab91f183f368369e2b Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 17:52:57 +0800 Subject: [PATCH 209/546] Revert "Temporarily disable dist-ing RLS, Rustfmt and Clippy." This reverts commit 9f792e199bc53a75afdad72547a151a0bc86ec5d. --- src/ci/run.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index afa6d1fa0aea5..e3f38e4834a92 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -105,15 +105,7 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then - # FIXME(#49246): Re-enable these tools after #49246 has been merged and thus fixing the cache. - if [ "$DEPLOY_ALT" = 1 ]; then - sh -x -c "$SCRIPT \ - --exclude src/tools/rls \ - --exclude src/tools/rustfmt \ - --exclude src/tools/clippy" - else - sh -x -c "$SCRIPT" - fi + sh -x -c "$SCRIPT" else do_make() { travis_fold start "make-$1" From bfb94ac5f43ac7fb0736185421f6135fe7043a2e Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Thu, 22 Mar 2018 10:34:51 -0500 Subject: [PATCH 210/546] Clean up raw identifier handling when recovering tokens from AST. --- src/libsyntax/ext/quote.rs | 5 +++-- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/token.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 090b9a3544630..540a03ff032ff 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -238,8 +238,9 @@ pub mod rt { if i > 0 { inner.push(TokenTree::Token(self.span, token::Colon).into()); } - inner.push(TokenTree::Token(self.span, - token::Ident(segment.identifier, false)).into()); + inner.push(TokenTree::Token( + self.span, token::Token::from_ast_ident(segment.identifier) + ).into()); } inner.push(self.tokens.clone()); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0f5855a32259c..3f01d5ec6dd87 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -169,7 +169,7 @@ pub fn transcribe(cx: &ExtCtxt, Ident { ctxt: ident.ctxt.apply_mark(cx.current_expansion.mark), ..ident }; sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); result.push(TokenTree::Token(sp, token::Dollar).into()); - result.push(TokenTree::Token(sp, token::Ident(ident, false)).into()); + result.push(TokenTree::Token(sp, token::Token::from_ast_ident(ident)).into()); } } quoted::TokenTree::Delimited(mut span, delimited) => { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 4e7a282adc584..7798a7a77ee6c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -236,7 +236,7 @@ impl Token { /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. pub fn from_ast_ident(ident: ast::Ident) -> Token { - Ident(ident, is_reserved_ident(ident)) + Ident(ident, is_reserved_ident(ident) && !is_path_segment_keyword(ident)) } /// Returns `true` if the token starts with '>'. From 57f9c4d6d9ba7d48b9f64193dd037a54e11ef7b4 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Thu, 22 Mar 2018 10:35:49 -0500 Subject: [PATCH 211/546] Clarify description of raw_identifiers feature flag. --- src/libsyntax/feature_gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 153e42c8214f8..c64e0f514de6d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -453,7 +453,7 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), - // Raw identifiers allowing keyword names to be used + // Allows keywords to be escaped for use as identifiers (active, raw_identifiers, "1.26.0", Some(48589), None), ); From 0d278ca6a887b0adc2b1b852c09f24892b8397b4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 22 Mar 2018 15:55:57 +0000 Subject: [PATCH 212/546] Use FunctionRetTy::Default rather than an explicit TyKind::Infer for lambda-building This prevents explicit `-> _` return type annotations for closures generated by `lambda`. --- src/librustc_allocator/expand.rs | 2 +- src/libsyntax/ext/build.rs | 10 +++++----- src/libsyntax/test.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 02e704b684185..ee38cca7828be 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -145,7 +145,7 @@ impl<'a> AllocFnFactory<'a> { let result = self.call_allocator(method.name, args); let (output_ty, output_expr) = self.ret_ty(&method.output, &mut abi_args, mk, result); - let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, output_ty), + let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)), Unsafety::Unsafe, dummy_spanned(Constness::NotConst), Abi::Rust, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9b53553bf69d7..269517e998f5b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -214,7 +214,7 @@ pub trait AstBuilder { fn arg(&self, span: Span, name: Ident, ty: P) -> ast::Arg; // FIXME unused self - fn fn_decl(&self, inputs: Vec , output: P) -> P; + fn fn_decl(&self, inputs: Vec , output: ast::FunctionRetTy) -> P; fn item_fn_poly(&self, span: Span, @@ -924,7 +924,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { -> P { let fn_decl = self.fn_decl( ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), - self.ty_infer(span)); + ast::FunctionRetTy::Default(span)); // FIXME -- We are using `span` as the span of the `|...|` // part of the lambda, but it probably (maybe?) corresponds to @@ -970,10 +970,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // FIXME unused self - fn fn_decl(&self, inputs: Vec, output: P) -> P { + fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { P(ast::FnDecl { inputs, - output: ast::FunctionRetTy::Ty(output), + output, variadic: false }) } @@ -1003,7 +1003,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), - ast::ItemKind::Fn(self.fn_decl(inputs, output), + ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)), ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), Abi::Rust, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9edfa767d3195..67d3adc83f2d2 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -547,7 +547,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { // pub fn main() { ... } let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); let main_body = ecx.block(sp, vec![call_test_main]); - let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty), + let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), ::abi::Abi::Rust, ast::Generics::default(), main_body); diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 49c372b751b50..3935f1722b615 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -962,7 +962,7 @@ impl<'a> MethodDef<'a> { let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); let method_ident = cx.ident_of(self.name); - let fn_decl = cx.fn_decl(args, ret_type); + let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type)); let body_block = cx.block_expr(body); let unsafety = if self.is_unsafe { From 9fa14e47d4a14fcda4adff658ccfdda3c8b9005f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 16:59:02 +0100 Subject: [PATCH 213/546] Skip checking for Storage* statements in constants/statics --- src/librustc_mir/interpret/eval_context.rs | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ee8419404ca47..376c7f240583c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,6 +1,7 @@ use std::fmt::Write; use rustc::hir::def_id::DefId; +use rustc::hir::def::Def; use rustc::hir::map::definitions::DefPathData; use rustc::middle::const_val::{ConstVal, ErrKind}; use rustc::mir; @@ -387,17 +388,23 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let num_locals = mir.local_decls.len() - 1; let mut locals = vec![Some(Value::ByVal(PrimVal::Undef)); num_locals]; - trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); - for block in mir.basic_blocks() { - for stmt in block.statements.iter() { - use rustc::mir::StatementKind::{StorageDead, StorageLive}; - match stmt.kind { - StorageLive(local) | StorageDead(local) => if local.index() > 0 { - locals[local.index() - 1] = None; - }, - _ => {} + match self.tcx.describe_def(instance.def_id()) { + // statics and constants don't have `Storage*` statements, no need to look for them + Some(Def::Static(..)) | Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {}, + _ => { + trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); + for block in mir.basic_blocks() { + for stmt in block.statements.iter() { + use rustc::mir::StatementKind::{StorageDead, StorageLive}; + match stmt.kind { + StorageLive(local) | StorageDead(local) => if local.index() > 0 { + locals[local.index() - 1] = None; + }, + _ => {} + } + } } - } + }, } self.stack.push(Frame { From ad50f3389a13d74aa0088bcb39c406193b721769 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 22 Mar 2018 16:35:54 +0000 Subject: [PATCH 214/546] Optimise decode return expression for unit structs --- src/libsyntax_ext/deriving/encodable.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index 743f22b6b3140..88baa22e7fa11 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -228,13 +228,13 @@ fn encodable_substructure(cx: &mut ExtCtxt, } // unit structs have no fields and need to return Ok() - if stmts.is_empty() { + let blk = if stmts.is_empty() { let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![])); - let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok))); - stmts.push(cx.stmt_expr(ret_ok)); - } + cx.lambda1(trait_span, ok, blkarg) + } else { + cx.lambda_stmts_1(trait_span, stmts, blkarg) + }; - let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg); cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_struct"), From 70559c54ce2a493a15f447436e281e16fc55b291 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 22 Mar 2018 09:49:20 -0700 Subject: [PATCH 215/546] Command::env_saw_path() may be unused on platforms not using posix_spawn() --- src/libstd/sys/unix/process/process_common.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 48255489dd916..b7f30600b8a4c 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -184,6 +184,7 @@ impl Command { let maybe_env = self.env.capture_if_changed(); maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) } + #[allow(dead_code)] pub fn env_saw_path(&self) -> bool { self.env.have_changed_path() } From 1b0e9f5af9283b003f5fce6f19ede145c1776684 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 14:57:28 +0000 Subject: [PATCH 216/546] Only generate documentation for local rustc crates. --- src/bootstrap/doc.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ca45adb4649af..e525bdb98fc0c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -17,12 +17,13 @@ //! Everything here is basically just a shim around calling either `rustbook` or //! `rustdoc`. +use std::collections::HashSet; use std::fs::{self, File}; use std::io::prelude::*; use std::io; use std::path::{PathBuf, Path}; -use Mode; +use {Build, Mode}; use build_helper::up_to_date; use util::{cp_r, symlink_dir}; @@ -704,15 +705,41 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); + // Only include compiler crates, no dependencies of those, such as `libc`. + cargo.arg("--no-deps"); + + // Find dependencies for top level crates. + let mut compiler_crates = HashSet::new(); + for root_crate in &["rustc", "rustc_driver"] { + let interned_root_crate = INTERNER.intern_str(root_crate); + find_compiler_crates(&build, &interned_root_crate, &mut compiler_crates); + } + + for krate in &compiler_crates { + cargo.arg("-p").arg(krate); + } build.run(&mut cargo); cp_r(&my_out, &out); } } +fn find_compiler_crates( + build: &Build, + name: &Interned, + crates: &mut HashSet> +) { + // Add current crate. + crates.insert(*name); + + // Look for dependencies. + for dep in build.crates.get(name).unwrap().deps.iter() { + if build.crates.get(dep).unwrap().is_local(build) { + find_compiler_crates(build, dep, crates); + } + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { target: Interned, From 7df6f4161cdc13a19216b5f1087081f490f06cdb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Mar 2018 09:26:15 -0800 Subject: [PATCH 217/546] rustc: Add a `#[wasm_custom_section]` attribute This commit is an implementation of adding custom sections to wasm artifacts in rustc. The intention here is to expose the ability of the wasm binary format to contain custom sections with arbitrary user-defined data. Currently neither our version of LLVM nor LLD supports this so the implementation is currently custom to rustc itself. The implementation here is to attach a `#[wasm_custom_section = "foo"]` attribute to any `const` which has a type like `[u8; N]`. Other types of constants aren't supported yet but may be added one day! This should hopefully be enough to get off the ground with *some* custom section support. The current semantics are that any constant tagged with `#[wasm_custom_section]` section will be *appended* to the corresponding section in the final output wasm artifact (and this affects dependencies linked in as well, not just the final crate). This means that whatever is interpreting the contents must be able to interpret binary-concatenated sections (or each constant needs to be in its own custom section). To test this change the existing `run-make` test suite was moved to a `run-make-fulldeps` folder and a new `run-make` test suite was added which applies to all targets by default. This test suite currently only has one test which only runs for the wasm target (using a node.js script to use `WebAssembly` in JS to parse the wasm output). --- src/bootstrap/builder.rs | 1 + src/bootstrap/compile.rs | 2 +- src/bootstrap/test.rs | 19 ++++-- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/hir/check_attr.rs | 13 ++++ src/librustc/middle/dead.rs | 5 ++ src/librustc/ty/maps/config.rs | 6 ++ src/librustc/ty/maps/mod.rs | 2 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_metadata/cstore_impl.rs | 2 + src/librustc_metadata/decoder.rs | 10 +++ src/librustc_metadata/encoder.rs | 12 ++++ src/librustc_metadata/schema.rs | 1 + src/librustc_trans/attributes.rs | 32 ++++++++- src/librustc_trans/back/link.rs | 6 ++ src/librustc_trans/back/wasm.rs | 44 +++++++++++++ src/librustc_trans/base.rs | 66 +++++++++++++++++++ src/librustc_trans/lib.rs | 3 + src/librustc_typeck/check/mod.rs | 23 ++++++- src/libsyntax/feature_gate.rs | 8 +++ .../a-b-a-linker-guard/Makefile | 0 .../a-b-a-linker-guard/a.rs | 0 .../a-b-a-linker-guard/b.rs | 0 .../alloc-extern-crates/Makefile | 0 .../alloc-extern-crates/fakealloc.rs | 0 .../allow-non-lint-warnings-cmdline/Makefile | 0 .../allow-non-lint-warnings-cmdline/foo.rs | 0 .../allow-warnings-cmdline-stability/Makefile | 0 .../allow-warnings-cmdline-stability/bar.rs | 0 .../allow-warnings-cmdline-stability/foo.rs | 0 .../archive-duplicate-names/Makefile | 0 .../archive-duplicate-names/bar.c | 0 .../archive-duplicate-names/bar.rs | 0 .../archive-duplicate-names/foo.c | 0 .../archive-duplicate-names/foo.rs | 0 .../atomic-lock-free/Makefile | 0 .../atomic-lock-free/atomic_lock_free.rs | 0 .../bare-outfile/Makefile | 0 .../bare-outfile/foo.rs | 0 .../c-dynamic-dylib/Makefile | 0 .../c-dynamic-dylib/bar.rs | 0 .../c-dynamic-dylib/cfoo.c | 0 .../c-dynamic-dylib/foo.rs | 0 .../c-dynamic-rlib/Makefile | 0 .../c-dynamic-rlib/bar.rs | 0 .../c-dynamic-rlib/cfoo.c | 0 .../c-dynamic-rlib/foo.rs | 0 .../c-link-to-rust-dylib/Makefile | 0 .../c-link-to-rust-dylib/bar.c | 0 .../c-link-to-rust-dylib/foo.rs | 0 .../c-link-to-rust-staticlib/Makefile | 0 .../c-link-to-rust-staticlib/bar.c | 0 .../c-link-to-rust-staticlib/foo.rs | 0 .../c-static-dylib/Makefile | 0 .../c-static-dylib/bar.rs | 0 .../c-static-dylib/cfoo.c | 0 .../c-static-dylib/foo.rs | 0 .../c-static-rlib/Makefile | 0 .../c-static-rlib/bar.rs | 0 .../c-static-rlib/cfoo.c | 0 .../c-static-rlib/foo.rs | 0 .../cat-and-grep-sanity-check/Makefile | 0 .../cdylib-fewer-symbols/Makefile | 0 .../cdylib-fewer-symbols/foo.rs | 0 .../cdylib/Makefile | 0 .../cdylib/bar.rs | 0 .../cdylib/foo.c | 0 .../cdylib/foo.rs | 0 .../codegen-options-parsing/Makefile | 0 .../codegen-options-parsing/dummy.rs | 0 .../compile-stdin/Makefile | 0 .../compiler-lookup-paths-2/Makefile | 0 .../compiler-lookup-paths-2/a.rs | 0 .../compiler-lookup-paths-2/b.rs | 0 .../compiler-lookup-paths-2/c.rs | 0 .../compiler-lookup-paths/Makefile | 0 .../compiler-lookup-paths/a.rs | 0 .../compiler-lookup-paths/b.rs | 0 .../compiler-lookup-paths/c.rs | 0 .../compiler-lookup-paths/d.rs | 0 .../compiler-lookup-paths/e.rs | 0 .../compiler-lookup-paths/e2.rs | 0 .../compiler-lookup-paths/f.rs | 0 .../compiler-lookup-paths/native.c | 0 .../compiler-rt-works-on-mingw/Makefile | 0 .../compiler-rt-works-on-mingw/foo.cpp | 0 .../compiler-rt-works-on-mingw/foo.rs | 0 .../crate-data-smoke/Makefile | 0 .../crate-data-smoke/crate.rs | 0 .../crate-data-smoke/lib.rs | 0 .../crate-data-smoke/rlib.rs | 0 .../crate-name-priority/Makefile | 0 .../crate-name-priority/foo.rs | 0 .../crate-name-priority/foo1.rs | 0 .../debug-assertions/Makefile | 0 .../debug-assertions/debug.rs | 0 .../dep-info-doesnt-run-much/Makefile | 0 .../dep-info-doesnt-run-much/foo.rs | 0 .../dep-info-spaces/Makefile | 0 .../dep-info-spaces/Makefile.foo | 0 .../dep-info-spaces/bar.rs | 0 .../dep-info-spaces/foo foo.rs | 0 .../dep-info-spaces/lib.rs | 0 .../dep-info/Makefile | 0 .../dep-info/Makefile.foo | 0 .../dep-info/bar.rs | 0 .../dep-info/foo.rs | 0 .../dep-info/lib.rs | 0 .../dep-info/lib2.rs | 0 .../duplicate-output-flavors/Makefile | 0 .../duplicate-output-flavors/foo.rs | 0 .../dylib-chain/Makefile | 0 .../dylib-chain/m1.rs | 0 .../dylib-chain/m2.rs | 0 .../dylib-chain/m3.rs | 0 .../dylib-chain/m4.rs | 0 .../emit/Makefile | 0 .../emit/test-24876.rs | 0 .../emit/test-26235.rs | 0 .../Makefile | 0 .../bar.rs | 0 .../foo.rs | 0 .../error-writing-dependencies/Makefile | 0 .../error-writing-dependencies/foo.rs | 0 .../extern-diff-internal-name/Makefile | 0 .../extern-diff-internal-name/lib.rs | 0 .../extern-diff-internal-name/test.rs | 0 .../extern-flag-disambiguates/Makefile | 0 .../extern-flag-disambiguates/a.rs | 0 .../extern-flag-disambiguates/b.rs | 0 .../extern-flag-disambiguates/c.rs | 0 .../extern-flag-disambiguates/d.rs | 0 .../extern-flag-fun/Makefile | 0 .../extern-flag-fun/bar-alt.rs | 0 .../extern-flag-fun/bar.rs | 0 .../extern-flag-fun/foo.rs | 0 .../extern-fn-generic/Makefile | 0 .../extern-fn-generic/test.c | 0 .../extern-fn-generic/test.rs | 0 .../extern-fn-generic/testcrate.rs | 0 .../extern-fn-mangle/Makefile | 0 .../extern-fn-mangle/test.c | 0 .../extern-fn-mangle/test.rs | 0 .../extern-fn-reachable/Makefile | 0 .../extern-fn-reachable/dylib.rs | 0 .../extern-fn-reachable/main.rs | 0 .../extern-fn-struct-passing-abi/Makefile | 0 .../extern-fn-struct-passing-abi/test.c | 0 .../extern-fn-struct-passing-abi/test.rs | 0 .../extern-fn-with-extern-types/Makefile | 0 .../extern-fn-with-extern-types/ctest.c | 0 .../extern-fn-with-extern-types/test.rs | 0 .../extern-fn-with-packed-struct/Makefile | 0 .../extern-fn-with-packed-struct/test.c | 0 .../extern-fn-with-packed-struct/test.rs | 0 .../extern-fn-with-union/Makefile | 0 .../extern-fn-with-union/ctest.c | 0 .../extern-fn-with-union/test.rs | 0 .../extern-fn-with-union/testcrate.rs | 0 .../extern-multiple-copies/Makefile | 0 .../extern-multiple-copies/bar.rs | 0 .../extern-multiple-copies/foo1.rs | 0 .../extern-multiple-copies/foo2.rs | 0 .../extern-multiple-copies2/Makefile | 0 .../extern-multiple-copies2/bar.rs | 0 .../extern-multiple-copies2/foo1.rs | 0 .../extern-multiple-copies2/foo2.rs | 0 .../extern-overrides-distribution/Makefile | 0 .../extern-overrides-distribution/libc.rs | 0 .../extern-overrides-distribution/main.rs | 0 .../extra-filename-with-temp-outputs/Makefile | 0 .../extra-filename-with-temp-outputs/foo.rs | 0 .../fpic/Makefile | 0 .../fpic/hello.rs | 0 .../hir-tree/Makefile | 0 .../hir-tree/input.rs | 0 .../hotplug_codegen_backend/Makefile | 0 .../hotplug_codegen_backend/some_crate.rs | 0 .../hotplug_codegen_backend/the_backend.rs | 0 .../include_bytes_deps/Makefile | 0 .../include_bytes_deps/input.bin | 0 .../include_bytes_deps/input.md | 0 .../include_bytes_deps/input.txt | 0 .../include_bytes_deps/main.rs | 0 .../inline-always-many-cgu/Makefile | 0 .../inline-always-many-cgu/foo.rs | 0 .../interdependent-c-libraries/Makefile | 0 .../interdependent-c-libraries/bar.c | 0 .../interdependent-c-libraries/bar.rs | 0 .../interdependent-c-libraries/foo.c | 0 .../interdependent-c-libraries/foo.rs | 0 .../interdependent-c-libraries/main.rs | 0 .../intrinsic-unreachable/Makefile | 0 .../intrinsic-unreachable/exit-ret.rs | 0 .../intrinsic-unreachable/exit-unreachable.rs | 0 .../invalid-library/Makefile | 0 .../invalid-library/foo.rs | 0 .../invalid-staticlib/Makefile | 0 .../issue-11908/Makefile | 0 .../issue-11908/bar.rs | 0 .../issue-11908/foo.rs | 0 .../issue-14500/Makefile | 0 .../issue-14500/bar.rs | 0 .../issue-14500/foo.c | 0 .../issue-14500/foo.rs | 0 .../issue-14698/Makefile | 0 .../issue-14698/foo.rs | 0 .../issue-15460/Makefile | 0 .../issue-15460/bar.rs | 0 .../issue-15460/foo.c | 0 .../issue-15460/foo.rs | 0 .../issue-18943/Makefile | 0 .../issue-18943/foo.rs | 0 .../issue-19371/Makefile | 0 .../issue-19371/foo.rs | 0 .../issue-20626/Makefile | 0 .../issue-20626/foo.rs | 0 .../issue-22131/Makefile | 0 .../issue-22131/foo.rs | 0 .../issue-24445/Makefile | 0 .../issue-24445/foo.c | 0 .../issue-24445/foo.rs | 0 .../issue-25581/Makefile | 0 .../issue-25581/test.c | 0 .../issue-25581/test.rs | 0 .../issue-26006/Makefile | 0 .../issue-26006/in/libc/lib.rs | 0 .../issue-26006/in/time/lib.rs | 0 .../issue-26092/Makefile | 0 .../issue-26092/blank.rs | 0 .../issue-28595/Makefile | 0 .../issue-28595/a.c | 0 .../issue-28595/a.rs | 0 .../issue-28595/b.c | 0 .../issue-28595/b.rs | 0 .../issue-28766/Makefile | 0 .../issue-28766/foo.rs | 0 .../issue-28766/main.rs | 0 .../issue-30063/Makefile | 0 .../issue-30063/foo.rs | 0 .../issue-33329/Makefile | 0 .../issue-33329/main.rs | 0 .../issue-35164/Makefile | 0 .../issue-35164/main.rs | 0 .../issue-35164/submodule/mod.rs | 0 .../issue-37839/Makefile | 0 .../issue-37839/a.rs | 0 .../issue-37839/b.rs | 0 .../issue-37839/c.rs | 0 .../issue-37893/Makefile | 0 .../issue-37893/a.rs | 0 .../issue-37893/b.rs | 0 .../issue-37893/c.rs | 0 .../issue-38237/Makefile | 0 .../issue-38237/bar.rs | 0 .../issue-38237/baz.rs | 0 .../issue-38237/foo.rs | 0 .../issue-40535/Makefile | 0 .../issue-40535/bar.rs | 0 .../issue-40535/baz.rs | 0 .../issue-40535/foo.rs | 0 .../issue-46239/Makefile | 0 .../issue-46239/main.rs | 0 .../issue-7349/Makefile | 0 .../issue-7349/foo.rs | 0 .../issues-41478-43796/Makefile | 0 .../issues-41478-43796/a.rs | 0 .../libs-and-bins/Makefile | 0 .../libs-and-bins/foo.rs | 0 .../libs-through-symlinks/Makefile | 0 .../libs-through-symlinks/bar.rs | 0 .../libs-through-symlinks/foo.rs | 0 .../libtest-json/Makefile | 0 .../libtest-json/f.rs | 0 .../libtest-json/output.json | 0 .../libtest-json/validate_json.py | 0 .../link-arg/Makefile | 0 .../link-arg/empty.rs | 0 .../link-cfg/Makefile | 0 .../link-cfg/dep-with-staticlib.rs | 0 .../link-cfg/dep.rs | 0 .../link-cfg/no-deps.rs | 0 .../link-cfg/return1.c | 0 .../link-cfg/return2.c | 0 .../link-cfg/return3.c | 0 .../link-cfg/with-deps.rs | 0 .../link-cfg/with-staticlib-deps.rs | 0 .../link-path-order/Makefile | 0 .../link-path-order/correct.c | 0 .../link-path-order/main.rs | 0 .../link-path-order/wrong.c | 0 .../linkage-attr-on-static/Makefile | 0 .../linkage-attr-on-static/bar.rs | 0 .../linkage-attr-on-static/foo.c | 0 .../linker-output-non-utf8/Makefile | 0 .../linker-output-non-utf8/exec.rs | 0 .../linker-output-non-utf8/library.rs | 0 .../llvm-pass/Makefile | 0 .../llvm-pass/llvm-function-pass.so.cc | 0 .../llvm-pass/llvm-module-pass.so.cc | 0 .../llvm-pass/main.rs | 0 .../llvm-pass/plugin.rs | 0 .../Makefile | 0 .../long-linker-command-lines-cmd-exe/foo.bat | 0 .../long-linker-command-lines-cmd-exe/foo.rs | 0 .../long-linker-command-lines/Makefile | 0 .../long-linker-command-lines/foo.rs | 0 .../longjmp-across-rust/Makefile | 0 .../longjmp-across-rust/foo.c | 0 .../longjmp-across-rust/main.rs | 0 .../ls-metadata/Makefile | 0 .../ls-metadata/foo.rs | 0 .../lto-no-link-whole-rlib/Makefile | 0 .../lto-no-link-whole-rlib/bar.c | 0 .../lto-no-link-whole-rlib/foo.c | 0 .../lto-no-link-whole-rlib/lib1.rs | 0 .../lto-no-link-whole-rlib/lib2.rs | 0 .../lto-no-link-whole-rlib/main.rs | 0 .../lto-readonly-lib/Makefile | 0 .../lto-readonly-lib/lib.rs | 0 .../lto-readonly-lib/main.rs | 0 .../lto-smoke-c/Makefile | 0 .../lto-smoke-c/bar.c | 0 .../lto-smoke-c/foo.rs | 0 .../lto-smoke/Makefile | 0 .../lto-smoke/lib.rs | 0 .../lto-smoke/main.rs | 0 .../manual-crate-name/Makefile | 0 .../manual-crate-name/bar.rs | 0 .../manual-link/Makefile | 0 .../manual-link/bar.c | 0 .../manual-link/foo.c | 0 .../manual-link/foo.rs | 0 .../manual-link/main.rs | 0 .../many-crates-but-no-match/Makefile | 0 .../many-crates-but-no-match/crateA1.rs | 0 .../many-crates-but-no-match/crateA2.rs | 0 .../many-crates-but-no-match/crateA3.rs | 0 .../many-crates-but-no-match/crateB.rs | 0 .../many-crates-but-no-match/crateC.rs | 0 .../metadata-flag-frobs-symbols/Makefile | 0 .../metadata-flag-frobs-symbols/bar.rs | 0 .../metadata-flag-frobs-symbols/foo.rs | 0 .../min-global-align/Makefile | 0 .../min-global-align/min_global_align.rs | 0 .../mismatching-target-triples/Makefile | 0 .../mismatching-target-triples/bar.rs | 0 .../mismatching-target-triples/foo.rs | 0 .../missing-crate-dependency/Makefile | 0 .../missing-crate-dependency/crateA.rs | 0 .../missing-crate-dependency/crateB.rs | 0 .../missing-crate-dependency/crateC.rs | 0 .../mixing-deps/Makefile | 0 .../mixing-deps/both.rs | 0 .../mixing-deps/dylib.rs | 0 .../mixing-deps/prog.rs | 0 .../mixing-formats/Makefile | 0 .../mixing-formats/bar1.rs | 0 .../mixing-formats/bar2.rs | 0 .../mixing-formats/baz.rs | 0 .../mixing-formats/baz2.rs | 0 .../mixing-formats/foo.rs | 0 .../mixing-libs/Makefile | 0 .../mixing-libs/dylib.rs | 0 .../mixing-libs/prog.rs | 0 .../mixing-libs/rlib.rs | 0 .../msvc-opt-minsize/Makefile | 0 .../msvc-opt-minsize/foo.rs | 0 .../multiple-emits/Makefile | 0 .../multiple-emits/foo.rs | 0 .../no-builtins-lto/Makefile | 0 .../no-builtins-lto/main.rs | 0 .../no-builtins-lto/no_builtins.rs | 0 .../no-duplicate-libs/Makefile | 0 .../no-duplicate-libs/bar.c | 0 .../no-duplicate-libs/foo.c | 0 .../no-duplicate-libs/main.rs | 0 .../no-integrated-as/Makefile | 0 .../no-integrated-as/hello.rs | 0 .../no-intermediate-extras/Makefile | 0 .../no-intermediate-extras/foo.rs | 0 .../obey-crate-type-flag/Makefile | 0 .../obey-crate-type-flag/test.rs | 0 .../Makefile | 0 .../foo.rs | 0 .../output-filename-overwrites-input/Makefile | 0 .../output-filename-overwrites-input/bar.rs | 0 .../output-filename-overwrites-input/foo.rs | 0 .../output-type-permutations/Makefile | 0 .../output-type-permutations/foo.rs | 0 .../output-with-hyphens/Makefile | 0 .../output-with-hyphens/foo-bar.rs | 0 .../prefer-dylib/Makefile | 0 .../prefer-dylib/bar.rs | 0 .../prefer-dylib/foo.rs | 0 .../prefer-rlib/Makefile | 0 .../prefer-rlib/bar.rs | 0 .../prefer-rlib/foo.rs | 0 .../pretty-expanded-hygiene/Makefile | 0 .../pretty-expanded-hygiene/input.pp.rs | 0 .../pretty-expanded-hygiene/input.rs | 0 .../pretty-expanded/Makefile | 0 .../pretty-expanded/input.rs | 0 .../pretty-print-path-suffix/Makefile | 0 .../pretty-print-path-suffix/foo.pp | 0 .../pretty-print-path-suffix/foo_method.pp | 0 .../pretty-print-path-suffix/input.rs | 0 .../pretty-print-path-suffix/nest_foo.pp | 0 .../pretty-print-to-file/Makefile | 0 .../pretty-print-to-file/input.pp | 0 .../pretty-print-to-file/input.rs | 0 .../print-cfg/Makefile | 0 .../print-target-list/Makefile | 0 .../profile/Makefile | 0 .../profile/test.rs | 0 .../prune-link-args/Makefile | 0 .../prune-link-args/empty.rs | 0 .../relocation-model/Makefile | 0 .../relocation-model/foo.rs | 0 .../relro-levels/Makefile | 0 .../relro-levels/hello.rs | 0 .../reproducible-build/Makefile | 0 .../reproducible-build/linker.rs | 0 .../reproducible-build-aux.rs | 0 .../reproducible-build/reproducible-build.rs | 0 .../rlib-chain/Makefile | 0 .../rlib-chain/m1.rs | 0 .../rlib-chain/m2.rs | 0 .../rlib-chain/m3.rs | 0 .../rlib-chain/m4.rs | 0 .../rustc-macro-dep-files/Makefile | 0 .../rustc-macro-dep-files/bar.rs | 0 .../rustc-macro-dep-files/foo.rs | 0 .../rustdoc-error-lines/Makefile | 0 .../rustdoc-error-lines/input.rs | 0 .../rustdoc-output-path/Makefile | 0 .../rustdoc-output-path/foo.rs | 0 .../sanitizer-address/Makefile | 0 .../sanitizer-address/overflow.rs | 0 .../sanitizer-cdylib-link/Makefile | 0 .../sanitizer-cdylib-link/library.rs | 0 .../sanitizer-cdylib-link/program.rs | 0 .../sanitizer-dylib-link/Makefile | 0 .../sanitizer-dylib-link/library.rs | 0 .../sanitizer-dylib-link/program.rs | 0 .../sanitizer-invalid-cratetype/Makefile | 0 .../sanitizer-invalid-cratetype/hello.rs | 0 .../sanitizer-invalid-target/Makefile | 0 .../sanitizer-invalid-target/hello.rs | 0 .../sanitizer-leak/Makefile | 0 .../sanitizer-leak/leak.rs | 0 .../sanitizer-memory/Makefile | 0 .../sanitizer-memory/uninit.rs | 0 .../sanitizer-staticlib-link/Makefile | 0 .../sanitizer-staticlib-link/library.rs | 0 .../sanitizer-staticlib-link/program.c | 0 .../save-analysis-fail/Makefile | 0 .../save-analysis-fail/SameDir.rs | 0 .../save-analysis-fail/SameDir3.rs | 0 .../save-analysis-fail/SubDir/mod.rs | 0 .../save-analysis-fail/foo.rs | 0 .../save-analysis-fail/krate2.rs | 0 .../save-analysis/Makefile | 0 .../save-analysis/SameDir.rs | 0 .../save-analysis/SameDir3.rs | 0 .../save-analysis/SubDir/mod.rs | 0 .../save-analysis/extra-docs.md | 0 .../save-analysis/foo.rs | 0 .../save-analysis/krate2.rs | 0 .../sepcomp-cci-copies/Makefile | 0 .../sepcomp-cci-copies/cci_lib.rs | 0 .../sepcomp-cci-copies/foo.rs | 0 .../sepcomp-inlining/Makefile | 0 .../sepcomp-inlining/foo.rs | 0 .../sepcomp-separate/Makefile | 0 .../sepcomp-separate/foo.rs | 0 .../simd-ffi/Makefile | 0 .../simd-ffi/simd.rs | 0 .../simple-dylib/Makefile | 0 .../simple-dylib/bar.rs | 0 .../simple-dylib/foo.rs | 0 .../simple-rlib/Makefile | 0 .../simple-rlib/bar.rs | 0 .../simple-rlib/foo.rs | 0 .../stable-symbol-names/Makefile | 0 .../stable-symbol-names1.rs | 0 .../stable-symbol-names2.rs | 0 .../static-dylib-by-default/Makefile | 0 .../static-dylib-by-default/bar.rs | 0 .../static-dylib-by-default/foo.rs | 0 .../static-dylib-by-default/main.c | 0 .../static-nobundle/Makefile | 0 .../static-nobundle/aaa.c | 0 .../static-nobundle/bbb.rs | 0 .../static-nobundle/ccc.rs | 0 .../static-nobundle/ddd.rs | 0 .../static-unwinding/Makefile | 0 .../static-unwinding/lib.rs | 0 .../static-unwinding/main.rs | 0 .../staticlib-blank-lib/Makefile | 0 .../staticlib-blank-lib/foo.rs | 0 .../stdin-non-utf8/Makefile | 0 .../stdin-non-utf8/non-utf8 | 0 .../suspicious-library/Makefile | 0 .../suspicious-library/bar.rs | 0 .../suspicious-library/foo.rs | 0 .../symbol-visibility/Makefile | 0 .../symbol-visibility/a_cdylib.rs | 0 .../symbol-visibility/a_rust_dylib.rs | 0 .../symbol-visibility/an_executable.rs | 0 .../symbol-visibility/an_rlib.rs | 0 .../symbols-are-reasonable/Makefile | 0 .../symbols-are-reasonable/lib.rs | 0 .../symbols-include-type-name/Makefile | 0 .../symbols-include-type-name/lib.rs | 0 .../symlinked-extern/Makefile | 0 .../symlinked-extern/bar.rs | 0 .../symlinked-extern/baz.rs | 0 .../symlinked-extern/foo.rs | 0 .../symlinked-libraries/Makefile | 0 .../symlinked-libraries/bar.rs | 0 .../symlinked-libraries/foo.rs | 0 .../symlinked-rlib/Makefile | 0 .../symlinked-rlib/bar.rs | 0 .../symlinked-rlib/foo.rs | 0 .../sysroot-crates-are-unstable/Makefile | 0 .../sysroot-crates-are-unstable/test.py | 0 .../target-cpu-native/Makefile | 0 .../target-cpu-native/foo.rs | 0 .../target-specs/Makefile | 0 .../target-specs/foo.rs | 0 .../target-specs/my-awesome-platform.json | 0 .../target-specs/my-incomplete-platform.json | 0 .../target-specs/my-invalid-platform.json | 0 .../my-x86_64-unknown-linux-gnu-platform.json | 0 .../target-without-atomics/Makefile | 0 .../test-harness/Makefile | 0 .../test-harness/test-ignore-cfg.rs | 0 .../{run-make => run-make-fulldeps}/tools.mk | 0 .../treat-err-as-bug/Makefile | 0 .../treat-err-as-bug/err.rs | 0 .../type-mismatch-same-crate-name/Makefile | 0 .../type-mismatch-same-crate-name/crateA.rs | 0 .../type-mismatch-same-crate-name/crateB.rs | 0 .../type-mismatch-same-crate-name/crateC.rs | 0 .../use-extern-for-plugins/Makefile | 0 .../use-extern-for-plugins/bar.rs | 0 .../use-extern-for-plugins/baz.rs | 0 .../use-extern-for-plugins/foo.rs | 0 .../used/Makefile | 0 .../used/used.rs | 0 .../version/Makefile | 0 .../volatile-intrinsics/Makefile | 0 .../volatile-intrinsics/main.rs | 0 .../weird-output-filenames/Makefile | 0 .../weird-output-filenames/foo.rs | 0 .../windows-spawn/Makefile | 0 .../windows-spawn/hello.rs | 0 .../windows-spawn/spawn.rs | 0 .../windows-subsystem/Makefile | 0 .../windows-subsystem/console.rs | 0 .../windows-subsystem/windows.rs | 0 .../run-make/wasm-custom-section/Makefile | 10 +++ src/test/run-make/wasm-custom-section/bar.rs | 24 +++++++ src/test/run-make/wasm-custom-section/foo.js | 46 +++++++++++++ src/test/run-make/wasm-custom-section/foo.rs | 19 ++++++ .../ui/feature-gate-wasm_custom_section.rs | 14 ++++ .../feature-gate-wasm_custom_section.stderr | 11 ++++ src/test/ui/wasm-custom-section/malformed.rs | 19 ++++++ .../ui/wasm-custom-section/malformed.stderr | 14 ++++ src/test/ui/wasm-custom-section/not-const.rs | 29 ++++++++ .../ui/wasm-custom-section/not-const.stderr | 38 +++++++++++ src/test/ui/wasm-custom-section/not-slice.rs | 22 +++++++ .../ui/wasm-custom-section/not-slice.stderr | 20 ++++++ src/tools/compiletest/src/runtest.rs | 15 +++-- 575 files changed, 522 insertions(+), 17 deletions(-) create mode 100644 src/librustc_trans/back/wasm.rs rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/alloc-extern-crates/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/alloc-extern-crates/fakealloc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-non-lint-warnings-cmdline/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/allow-non-lint-warnings-cmdline/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/atomic-lock-free/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/atomic-lock-free/atomic_lock_free.rs (100%) rename src/test/{run-make => run-make-fulldeps}/bare-outfile/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/bare-outfile/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cat-and-grep-sanity-check/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib-fewer-symbols/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib-fewer-symbols/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/codegen-options-parsing/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/codegen-options-parsing/dummy.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compile-stdin/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/d.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/e.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/e2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/f.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/native.c (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/foo.cpp (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/crate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/debug-assertions/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/debug-assertions/debug.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-doesnt-run-much/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-doesnt-run-much/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/Makefile.foo (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/foo foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/Makefile.foo (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/lib2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/duplicate-output-flavors/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/duplicate-output-flavors/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m4.rs (100%) rename src/test/{run-make => run-make-fulldeps}/emit/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/emit/test-24876.rs (100%) rename src/test/{run-make => run-make-fulldeps}/emit/test-26235.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-writing-dependencies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/error-writing-dependencies/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/d.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/bar-alt.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/testcrate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/ctest.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/ctest.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/testcrate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/foo2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/foo2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/libc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extra-filename-with-temp-outputs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extra-filename-with-temp-outputs/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/fpic/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/fpic/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hir-tree/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/hir-tree/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/some_crate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/the_backend.rs (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.bin (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.md (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.txt (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/inline-always-many-cgu/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/inline-always-many-cgu/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/exit-ret.rs (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/exit-unreachable.rs (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-library/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-library/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-staticlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14698/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14698/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-18943/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-18943/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-19371/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-19371/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-20626/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-20626/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-22131/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-22131/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/in/libc/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/in/time/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26092/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26092/blank.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/a.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/b.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-30063/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-30063/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-33329/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-33329/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/submodule/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-46239/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-46239/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-7349/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-7349/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issues-41478-43796/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issues-41478-43796/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-and-bins/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libs-and-bins/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/f.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/output.json (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/validate_json.py (100%) rename src/test/{run-make => run-make-fulldeps}/link-arg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-arg/empty.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/dep-with-staticlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/dep.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/no-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return1.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return2.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return3.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/with-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/with-staticlib-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/correct.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/wrong.c (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/exec.rs (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/llvm-function-pass.so.cc (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/llvm-module-pass.so.cc (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/plugin.rs (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/foo.bat (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/ls-metadata/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/ls-metadata/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/lib1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/lib2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-crate-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/manual-crate-name/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/min-global-align/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/min-global-align/min_global_align.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateA.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/both.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/prog.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/bar1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/bar2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/baz2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/prog.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/msvc-opt-minsize/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/msvc-opt-minsize/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/multiple-emits/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/multiple-emits/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/no_builtins.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-integrated-as/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-integrated-as/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-intermediate-extras/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-intermediate-extras/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/obey-crate-type-flag/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/obey-crate-type-flag/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-conflicts-with-directory/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-conflicts-with-directory/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-type-permutations/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-type-permutations/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-with-hyphens/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-with-hyphens/foo-bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/input.pp.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/foo.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/foo_method.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/nest_foo.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/input.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/print-cfg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/print-target-list/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/profile/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/profile/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prune-link-args/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prune-link-args/empty.rs (100%) rename src/test/{run-make => run-make-fulldeps}/relocation-model/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/relocation-model/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/relro-levels/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/relro-levels/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/linker.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/reproducible-build-aux.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/reproducible-build.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m4.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-error-lines/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-error-lines/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-output-path/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-output-path/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-address/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-address/overflow.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/program.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/program.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-cratetype/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-cratetype/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-target/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-target/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-leak/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-leak/leak.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-memory/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-memory/uninit.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/program.c (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SameDir.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SameDir3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SubDir/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/krate2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SameDir.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SameDir3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SubDir/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/extra-docs.md (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/krate2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/cci_lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-inlining/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-inlining/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-separate/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-separate/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simd-ffi/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simd-ffi/simd.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/stable-symbol-names1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/stable-symbol-names2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/main.c (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/aaa.c (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/bbb.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/ccc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/ddd.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/staticlib-blank-lib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/staticlib-blank-lib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stdin-non-utf8/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/stdin-non-utf8/non-utf8 (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/a_cdylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/a_rust_dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/an_executable.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/an_rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-are-reasonable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-are-reasonable/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-include-type-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-include-type-name/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sysroot-crates-are-unstable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sysroot-crates-are-unstable/test.py (100%) rename src/test/{run-make => run-make-fulldeps}/target-cpu-native/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/target-cpu-native/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-awesome-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-incomplete-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-invalid-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-x86_64-unknown-linux-gnu-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-without-atomics/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/test-harness/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/test-harness/test-ignore-cfg.rs (100%) rename src/test/{run-make => run-make-fulldeps}/tools.mk (100%) rename src/test/{run-make => run-make-fulldeps}/treat-err-as-bug/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/treat-err-as-bug/err.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateA.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/used/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/used/used.rs (100%) rename src/test/{run-make => run-make-fulldeps}/version/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/volatile-intrinsics/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/volatile-intrinsics/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/weird-output-filenames/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/weird-output-filenames/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/spawn.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/console.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/windows.rs (100%) create mode 100644 src/test/run-make/wasm-custom-section/Makefile create mode 100644 src/test/run-make/wasm-custom-section/bar.rs create mode 100644 src/test/run-make/wasm-custom-section/foo.js create mode 100644 src/test/run-make/wasm-custom-section/foo.rs create mode 100644 src/test/ui/feature-gate-wasm_custom_section.rs create mode 100644 src/test/ui/feature-gate-wasm_custom_section.stderr create mode 100644 src/test/ui/wasm-custom-section/malformed.rs create mode 100644 src/test/ui/wasm-custom-section/malformed.stderr create mode 100644 src/test/ui/wasm-custom-section/not-const.rs create mode 100644 src/test/ui/wasm-custom-section/not-const.stderr create mode 100644 src/test/ui/wasm-custom-section/not-slice.rs create mode 100644 src/test/ui/wasm-custom-section/not-slice.stderr diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a398bcc973746..2e094a8898206 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -313,6 +313,7 @@ impl<'a> Builder<'a> { test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, + test::RunMakeFullDeps, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, test::TheBook, test::UnstableBook, test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 86263c8fa0733..2640248373c3d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -915,7 +915,7 @@ impl Step for Assemble { } } - let lld_install = if build.config.lld_enabled && target_compiler.stage > 0 { + let lld_install = if build.config.lld_enabled { Some(builder.ensure(native::Lld { target: target_compiler.host, })) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de938ec8e8306..6c19da4648a29 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -759,12 +759,18 @@ test!(RunFailFullDepsPretty { host: true }); -host_test!(RunMake { +default_test!(RunMake { path: "src/test/run-make", mode: "run-make", suite: "run-make" }); +host_test!(RunMakeFullDeps { + path: "src/test/run-make-fulldeps", + mode: "run-make", + suite: "run-make-fulldeps" +}); + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct Compiletest { compiler: Compiler, @@ -827,8 +833,7 @@ impl Step for Compiletest { // FIXME: Does pretty need librustc compiled? Note that there are // fulldeps test suites with mode = pretty as well. mode == "pretty" || - mode == "rustdoc" || - mode == "run-make" { + mode == "rustdoc" { builder.ensure(compile::Rustc { compiler, target }); } @@ -849,7 +854,7 @@ impl Step for Compiletest { cmd.arg("--rustc-path").arg(builder.rustc(compiler)); // Avoid depending on rustdoc when we don't need it. - if mode == "rustdoc" || mode == "run-make" { + if mode == "rustdoc" || (mode == "run-make" && suite.ends_with("fulldeps")) { cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host)); } @@ -931,7 +936,7 @@ impl Step for Compiletest { // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if suite == "run-make" { + if suite == "run-make-fulldeps" { let llvm_components = output(Command::new(&llvm_config).arg("--components")); let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); cmd.arg("--cc").arg(build.cc(target)) @@ -944,12 +949,12 @@ impl Step for Compiletest { } } } - if suite == "run-make" && !build.config.llvm_enabled { + if suite == "run-make-fulldeps" && !build.config.llvm_enabled { println!("Ignoring run-make test suite as they generally don't work without LLVM"); return; } - if suite != "run-make" { + if suite != "run-make-fulldeps" { cmd.arg("--cc").arg("") .arg("--cxx").arg("") .arg("--cflags").arg("") diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1e2e4e5a69fa1..09d7ce599ab03 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -650,6 +650,8 @@ define_dep_nodes!( <'tcx> [] GetSymbolExportLevel(DefId), + [] WasmCustomSections(CrateNum), + [input] Features, [] ProgramClausesFor(DefId), diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index d7194e9c2cabb..f141cac161483 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -25,6 +25,7 @@ enum Target { Struct, Union, Enum, + Const, Other, } @@ -35,6 +36,7 @@ impl Target { hir::ItemStruct(..) => Target::Struct, hir::ItemUnion(..) => Target::Union, hir::ItemEnum(..) => Target::Enum, + hir::ItemConst(..) => Target::Const, _ => Target::Other, } } @@ -60,6 +62,17 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { if name == "inline" { self.check_inline(attr, item, target) } + + if name == "wasm_custom_section" { + if target != Target::Const { + self.tcx.sess.span_err(attr.span, "only allowed on consts"); + } + + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "must be of the form \ + #[wasm_custom_section = \"foo\"]"); + } + } } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 1ff9c7a86291e..abd52624c30d4 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -318,6 +318,11 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt, return true; } + // These constants are special for wasm + if attr::contains_name(attrs, "wasm_custom_section") { + return true; + } + tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow } diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 117d921931235..0b41c3ab2fa20 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -678,6 +678,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> } } +impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("custom wasm sections for a crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { #[inline] fn cache_on_disk(def_id: Self::Key) -> bool { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 6c3b4efb932ad..2b4c1992762ea 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -424,6 +424,8 @@ define_maps! { <'tcx> [] fn features_query: features_node(CrateNum) -> Lrc, [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, + + [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 4170fa7679716..910c00b832ef8 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -940,6 +940,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::Features => { force!(features_query, LOCAL_CRATE); } DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } + DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); } } true diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 2de27f3a1c3ea..3c2f984ef8b3f 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -271,6 +271,8 @@ provide! { <'tcx> tcx, def_id, other, cdata, Arc::new(cdata.exported_symbols()) } + + wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) } } pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b0c945fbf2a05..0e5df3142af64 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1067,6 +1067,16 @@ impl<'a, 'tcx> CrateMetadata { .collect() } + pub fn wasm_custom_sections(&self) -> Vec { + let sections = self.root + .wasm_custom_sections + .decode(self) + .map(|def_index| self.local_def_id(def_index)) + .collect::>(); + info!("loaded wasm sections {:?}", sections); + return sections + } + pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) { let entry = self.entry(id); match entry.kind { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6b3453f2c99e8..56981b8f4a1e9 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -435,6 +435,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { &exported_symbols); let exported_symbols_bytes = self.position() - i; + // encode wasm custom sections + let wasm_custom_sections = self.tcx.wasm_custom_sections(LOCAL_CRATE); + let wasm_custom_sections = self.tracked( + IsolatedEncoder::encode_wasm_custom_sections, + &wasm_custom_sections); + // Encode and index the items. i = self.position(); let items = self.encode_info_for_items(); @@ -478,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_path_table, impls, exported_symbols, + wasm_custom_sections, index, }); @@ -1444,6 +1451,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { .cloned()) } + fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq { + info!("encoding custom wasm section constants {:?}", statics); + self.lazy_seq(statics.iter().map(|id| id.index)) + } + fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq> { match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) { Some(arr) => { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 593f08e90bb3b..001772623e75b 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -204,6 +204,7 @@ pub struct CrateRoot { pub def_path_table: Lazy, pub impls: LazySeq, pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>, + pub wasm_custom_sections: LazySeq, pub index: LazySeq, } diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 040d9455334bc..16253aa92acc7 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -11,9 +11,11 @@ use std::ffi::{CStr, CString}; -use rustc::hir::TransFnAttrFlags; +use rustc::hir::{self, TransFnAttrFlags}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::session::config::Sanitizer; +use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc_data_structures::sync::Lrc; @@ -161,4 +163,32 @@ pub fn provide(providers: &mut Providers) { .collect()) } }; + + providers.wasm_custom_sections = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + let mut finder = WasmSectionFinder { tcx, list: Vec::new() }; + tcx.hir.krate().visit_all_item_likes(&mut finder); + Lrc::new(finder.list) + }; +} + +struct WasmSectionFinder<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + list: Vec, +} + +impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> { + fn visit_item(&mut self, i: &'tcx hir::Item) { + match i.node { + hir::ItemConst(..) => {} + _ => return, + } + if i.attrs.iter().any(|i| i.check_name("wasm_custom_section")) { + self.list.push(self.tcx.hir.local_def_id(i.id)); + } + } + + fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {} + + fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index bdda7741221f5..8e8ba823b6f8d 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use back::wasm; use cc::windows_registry; use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::bytecode::RLIB_BYTECODE_EXTENSION; @@ -810,6 +811,11 @@ fn link_natively(sess: &Session, Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)), } } + + if sess.opts.target_triple == "wasm32-unknown-unknown" { + wasm::add_custom_sections(&out_filename, + &trans.crate_info.wasm_custom_sections); + } } fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) diff --git a/src/librustc_trans/back/wasm.rs b/src/librustc_trans/back/wasm.rs new file mode 100644 index 0000000000000..99f1e4b7e78fe --- /dev/null +++ b/src/librustc_trans/back/wasm.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fs; +use std::path::Path; +use std::collections::BTreeMap; + +use serialize::leb128; + +pub fn add_custom_sections(path: &Path, sections: &BTreeMap>) { + let mut wasm = fs::read(path).expect("failed to read wasm output"); + + // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section + for (section, bytes) in sections { + // write the `id` identifier, 0 for a custom section + let len = wasm.len(); + leb128::write_u32_leb128(&mut wasm, len, 0); + + // figure out how long our name descriptor will be + let mut name = Vec::new(); + leb128::write_u32_leb128(&mut name, 0, section.len() as u32); + name.extend_from_slice(section.as_bytes()); + + // write the length of the payload + let len = wasm.len(); + let total_len = bytes.len() + name.len(); + leb128::write_u32_leb128(&mut wasm, len, total_len as u32); + + // write out the name section + wasm.extend(name); + + // and now the payload itself + wasm.extend_from_slice(bytes); + } + + fs::write(path, &wasm).expect("failed to write wasm output"); +} diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 4da082e9d50f1..11f952bc5bc77 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -74,6 +74,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use std::any::Any; +use std::collections::BTreeMap; use std::ffi::CString; use std::str; use std::sync::Arc; @@ -1070,8 +1071,24 @@ impl CrateInfo { used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic), used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), used_crate_source: FxHashMap(), + wasm_custom_sections: BTreeMap::new(), }; + let load_wasm_sections = tcx.sess.crate_types.borrow() + .iter() + .any(|c| *c != config::CrateTypeRlib) && + tcx.sess.opts.target_triple == "wasm32-unknown-unknown"; + + if load_wasm_sections { + info!("attempting to load all wasm sections"); + for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() { + let (name, contents) = fetch_wasm_section(tcx, id); + info.wasm_custom_sections.entry(name) + .or_insert(Vec::new()) + .extend(contents); + } + } + for &cnum in tcx.crates().iter() { info.native_libraries.insert(cnum, tcx.native_libraries(cnum)); info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string()); @@ -1091,6 +1108,14 @@ impl CrateInfo { if tcx.is_no_builtins(cnum) { info.is_no_builtins.insert(cnum); } + if load_wasm_sections { + for &id in tcx.wasm_custom_sections(cnum).iter() { + let (name, contents) = fetch_wasm_section(tcx, id); + info.wasm_custom_sections.entry(name) + .or_insert(Vec::new()) + .extend(contents); + } + } } @@ -1270,3 +1295,44 @@ mod temp_stable_hash_impls { } } } + +fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec) { + use rustc::mir::interpret::{GlobalId, Value, PrimVal}; + use rustc::middle::const_val::ConstVal; + + info!("loading wasm section {:?}", id); + + let section = tcx.get_attrs(id) + .iter() + .find(|a| a.check_name("wasm_custom_section")) + .expect("missing #[wasm_custom_section] attribute") + .value_str() + .expect("malformed #[wasm_custom_section] attribute"); + + let instance = ty::Instance::mono(tcx, id); + let cid = GlobalId { + instance, + promoted: None + }; + let param_env = ty::ParamEnv::reveal_all(); + let val = tcx.const_eval(param_env.and(cid)).unwrap(); + + let val = match val.val { + ConstVal::Value(val) => val, + ConstVal::Unevaluated(..) => bug!("should be evaluated"), + }; + let val = match val { + Value::ByRef(ptr, _align) => ptr.into_inner_primval(), + ref v => bug!("should be ByRef, was {:?}", v), + }; + let mem = match val { + PrimVal::Ptr(mem) => mem, + ref v => bug!("should be Ptr, was {:?}", v), + }; + assert_eq!(mem.offset, 0); + let alloc = tcx + .interpret_interner + .get_alloc(mem.alloc_id) + .expect("miri allocation never successfully created"); + (section.to_string(), alloc.bytes.clone()) +} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 337f85a381399..bb2aeca374882 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -72,6 +72,7 @@ pub use llvm_util::target_features; use std::any::Any; use std::path::PathBuf; use std::sync::mpsc; +use std::collections::BTreeMap; use rustc_data_structures::sync::Lrc; use rustc::dep_graph::DepGraph; @@ -98,6 +99,7 @@ mod back { pub mod symbol_export; pub mod write; mod rpath; + mod wasm; } mod abi; @@ -400,6 +402,7 @@ struct CrateInfo { used_crate_source: FxHashMap>, used_crates_static: Vec<(CrateNum, LibSource)>, used_crates_dynamic: Vec<(CrateNum, LibSource)>, + wasm_custom_sections: BTreeMap>, } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 69879bbe85d6e..f86fe1fb75643 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1182,9 +1182,15 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. - hir::ItemStatic(..) | + hir::ItemStatic(..) => { + tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); + } hir::ItemConst(..) => { tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); + if it.attrs.iter().any(|a| a.check_name("wasm_custom_section")) { + let def_id = tcx.hir.local_def_id(it.id); + check_const_is_u8_array(tcx, def_id, it.span); + } } hir::ItemEnum(ref enum_definition, _) => { check_enum(tcx, @@ -1256,6 +1262,21 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item } } +fn check_const_is_u8_array<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + span: Span) { + match tcx.type_of(def_id).sty { + ty::TyArray(t, _) => { + match t.sty { + ty::TyUint(ast::UintTy::U8) => return, + _ => {} + } + } + _ => {} + } + tcx.sess.span_err(span, "must be an array of bytes like `[u8; N]`"); +} + fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId, item: &hir::Item) { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 915396d29fe26..dbcfee208ca2d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -451,6 +451,9 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), + + // The #[wasm_custom_section] attribute + (active, wasm_custom_section, "1.26.0", None, None), ); declare_features! ( @@ -1004,6 +1007,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "never will be stable", cfg_fn!(rustc_attrs))), + ("wasm_custom_section", Whitelisted, Gated(Stability::Unstable, + "wasm_custom_section", + "attribute is currently unstable", + cfg_fn!(wasm_custom_section))), + // Crate level attributes ("crate_name", CrateLevel, Ungated), ("crate_type", CrateLevel, Ungated), diff --git a/src/test/run-make/a-b-a-linker-guard/Makefile b/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/Makefile rename to src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile diff --git a/src/test/run-make/a-b-a-linker-guard/a.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/a.rs rename to src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs diff --git a/src/test/run-make/a-b-a-linker-guard/b.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/b.rs rename to src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs diff --git a/src/test/run-make/alloc-extern-crates/Makefile b/src/test/run-make-fulldeps/alloc-extern-crates/Makefile similarity index 100% rename from src/test/run-make/alloc-extern-crates/Makefile rename to src/test/run-make-fulldeps/alloc-extern-crates/Makefile diff --git a/src/test/run-make/alloc-extern-crates/fakealloc.rs b/src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs similarity index 100% rename from src/test/run-make/alloc-extern-crates/fakealloc.rs rename to src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/Makefile b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile similarity index 100% rename from src/test/run-make/allow-non-lint-warnings-cmdline/Makefile rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs similarity index 100% rename from src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs diff --git a/src/test/run-make/allow-warnings-cmdline-stability/Makefile b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/Makefile rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile diff --git a/src/test/run-make/allow-warnings-cmdline-stability/bar.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/bar.rs rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs diff --git a/src/test/run-make/allow-warnings-cmdline-stability/foo.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/foo.rs rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs diff --git a/src/test/run-make/archive-duplicate-names/Makefile b/src/test/run-make-fulldeps/archive-duplicate-names/Makefile similarity index 100% rename from src/test/run-make/archive-duplicate-names/Makefile rename to src/test/run-make-fulldeps/archive-duplicate-names/Makefile diff --git a/src/test/run-make/archive-duplicate-names/bar.c b/src/test/run-make-fulldeps/archive-duplicate-names/bar.c similarity index 100% rename from src/test/run-make/archive-duplicate-names/bar.c rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.c diff --git a/src/test/run-make/archive-duplicate-names/bar.rs b/src/test/run-make-fulldeps/archive-duplicate-names/bar.rs similarity index 100% rename from src/test/run-make/archive-duplicate-names/bar.rs rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.rs diff --git a/src/test/run-make/archive-duplicate-names/foo.c b/src/test/run-make-fulldeps/archive-duplicate-names/foo.c similarity index 100% rename from src/test/run-make/archive-duplicate-names/foo.c rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.c diff --git a/src/test/run-make/archive-duplicate-names/foo.rs b/src/test/run-make-fulldeps/archive-duplicate-names/foo.rs similarity index 100% rename from src/test/run-make/archive-duplicate-names/foo.rs rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.rs diff --git a/src/test/run-make/atomic-lock-free/Makefile b/src/test/run-make-fulldeps/atomic-lock-free/Makefile similarity index 100% rename from src/test/run-make/atomic-lock-free/Makefile rename to src/test/run-make-fulldeps/atomic-lock-free/Makefile diff --git a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs similarity index 100% rename from src/test/run-make/atomic-lock-free/atomic_lock_free.rs rename to src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs diff --git a/src/test/run-make/bare-outfile/Makefile b/src/test/run-make-fulldeps/bare-outfile/Makefile similarity index 100% rename from src/test/run-make/bare-outfile/Makefile rename to src/test/run-make-fulldeps/bare-outfile/Makefile diff --git a/src/test/run-make/bare-outfile/foo.rs b/src/test/run-make-fulldeps/bare-outfile/foo.rs similarity index 100% rename from src/test/run-make/bare-outfile/foo.rs rename to src/test/run-make-fulldeps/bare-outfile/foo.rs diff --git a/src/test/run-make/c-dynamic-dylib/Makefile b/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile similarity index 100% rename from src/test/run-make/c-dynamic-dylib/Makefile rename to src/test/run-make-fulldeps/c-dynamic-dylib/Makefile diff --git a/src/test/run-make/c-dynamic-dylib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs similarity index 100% rename from src/test/run-make/c-dynamic-dylib/bar.rs rename to src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs diff --git a/src/test/run-make/c-dynamic-dylib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c similarity index 100% rename from src/test/run-make/c-dynamic-dylib/cfoo.c rename to src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c diff --git a/src/test/run-make/c-dynamic-dylib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-dynamic-dylib/foo.rs rename to src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs diff --git a/src/test/run-make/c-dynamic-rlib/Makefile b/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile similarity index 100% rename from src/test/run-make/c-dynamic-rlib/Makefile rename to src/test/run-make-fulldeps/c-dynamic-rlib/Makefile diff --git a/src/test/run-make/c-dynamic-rlib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs similarity index 100% rename from src/test/run-make/c-dynamic-rlib/bar.rs rename to src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs diff --git a/src/test/run-make/c-dynamic-rlib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c similarity index 100% rename from src/test/run-make/c-dynamic-rlib/cfoo.c rename to src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c diff --git a/src/test/run-make/c-dynamic-rlib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs similarity index 100% rename from src/test/run-make/c-dynamic-rlib/foo.rs rename to src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs diff --git a/src/test/run-make/c-link-to-rust-dylib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/Makefile rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile diff --git a/src/test/run-make/c-link-to-rust-dylib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/bar.c rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c diff --git a/src/test/run-make/c-link-to-rust-dylib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/foo.rs rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/Makefile rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile diff --git a/src/test/run-make/c-link-to-rust-staticlib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/bar.c rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c diff --git a/src/test/run-make/c-link-to-rust-staticlib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/foo.rs rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs diff --git a/src/test/run-make/c-static-dylib/Makefile b/src/test/run-make-fulldeps/c-static-dylib/Makefile similarity index 100% rename from src/test/run-make/c-static-dylib/Makefile rename to src/test/run-make-fulldeps/c-static-dylib/Makefile diff --git a/src/test/run-make/c-static-dylib/bar.rs b/src/test/run-make-fulldeps/c-static-dylib/bar.rs similarity index 100% rename from src/test/run-make/c-static-dylib/bar.rs rename to src/test/run-make-fulldeps/c-static-dylib/bar.rs diff --git a/src/test/run-make/c-static-dylib/cfoo.c b/src/test/run-make-fulldeps/c-static-dylib/cfoo.c similarity index 100% rename from src/test/run-make/c-static-dylib/cfoo.c rename to src/test/run-make-fulldeps/c-static-dylib/cfoo.c diff --git a/src/test/run-make/c-static-dylib/foo.rs b/src/test/run-make-fulldeps/c-static-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-static-dylib/foo.rs rename to src/test/run-make-fulldeps/c-static-dylib/foo.rs diff --git a/src/test/run-make/c-static-rlib/Makefile b/src/test/run-make-fulldeps/c-static-rlib/Makefile similarity index 100% rename from src/test/run-make/c-static-rlib/Makefile rename to src/test/run-make-fulldeps/c-static-rlib/Makefile diff --git a/src/test/run-make/c-static-rlib/bar.rs b/src/test/run-make-fulldeps/c-static-rlib/bar.rs similarity index 100% rename from src/test/run-make/c-static-rlib/bar.rs rename to src/test/run-make-fulldeps/c-static-rlib/bar.rs diff --git a/src/test/run-make/c-static-rlib/cfoo.c b/src/test/run-make-fulldeps/c-static-rlib/cfoo.c similarity index 100% rename from src/test/run-make/c-static-rlib/cfoo.c rename to src/test/run-make-fulldeps/c-static-rlib/cfoo.c diff --git a/src/test/run-make/c-static-rlib/foo.rs b/src/test/run-make-fulldeps/c-static-rlib/foo.rs similarity index 100% rename from src/test/run-make/c-static-rlib/foo.rs rename to src/test/run-make-fulldeps/c-static-rlib/foo.rs diff --git a/src/test/run-make/cat-and-grep-sanity-check/Makefile b/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile similarity index 100% rename from src/test/run-make/cat-and-grep-sanity-check/Makefile rename to src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile diff --git a/src/test/run-make/cdylib-fewer-symbols/Makefile b/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile similarity index 100% rename from src/test/run-make/cdylib-fewer-symbols/Makefile rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile diff --git a/src/test/run-make/cdylib-fewer-symbols/foo.rs b/src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs similarity index 100% rename from src/test/run-make/cdylib-fewer-symbols/foo.rs rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs diff --git a/src/test/run-make/cdylib/Makefile b/src/test/run-make-fulldeps/cdylib/Makefile similarity index 100% rename from src/test/run-make/cdylib/Makefile rename to src/test/run-make-fulldeps/cdylib/Makefile diff --git a/src/test/run-make/cdylib/bar.rs b/src/test/run-make-fulldeps/cdylib/bar.rs similarity index 100% rename from src/test/run-make/cdylib/bar.rs rename to src/test/run-make-fulldeps/cdylib/bar.rs diff --git a/src/test/run-make/cdylib/foo.c b/src/test/run-make-fulldeps/cdylib/foo.c similarity index 100% rename from src/test/run-make/cdylib/foo.c rename to src/test/run-make-fulldeps/cdylib/foo.c diff --git a/src/test/run-make/cdylib/foo.rs b/src/test/run-make-fulldeps/cdylib/foo.rs similarity index 100% rename from src/test/run-make/cdylib/foo.rs rename to src/test/run-make-fulldeps/cdylib/foo.rs diff --git a/src/test/run-make/codegen-options-parsing/Makefile b/src/test/run-make-fulldeps/codegen-options-parsing/Makefile similarity index 100% rename from src/test/run-make/codegen-options-parsing/Makefile rename to src/test/run-make-fulldeps/codegen-options-parsing/Makefile diff --git a/src/test/run-make/codegen-options-parsing/dummy.rs b/src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs similarity index 100% rename from src/test/run-make/codegen-options-parsing/dummy.rs rename to src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs diff --git a/src/test/run-make/compile-stdin/Makefile b/src/test/run-make-fulldeps/compile-stdin/Makefile similarity index 100% rename from src/test/run-make/compile-stdin/Makefile rename to src/test/run-make-fulldeps/compile-stdin/Makefile diff --git a/src/test/run-make/compiler-lookup-paths-2/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/Makefile rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile diff --git a/src/test/run-make/compiler-lookup-paths-2/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/a.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs diff --git a/src/test/run-make/compiler-lookup-paths-2/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/b.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs diff --git a/src/test/run-make/compiler-lookup-paths-2/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/c.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs diff --git a/src/test/run-make/compiler-lookup-paths/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile similarity index 100% rename from src/test/run-make/compiler-lookup-paths/Makefile rename to src/test/run-make-fulldeps/compiler-lookup-paths/Makefile diff --git a/src/test/run-make/compiler-lookup-paths/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/a.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/a.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/a.rs diff --git a/src/test/run-make/compiler-lookup-paths/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/b.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/b.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/b.rs diff --git a/src/test/run-make/compiler-lookup-paths/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/c.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/c.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/c.rs diff --git a/src/test/run-make/compiler-lookup-paths/d.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/d.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/d.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/d.rs diff --git a/src/test/run-make/compiler-lookup-paths/e.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/e.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/e.rs diff --git a/src/test/run-make/compiler-lookup-paths/e2.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/e2.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs diff --git a/src/test/run-make/compiler-lookup-paths/f.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/f.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/f.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/f.rs diff --git a/src/test/run-make/compiler-lookup-paths/native.c b/src/test/run-make-fulldeps/compiler-lookup-paths/native.c similarity index 100% rename from src/test/run-make/compiler-lookup-paths/native.c rename to src/test/run-make-fulldeps/compiler-lookup-paths/native.c diff --git a/src/test/run-make/compiler-rt-works-on-mingw/Makefile b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/Makefile rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.cpp b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/foo.cpp rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.rs b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/foo.rs rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs diff --git a/src/test/run-make/crate-data-smoke/Makefile b/src/test/run-make-fulldeps/crate-data-smoke/Makefile similarity index 100% rename from src/test/run-make/crate-data-smoke/Makefile rename to src/test/run-make-fulldeps/crate-data-smoke/Makefile diff --git a/src/test/run-make/crate-data-smoke/crate.rs b/src/test/run-make-fulldeps/crate-data-smoke/crate.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/crate.rs rename to src/test/run-make-fulldeps/crate-data-smoke/crate.rs diff --git a/src/test/run-make/crate-data-smoke/lib.rs b/src/test/run-make-fulldeps/crate-data-smoke/lib.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/lib.rs rename to src/test/run-make-fulldeps/crate-data-smoke/lib.rs diff --git a/src/test/run-make/crate-data-smoke/rlib.rs b/src/test/run-make-fulldeps/crate-data-smoke/rlib.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/rlib.rs rename to src/test/run-make-fulldeps/crate-data-smoke/rlib.rs diff --git a/src/test/run-make/crate-name-priority/Makefile b/src/test/run-make-fulldeps/crate-name-priority/Makefile similarity index 100% rename from src/test/run-make/crate-name-priority/Makefile rename to src/test/run-make-fulldeps/crate-name-priority/Makefile diff --git a/src/test/run-make/crate-name-priority/foo.rs b/src/test/run-make-fulldeps/crate-name-priority/foo.rs similarity index 100% rename from src/test/run-make/crate-name-priority/foo.rs rename to src/test/run-make-fulldeps/crate-name-priority/foo.rs diff --git a/src/test/run-make/crate-name-priority/foo1.rs b/src/test/run-make-fulldeps/crate-name-priority/foo1.rs similarity index 100% rename from src/test/run-make/crate-name-priority/foo1.rs rename to src/test/run-make-fulldeps/crate-name-priority/foo1.rs diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make-fulldeps/debug-assertions/Makefile similarity index 100% rename from src/test/run-make/debug-assertions/Makefile rename to src/test/run-make-fulldeps/debug-assertions/Makefile diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make-fulldeps/debug-assertions/debug.rs similarity index 100% rename from src/test/run-make/debug-assertions/debug.rs rename to src/test/run-make-fulldeps/debug-assertions/debug.rs diff --git a/src/test/run-make/dep-info-doesnt-run-much/Makefile b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile similarity index 100% rename from src/test/run-make/dep-info-doesnt-run-much/Makefile rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile diff --git a/src/test/run-make/dep-info-doesnt-run-much/foo.rs b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs similarity index 100% rename from src/test/run-make/dep-info-doesnt-run-much/foo.rs rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs diff --git a/src/test/run-make/dep-info-spaces/Makefile b/src/test/run-make-fulldeps/dep-info-spaces/Makefile similarity index 100% rename from src/test/run-make/dep-info-spaces/Makefile rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile diff --git a/src/test/run-make/dep-info-spaces/Makefile.foo b/src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo similarity index 100% rename from src/test/run-make/dep-info-spaces/Makefile.foo rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo diff --git a/src/test/run-make/dep-info-spaces/bar.rs b/src/test/run-make-fulldeps/dep-info-spaces/bar.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/bar.rs rename to src/test/run-make-fulldeps/dep-info-spaces/bar.rs diff --git a/src/test/run-make/dep-info-spaces/foo foo.rs b/src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/foo foo.rs rename to src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs diff --git a/src/test/run-make/dep-info-spaces/lib.rs b/src/test/run-make-fulldeps/dep-info-spaces/lib.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/lib.rs rename to src/test/run-make-fulldeps/dep-info-spaces/lib.rs diff --git a/src/test/run-make/dep-info/Makefile b/src/test/run-make-fulldeps/dep-info/Makefile similarity index 100% rename from src/test/run-make/dep-info/Makefile rename to src/test/run-make-fulldeps/dep-info/Makefile diff --git a/src/test/run-make/dep-info/Makefile.foo b/src/test/run-make-fulldeps/dep-info/Makefile.foo similarity index 100% rename from src/test/run-make/dep-info/Makefile.foo rename to src/test/run-make-fulldeps/dep-info/Makefile.foo diff --git a/src/test/run-make/dep-info/bar.rs b/src/test/run-make-fulldeps/dep-info/bar.rs similarity index 100% rename from src/test/run-make/dep-info/bar.rs rename to src/test/run-make-fulldeps/dep-info/bar.rs diff --git a/src/test/run-make/dep-info/foo.rs b/src/test/run-make-fulldeps/dep-info/foo.rs similarity index 100% rename from src/test/run-make/dep-info/foo.rs rename to src/test/run-make-fulldeps/dep-info/foo.rs diff --git a/src/test/run-make/dep-info/lib.rs b/src/test/run-make-fulldeps/dep-info/lib.rs similarity index 100% rename from src/test/run-make/dep-info/lib.rs rename to src/test/run-make-fulldeps/dep-info/lib.rs diff --git a/src/test/run-make/dep-info/lib2.rs b/src/test/run-make-fulldeps/dep-info/lib2.rs similarity index 100% rename from src/test/run-make/dep-info/lib2.rs rename to src/test/run-make-fulldeps/dep-info/lib2.rs diff --git a/src/test/run-make/duplicate-output-flavors/Makefile b/src/test/run-make-fulldeps/duplicate-output-flavors/Makefile similarity index 100% rename from src/test/run-make/duplicate-output-flavors/Makefile rename to src/test/run-make-fulldeps/duplicate-output-flavors/Makefile diff --git a/src/test/run-make/duplicate-output-flavors/foo.rs b/src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs similarity index 100% rename from src/test/run-make/duplicate-output-flavors/foo.rs rename to src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs diff --git a/src/test/run-make/dylib-chain/Makefile b/src/test/run-make-fulldeps/dylib-chain/Makefile similarity index 100% rename from src/test/run-make/dylib-chain/Makefile rename to src/test/run-make-fulldeps/dylib-chain/Makefile diff --git a/src/test/run-make/dylib-chain/m1.rs b/src/test/run-make-fulldeps/dylib-chain/m1.rs similarity index 100% rename from src/test/run-make/dylib-chain/m1.rs rename to src/test/run-make-fulldeps/dylib-chain/m1.rs diff --git a/src/test/run-make/dylib-chain/m2.rs b/src/test/run-make-fulldeps/dylib-chain/m2.rs similarity index 100% rename from src/test/run-make/dylib-chain/m2.rs rename to src/test/run-make-fulldeps/dylib-chain/m2.rs diff --git a/src/test/run-make/dylib-chain/m3.rs b/src/test/run-make-fulldeps/dylib-chain/m3.rs similarity index 100% rename from src/test/run-make/dylib-chain/m3.rs rename to src/test/run-make-fulldeps/dylib-chain/m3.rs diff --git a/src/test/run-make/dylib-chain/m4.rs b/src/test/run-make-fulldeps/dylib-chain/m4.rs similarity index 100% rename from src/test/run-make/dylib-chain/m4.rs rename to src/test/run-make-fulldeps/dylib-chain/m4.rs diff --git a/src/test/run-make/emit/Makefile b/src/test/run-make-fulldeps/emit/Makefile similarity index 100% rename from src/test/run-make/emit/Makefile rename to src/test/run-make-fulldeps/emit/Makefile diff --git a/src/test/run-make/emit/test-24876.rs b/src/test/run-make-fulldeps/emit/test-24876.rs similarity index 100% rename from src/test/run-make/emit/test-24876.rs rename to src/test/run-make-fulldeps/emit/test-24876.rs diff --git a/src/test/run-make/emit/test-26235.rs b/src/test/run-make-fulldeps/emit/test-26235.rs similarity index 100% rename from src/test/run-make/emit/test-26235.rs rename to src/test/run-make-fulldeps/emit/test-26235.rs diff --git a/src/test/run-make/error-found-staticlib-instead-crate/Makefile b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/Makefile rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile diff --git a/src/test/run-make/error-found-staticlib-instead-crate/bar.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/bar.rs rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs diff --git a/src/test/run-make/error-found-staticlib-instead-crate/foo.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/foo.rs rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs diff --git a/src/test/run-make/error-writing-dependencies/Makefile b/src/test/run-make-fulldeps/error-writing-dependencies/Makefile similarity index 100% rename from src/test/run-make/error-writing-dependencies/Makefile rename to src/test/run-make-fulldeps/error-writing-dependencies/Makefile diff --git a/src/test/run-make/error-writing-dependencies/foo.rs b/src/test/run-make-fulldeps/error-writing-dependencies/foo.rs similarity index 100% rename from src/test/run-make/error-writing-dependencies/foo.rs rename to src/test/run-make-fulldeps/error-writing-dependencies/foo.rs diff --git a/src/test/run-make/extern-diff-internal-name/Makefile b/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile similarity index 100% rename from src/test/run-make/extern-diff-internal-name/Makefile rename to src/test/run-make-fulldeps/extern-diff-internal-name/Makefile diff --git a/src/test/run-make/extern-diff-internal-name/lib.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs similarity index 100% rename from src/test/run-make/extern-diff-internal-name/lib.rs rename to src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs diff --git a/src/test/run-make/extern-diff-internal-name/test.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/test.rs similarity index 100% rename from src/test/run-make/extern-diff-internal-name/test.rs rename to src/test/run-make-fulldeps/extern-diff-internal-name/test.rs diff --git a/src/test/run-make/extern-flag-disambiguates/Makefile b/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/Makefile rename to src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile diff --git a/src/test/run-make/extern-flag-disambiguates/a.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/a.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs diff --git a/src/test/run-make/extern-flag-disambiguates/b.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/b.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs diff --git a/src/test/run-make/extern-flag-disambiguates/c.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/c.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs diff --git a/src/test/run-make/extern-flag-disambiguates/d.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/d.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs diff --git a/src/test/run-make/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile similarity index 100% rename from src/test/run-make/extern-flag-fun/Makefile rename to src/test/run-make-fulldeps/extern-flag-fun/Makefile diff --git a/src/test/run-make/extern-flag-fun/bar-alt.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/bar-alt.rs rename to src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs diff --git a/src/test/run-make/extern-flag-fun/bar.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/bar.rs rename to src/test/run-make-fulldeps/extern-flag-fun/bar.rs diff --git a/src/test/run-make/extern-flag-fun/foo.rs b/src/test/run-make-fulldeps/extern-flag-fun/foo.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/foo.rs rename to src/test/run-make-fulldeps/extern-flag-fun/foo.rs diff --git a/src/test/run-make/extern-fn-generic/Makefile b/src/test/run-make-fulldeps/extern-fn-generic/Makefile similarity index 100% rename from src/test/run-make/extern-fn-generic/Makefile rename to src/test/run-make-fulldeps/extern-fn-generic/Makefile diff --git a/src/test/run-make/extern-fn-generic/test.c b/src/test/run-make-fulldeps/extern-fn-generic/test.c similarity index 100% rename from src/test/run-make/extern-fn-generic/test.c rename to src/test/run-make-fulldeps/extern-fn-generic/test.c diff --git a/src/test/run-make/extern-fn-generic/test.rs b/src/test/run-make-fulldeps/extern-fn-generic/test.rs similarity index 100% rename from src/test/run-make/extern-fn-generic/test.rs rename to src/test/run-make-fulldeps/extern-fn-generic/test.rs diff --git a/src/test/run-make/extern-fn-generic/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs similarity index 100% rename from src/test/run-make/extern-fn-generic/testcrate.rs rename to src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs diff --git a/src/test/run-make/extern-fn-mangle/Makefile b/src/test/run-make-fulldeps/extern-fn-mangle/Makefile similarity index 100% rename from src/test/run-make/extern-fn-mangle/Makefile rename to src/test/run-make-fulldeps/extern-fn-mangle/Makefile diff --git a/src/test/run-make/extern-fn-mangle/test.c b/src/test/run-make-fulldeps/extern-fn-mangle/test.c similarity index 100% rename from src/test/run-make/extern-fn-mangle/test.c rename to src/test/run-make-fulldeps/extern-fn-mangle/test.c diff --git a/src/test/run-make/extern-fn-mangle/test.rs b/src/test/run-make-fulldeps/extern-fn-mangle/test.rs similarity index 100% rename from src/test/run-make/extern-fn-mangle/test.rs rename to src/test/run-make-fulldeps/extern-fn-mangle/test.rs diff --git a/src/test/run-make/extern-fn-reachable/Makefile b/src/test/run-make-fulldeps/extern-fn-reachable/Makefile similarity index 100% rename from src/test/run-make/extern-fn-reachable/Makefile rename to src/test/run-make-fulldeps/extern-fn-reachable/Makefile diff --git a/src/test/run-make/extern-fn-reachable/dylib.rs b/src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs similarity index 100% rename from src/test/run-make/extern-fn-reachable/dylib.rs rename to src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs diff --git a/src/test/run-make/extern-fn-reachable/main.rs b/src/test/run-make-fulldeps/extern-fn-reachable/main.rs similarity index 100% rename from src/test/run-make/extern-fn-reachable/main.rs rename to src/test/run-make-fulldeps/extern-fn-reachable/main.rs diff --git a/src/test/run-make/extern-fn-struct-passing-abi/Makefile b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/Makefile rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/test.c rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/test.rs rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs diff --git a/src/test/run-make/extern-fn-with-extern-types/Makefile b/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile diff --git a/src/test/run-make/extern-fn-with-extern-types/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/ctest.c rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c diff --git a/src/test/run-make/extern-fn-with-extern-types/test.rs b/src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs diff --git a/src/test/run-make/extern-fn-with-packed-struct/Makefile b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.c b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/test.c rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs diff --git a/src/test/run-make/extern-fn-with-union/Makefile b/src/test/run-make-fulldeps/extern-fn-with-union/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-union/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-union/Makefile diff --git a/src/test/run-make/extern-fn-with-union/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c similarity index 100% rename from src/test/run-make/extern-fn-with-union/ctest.c rename to src/test/run-make-fulldeps/extern-fn-with-union/ctest.c diff --git a/src/test/run-make/extern-fn-with-union/test.rs b/src/test/run-make-fulldeps/extern-fn-with-union/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-union/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-union/test.rs diff --git a/src/test/run-make/extern-fn-with-union/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs similarity index 100% rename from src/test/run-make/extern-fn-with-union/testcrate.rs rename to src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs diff --git a/src/test/run-make/extern-multiple-copies/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies/Makefile similarity index 100% rename from src/test/run-make/extern-multiple-copies/Makefile rename to src/test/run-make-fulldeps/extern-multiple-copies/Makefile diff --git a/src/test/run-make/extern-multiple-copies/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies/bar.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/bar.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/bar.rs diff --git a/src/test/run-make/extern-multiple-copies/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/foo1.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs diff --git a/src/test/run-make/extern-multiple-copies/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/foo2.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs diff --git a/src/test/run-make/extern-multiple-copies2/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile similarity index 100% rename from src/test/run-make/extern-multiple-copies2/Makefile rename to src/test/run-make-fulldeps/extern-multiple-copies2/Makefile diff --git a/src/test/run-make/extern-multiple-copies2/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/bar.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs diff --git a/src/test/run-make/extern-multiple-copies2/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/foo1.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs diff --git a/src/test/run-make/extern-multiple-copies2/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/foo2.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs diff --git a/src/test/run-make/extern-overrides-distribution/Makefile b/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile similarity index 100% rename from src/test/run-make/extern-overrides-distribution/Makefile rename to src/test/run-make-fulldeps/extern-overrides-distribution/Makefile diff --git a/src/test/run-make/extern-overrides-distribution/libc.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs similarity index 100% rename from src/test/run-make/extern-overrides-distribution/libc.rs rename to src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs diff --git a/src/test/run-make/extern-overrides-distribution/main.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/main.rs similarity index 100% rename from src/test/run-make/extern-overrides-distribution/main.rs rename to src/test/run-make-fulldeps/extern-overrides-distribution/main.rs diff --git a/src/test/run-make/extra-filename-with-temp-outputs/Makefile b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile similarity index 100% rename from src/test/run-make/extra-filename-with-temp-outputs/Makefile rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile diff --git a/src/test/run-make/extra-filename-with-temp-outputs/foo.rs b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs similarity index 100% rename from src/test/run-make/extra-filename-with-temp-outputs/foo.rs rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs diff --git a/src/test/run-make/fpic/Makefile b/src/test/run-make-fulldeps/fpic/Makefile similarity index 100% rename from src/test/run-make/fpic/Makefile rename to src/test/run-make-fulldeps/fpic/Makefile diff --git a/src/test/run-make/fpic/hello.rs b/src/test/run-make-fulldeps/fpic/hello.rs similarity index 100% rename from src/test/run-make/fpic/hello.rs rename to src/test/run-make-fulldeps/fpic/hello.rs diff --git a/src/test/run-make/hir-tree/Makefile b/src/test/run-make-fulldeps/hir-tree/Makefile similarity index 100% rename from src/test/run-make/hir-tree/Makefile rename to src/test/run-make-fulldeps/hir-tree/Makefile diff --git a/src/test/run-make/hir-tree/input.rs b/src/test/run-make-fulldeps/hir-tree/input.rs similarity index 100% rename from src/test/run-make/hir-tree/input.rs rename to src/test/run-make-fulldeps/hir-tree/input.rs diff --git a/src/test/run-make/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/Makefile rename to src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile diff --git a/src/test/run-make/hotplug_codegen_backend/some_crate.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/some_crate.rs rename to src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/the_backend.rs rename to src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs diff --git a/src/test/run-make/include_bytes_deps/Makefile b/src/test/run-make-fulldeps/include_bytes_deps/Makefile similarity index 100% rename from src/test/run-make/include_bytes_deps/Makefile rename to src/test/run-make-fulldeps/include_bytes_deps/Makefile diff --git a/src/test/run-make/include_bytes_deps/input.bin b/src/test/run-make-fulldeps/include_bytes_deps/input.bin similarity index 100% rename from src/test/run-make/include_bytes_deps/input.bin rename to src/test/run-make-fulldeps/include_bytes_deps/input.bin diff --git a/src/test/run-make/include_bytes_deps/input.md b/src/test/run-make-fulldeps/include_bytes_deps/input.md similarity index 100% rename from src/test/run-make/include_bytes_deps/input.md rename to src/test/run-make-fulldeps/include_bytes_deps/input.md diff --git a/src/test/run-make/include_bytes_deps/input.txt b/src/test/run-make-fulldeps/include_bytes_deps/input.txt similarity index 100% rename from src/test/run-make/include_bytes_deps/input.txt rename to src/test/run-make-fulldeps/include_bytes_deps/input.txt diff --git a/src/test/run-make/include_bytes_deps/main.rs b/src/test/run-make-fulldeps/include_bytes_deps/main.rs similarity index 100% rename from src/test/run-make/include_bytes_deps/main.rs rename to src/test/run-make-fulldeps/include_bytes_deps/main.rs diff --git a/src/test/run-make/inline-always-many-cgu/Makefile b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile similarity index 100% rename from src/test/run-make/inline-always-many-cgu/Makefile rename to src/test/run-make-fulldeps/inline-always-many-cgu/Makefile diff --git a/src/test/run-make/inline-always-many-cgu/foo.rs b/src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs similarity index 100% rename from src/test/run-make/inline-always-many-cgu/foo.rs rename to src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs diff --git a/src/test/run-make/interdependent-c-libraries/Makefile b/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile similarity index 100% rename from src/test/run-make/interdependent-c-libraries/Makefile rename to src/test/run-make-fulldeps/interdependent-c-libraries/Makefile diff --git a/src/test/run-make/interdependent-c-libraries/bar.c b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c similarity index 100% rename from src/test/run-make/interdependent-c-libraries/bar.c rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.c diff --git a/src/test/run-make/interdependent-c-libraries/bar.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/bar.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs diff --git a/src/test/run-make/interdependent-c-libraries/foo.c b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c similarity index 100% rename from src/test/run-make/interdependent-c-libraries/foo.c rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.c diff --git a/src/test/run-make/interdependent-c-libraries/foo.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/foo.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs diff --git a/src/test/run-make/interdependent-c-libraries/main.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/main.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/main.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/main.rs diff --git a/src/test/run-make/intrinsic-unreachable/Makefile b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile similarity index 100% rename from src/test/run-make/intrinsic-unreachable/Makefile rename to src/test/run-make-fulldeps/intrinsic-unreachable/Makefile diff --git a/src/test/run-make/intrinsic-unreachable/exit-ret.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs similarity index 100% rename from src/test/run-make/intrinsic-unreachable/exit-ret.rs rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs diff --git a/src/test/run-make/intrinsic-unreachable/exit-unreachable.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs similarity index 100% rename from src/test/run-make/intrinsic-unreachable/exit-unreachable.rs rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs diff --git a/src/test/run-make/invalid-library/Makefile b/src/test/run-make-fulldeps/invalid-library/Makefile similarity index 100% rename from src/test/run-make/invalid-library/Makefile rename to src/test/run-make-fulldeps/invalid-library/Makefile diff --git a/src/test/run-make/invalid-library/foo.rs b/src/test/run-make-fulldeps/invalid-library/foo.rs similarity index 100% rename from src/test/run-make/invalid-library/foo.rs rename to src/test/run-make-fulldeps/invalid-library/foo.rs diff --git a/src/test/run-make/invalid-staticlib/Makefile b/src/test/run-make-fulldeps/invalid-staticlib/Makefile similarity index 100% rename from src/test/run-make/invalid-staticlib/Makefile rename to src/test/run-make-fulldeps/invalid-staticlib/Makefile diff --git a/src/test/run-make/issue-11908/Makefile b/src/test/run-make-fulldeps/issue-11908/Makefile similarity index 100% rename from src/test/run-make/issue-11908/Makefile rename to src/test/run-make-fulldeps/issue-11908/Makefile diff --git a/src/test/run-make/issue-11908/bar.rs b/src/test/run-make-fulldeps/issue-11908/bar.rs similarity index 100% rename from src/test/run-make/issue-11908/bar.rs rename to src/test/run-make-fulldeps/issue-11908/bar.rs diff --git a/src/test/run-make/issue-11908/foo.rs b/src/test/run-make-fulldeps/issue-11908/foo.rs similarity index 100% rename from src/test/run-make/issue-11908/foo.rs rename to src/test/run-make-fulldeps/issue-11908/foo.rs diff --git a/src/test/run-make/issue-14500/Makefile b/src/test/run-make-fulldeps/issue-14500/Makefile similarity index 100% rename from src/test/run-make/issue-14500/Makefile rename to src/test/run-make-fulldeps/issue-14500/Makefile diff --git a/src/test/run-make/issue-14500/bar.rs b/src/test/run-make-fulldeps/issue-14500/bar.rs similarity index 100% rename from src/test/run-make/issue-14500/bar.rs rename to src/test/run-make-fulldeps/issue-14500/bar.rs diff --git a/src/test/run-make/issue-14500/foo.c b/src/test/run-make-fulldeps/issue-14500/foo.c similarity index 100% rename from src/test/run-make/issue-14500/foo.c rename to src/test/run-make-fulldeps/issue-14500/foo.c diff --git a/src/test/run-make/issue-14500/foo.rs b/src/test/run-make-fulldeps/issue-14500/foo.rs similarity index 100% rename from src/test/run-make/issue-14500/foo.rs rename to src/test/run-make-fulldeps/issue-14500/foo.rs diff --git a/src/test/run-make/issue-14698/Makefile b/src/test/run-make-fulldeps/issue-14698/Makefile similarity index 100% rename from src/test/run-make/issue-14698/Makefile rename to src/test/run-make-fulldeps/issue-14698/Makefile diff --git a/src/test/run-make/issue-14698/foo.rs b/src/test/run-make-fulldeps/issue-14698/foo.rs similarity index 100% rename from src/test/run-make/issue-14698/foo.rs rename to src/test/run-make-fulldeps/issue-14698/foo.rs diff --git a/src/test/run-make/issue-15460/Makefile b/src/test/run-make-fulldeps/issue-15460/Makefile similarity index 100% rename from src/test/run-make/issue-15460/Makefile rename to src/test/run-make-fulldeps/issue-15460/Makefile diff --git a/src/test/run-make/issue-15460/bar.rs b/src/test/run-make-fulldeps/issue-15460/bar.rs similarity index 100% rename from src/test/run-make/issue-15460/bar.rs rename to src/test/run-make-fulldeps/issue-15460/bar.rs diff --git a/src/test/run-make/issue-15460/foo.c b/src/test/run-make-fulldeps/issue-15460/foo.c similarity index 100% rename from src/test/run-make/issue-15460/foo.c rename to src/test/run-make-fulldeps/issue-15460/foo.c diff --git a/src/test/run-make/issue-15460/foo.rs b/src/test/run-make-fulldeps/issue-15460/foo.rs similarity index 100% rename from src/test/run-make/issue-15460/foo.rs rename to src/test/run-make-fulldeps/issue-15460/foo.rs diff --git a/src/test/run-make/issue-18943/Makefile b/src/test/run-make-fulldeps/issue-18943/Makefile similarity index 100% rename from src/test/run-make/issue-18943/Makefile rename to src/test/run-make-fulldeps/issue-18943/Makefile diff --git a/src/test/run-make/issue-18943/foo.rs b/src/test/run-make-fulldeps/issue-18943/foo.rs similarity index 100% rename from src/test/run-make/issue-18943/foo.rs rename to src/test/run-make-fulldeps/issue-18943/foo.rs diff --git a/src/test/run-make/issue-19371/Makefile b/src/test/run-make-fulldeps/issue-19371/Makefile similarity index 100% rename from src/test/run-make/issue-19371/Makefile rename to src/test/run-make-fulldeps/issue-19371/Makefile diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs similarity index 100% rename from src/test/run-make/issue-19371/foo.rs rename to src/test/run-make-fulldeps/issue-19371/foo.rs diff --git a/src/test/run-make/issue-20626/Makefile b/src/test/run-make-fulldeps/issue-20626/Makefile similarity index 100% rename from src/test/run-make/issue-20626/Makefile rename to src/test/run-make-fulldeps/issue-20626/Makefile diff --git a/src/test/run-make/issue-20626/foo.rs b/src/test/run-make-fulldeps/issue-20626/foo.rs similarity index 100% rename from src/test/run-make/issue-20626/foo.rs rename to src/test/run-make-fulldeps/issue-20626/foo.rs diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make-fulldeps/issue-22131/Makefile similarity index 100% rename from src/test/run-make/issue-22131/Makefile rename to src/test/run-make-fulldeps/issue-22131/Makefile diff --git a/src/test/run-make/issue-22131/foo.rs b/src/test/run-make-fulldeps/issue-22131/foo.rs similarity index 100% rename from src/test/run-make/issue-22131/foo.rs rename to src/test/run-make-fulldeps/issue-22131/foo.rs diff --git a/src/test/run-make/issue-24445/Makefile b/src/test/run-make-fulldeps/issue-24445/Makefile similarity index 100% rename from src/test/run-make/issue-24445/Makefile rename to src/test/run-make-fulldeps/issue-24445/Makefile diff --git a/src/test/run-make/issue-24445/foo.c b/src/test/run-make-fulldeps/issue-24445/foo.c similarity index 100% rename from src/test/run-make/issue-24445/foo.c rename to src/test/run-make-fulldeps/issue-24445/foo.c diff --git a/src/test/run-make/issue-24445/foo.rs b/src/test/run-make-fulldeps/issue-24445/foo.rs similarity index 100% rename from src/test/run-make/issue-24445/foo.rs rename to src/test/run-make-fulldeps/issue-24445/foo.rs diff --git a/src/test/run-make/issue-25581/Makefile b/src/test/run-make-fulldeps/issue-25581/Makefile similarity index 100% rename from src/test/run-make/issue-25581/Makefile rename to src/test/run-make-fulldeps/issue-25581/Makefile diff --git a/src/test/run-make/issue-25581/test.c b/src/test/run-make-fulldeps/issue-25581/test.c similarity index 100% rename from src/test/run-make/issue-25581/test.c rename to src/test/run-make-fulldeps/issue-25581/test.c diff --git a/src/test/run-make/issue-25581/test.rs b/src/test/run-make-fulldeps/issue-25581/test.rs similarity index 100% rename from src/test/run-make/issue-25581/test.rs rename to src/test/run-make-fulldeps/issue-25581/test.rs diff --git a/src/test/run-make/issue-26006/Makefile b/src/test/run-make-fulldeps/issue-26006/Makefile similarity index 100% rename from src/test/run-make/issue-26006/Makefile rename to src/test/run-make-fulldeps/issue-26006/Makefile diff --git a/src/test/run-make/issue-26006/in/libc/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs similarity index 100% rename from src/test/run-make/issue-26006/in/libc/lib.rs rename to src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs diff --git a/src/test/run-make/issue-26006/in/time/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs similarity index 100% rename from src/test/run-make/issue-26006/in/time/lib.rs rename to src/test/run-make-fulldeps/issue-26006/in/time/lib.rs diff --git a/src/test/run-make/issue-26092/Makefile b/src/test/run-make-fulldeps/issue-26092/Makefile similarity index 100% rename from src/test/run-make/issue-26092/Makefile rename to src/test/run-make-fulldeps/issue-26092/Makefile diff --git a/src/test/run-make/issue-26092/blank.rs b/src/test/run-make-fulldeps/issue-26092/blank.rs similarity index 100% rename from src/test/run-make/issue-26092/blank.rs rename to src/test/run-make-fulldeps/issue-26092/blank.rs diff --git a/src/test/run-make/issue-28595/Makefile b/src/test/run-make-fulldeps/issue-28595/Makefile similarity index 100% rename from src/test/run-make/issue-28595/Makefile rename to src/test/run-make-fulldeps/issue-28595/Makefile diff --git a/src/test/run-make/issue-28595/a.c b/src/test/run-make-fulldeps/issue-28595/a.c similarity index 100% rename from src/test/run-make/issue-28595/a.c rename to src/test/run-make-fulldeps/issue-28595/a.c diff --git a/src/test/run-make/issue-28595/a.rs b/src/test/run-make-fulldeps/issue-28595/a.rs similarity index 100% rename from src/test/run-make/issue-28595/a.rs rename to src/test/run-make-fulldeps/issue-28595/a.rs diff --git a/src/test/run-make/issue-28595/b.c b/src/test/run-make-fulldeps/issue-28595/b.c similarity index 100% rename from src/test/run-make/issue-28595/b.c rename to src/test/run-make-fulldeps/issue-28595/b.c diff --git a/src/test/run-make/issue-28595/b.rs b/src/test/run-make-fulldeps/issue-28595/b.rs similarity index 100% rename from src/test/run-make/issue-28595/b.rs rename to src/test/run-make-fulldeps/issue-28595/b.rs diff --git a/src/test/run-make/issue-28766/Makefile b/src/test/run-make-fulldeps/issue-28766/Makefile similarity index 100% rename from src/test/run-make/issue-28766/Makefile rename to src/test/run-make-fulldeps/issue-28766/Makefile diff --git a/src/test/run-make/issue-28766/foo.rs b/src/test/run-make-fulldeps/issue-28766/foo.rs similarity index 100% rename from src/test/run-make/issue-28766/foo.rs rename to src/test/run-make-fulldeps/issue-28766/foo.rs diff --git a/src/test/run-make/issue-28766/main.rs b/src/test/run-make-fulldeps/issue-28766/main.rs similarity index 100% rename from src/test/run-make/issue-28766/main.rs rename to src/test/run-make-fulldeps/issue-28766/main.rs diff --git a/src/test/run-make/issue-30063/Makefile b/src/test/run-make-fulldeps/issue-30063/Makefile similarity index 100% rename from src/test/run-make/issue-30063/Makefile rename to src/test/run-make-fulldeps/issue-30063/Makefile diff --git a/src/test/run-make/issue-30063/foo.rs b/src/test/run-make-fulldeps/issue-30063/foo.rs similarity index 100% rename from src/test/run-make/issue-30063/foo.rs rename to src/test/run-make-fulldeps/issue-30063/foo.rs diff --git a/src/test/run-make/issue-33329/Makefile b/src/test/run-make-fulldeps/issue-33329/Makefile similarity index 100% rename from src/test/run-make/issue-33329/Makefile rename to src/test/run-make-fulldeps/issue-33329/Makefile diff --git a/src/test/run-make/issue-33329/main.rs b/src/test/run-make-fulldeps/issue-33329/main.rs similarity index 100% rename from src/test/run-make/issue-33329/main.rs rename to src/test/run-make-fulldeps/issue-33329/main.rs diff --git a/src/test/run-make/issue-35164/Makefile b/src/test/run-make-fulldeps/issue-35164/Makefile similarity index 100% rename from src/test/run-make/issue-35164/Makefile rename to src/test/run-make-fulldeps/issue-35164/Makefile diff --git a/src/test/run-make/issue-35164/main.rs b/src/test/run-make-fulldeps/issue-35164/main.rs similarity index 100% rename from src/test/run-make/issue-35164/main.rs rename to src/test/run-make-fulldeps/issue-35164/main.rs diff --git a/src/test/run-make/issue-35164/submodule/mod.rs b/src/test/run-make-fulldeps/issue-35164/submodule/mod.rs similarity index 100% rename from src/test/run-make/issue-35164/submodule/mod.rs rename to src/test/run-make-fulldeps/issue-35164/submodule/mod.rs diff --git a/src/test/run-make/issue-37839/Makefile b/src/test/run-make-fulldeps/issue-37839/Makefile similarity index 100% rename from src/test/run-make/issue-37839/Makefile rename to src/test/run-make-fulldeps/issue-37839/Makefile diff --git a/src/test/run-make/issue-37839/a.rs b/src/test/run-make-fulldeps/issue-37839/a.rs similarity index 100% rename from src/test/run-make/issue-37839/a.rs rename to src/test/run-make-fulldeps/issue-37839/a.rs diff --git a/src/test/run-make/issue-37839/b.rs b/src/test/run-make-fulldeps/issue-37839/b.rs similarity index 100% rename from src/test/run-make/issue-37839/b.rs rename to src/test/run-make-fulldeps/issue-37839/b.rs diff --git a/src/test/run-make/issue-37839/c.rs b/src/test/run-make-fulldeps/issue-37839/c.rs similarity index 100% rename from src/test/run-make/issue-37839/c.rs rename to src/test/run-make-fulldeps/issue-37839/c.rs diff --git a/src/test/run-make/issue-37893/Makefile b/src/test/run-make-fulldeps/issue-37893/Makefile similarity index 100% rename from src/test/run-make/issue-37893/Makefile rename to src/test/run-make-fulldeps/issue-37893/Makefile diff --git a/src/test/run-make/issue-37893/a.rs b/src/test/run-make-fulldeps/issue-37893/a.rs similarity index 100% rename from src/test/run-make/issue-37893/a.rs rename to src/test/run-make-fulldeps/issue-37893/a.rs diff --git a/src/test/run-make/issue-37893/b.rs b/src/test/run-make-fulldeps/issue-37893/b.rs similarity index 100% rename from src/test/run-make/issue-37893/b.rs rename to src/test/run-make-fulldeps/issue-37893/b.rs diff --git a/src/test/run-make/issue-37893/c.rs b/src/test/run-make-fulldeps/issue-37893/c.rs similarity index 100% rename from src/test/run-make/issue-37893/c.rs rename to src/test/run-make-fulldeps/issue-37893/c.rs diff --git a/src/test/run-make/issue-38237/Makefile b/src/test/run-make-fulldeps/issue-38237/Makefile similarity index 100% rename from src/test/run-make/issue-38237/Makefile rename to src/test/run-make-fulldeps/issue-38237/Makefile diff --git a/src/test/run-make/issue-38237/bar.rs b/src/test/run-make-fulldeps/issue-38237/bar.rs similarity index 100% rename from src/test/run-make/issue-38237/bar.rs rename to src/test/run-make-fulldeps/issue-38237/bar.rs diff --git a/src/test/run-make/issue-38237/baz.rs b/src/test/run-make-fulldeps/issue-38237/baz.rs similarity index 100% rename from src/test/run-make/issue-38237/baz.rs rename to src/test/run-make-fulldeps/issue-38237/baz.rs diff --git a/src/test/run-make/issue-38237/foo.rs b/src/test/run-make-fulldeps/issue-38237/foo.rs similarity index 100% rename from src/test/run-make/issue-38237/foo.rs rename to src/test/run-make-fulldeps/issue-38237/foo.rs diff --git a/src/test/run-make/issue-40535/Makefile b/src/test/run-make-fulldeps/issue-40535/Makefile similarity index 100% rename from src/test/run-make/issue-40535/Makefile rename to src/test/run-make-fulldeps/issue-40535/Makefile diff --git a/src/test/run-make/issue-40535/bar.rs b/src/test/run-make-fulldeps/issue-40535/bar.rs similarity index 100% rename from src/test/run-make/issue-40535/bar.rs rename to src/test/run-make-fulldeps/issue-40535/bar.rs diff --git a/src/test/run-make/issue-40535/baz.rs b/src/test/run-make-fulldeps/issue-40535/baz.rs similarity index 100% rename from src/test/run-make/issue-40535/baz.rs rename to src/test/run-make-fulldeps/issue-40535/baz.rs diff --git a/src/test/run-make/issue-40535/foo.rs b/src/test/run-make-fulldeps/issue-40535/foo.rs similarity index 100% rename from src/test/run-make/issue-40535/foo.rs rename to src/test/run-make-fulldeps/issue-40535/foo.rs diff --git a/src/test/run-make/issue-46239/Makefile b/src/test/run-make-fulldeps/issue-46239/Makefile similarity index 100% rename from src/test/run-make/issue-46239/Makefile rename to src/test/run-make-fulldeps/issue-46239/Makefile diff --git a/src/test/run-make/issue-46239/main.rs b/src/test/run-make-fulldeps/issue-46239/main.rs similarity index 100% rename from src/test/run-make/issue-46239/main.rs rename to src/test/run-make-fulldeps/issue-46239/main.rs diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make-fulldeps/issue-7349/Makefile similarity index 100% rename from src/test/run-make/issue-7349/Makefile rename to src/test/run-make-fulldeps/issue-7349/Makefile diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make-fulldeps/issue-7349/foo.rs similarity index 100% rename from src/test/run-make/issue-7349/foo.rs rename to src/test/run-make-fulldeps/issue-7349/foo.rs diff --git a/src/test/run-make/issues-41478-43796/Makefile b/src/test/run-make-fulldeps/issues-41478-43796/Makefile similarity index 100% rename from src/test/run-make/issues-41478-43796/Makefile rename to src/test/run-make-fulldeps/issues-41478-43796/Makefile diff --git a/src/test/run-make/issues-41478-43796/a.rs b/src/test/run-make-fulldeps/issues-41478-43796/a.rs similarity index 100% rename from src/test/run-make/issues-41478-43796/a.rs rename to src/test/run-make-fulldeps/issues-41478-43796/a.rs diff --git a/src/test/run-make/libs-and-bins/Makefile b/src/test/run-make-fulldeps/libs-and-bins/Makefile similarity index 100% rename from src/test/run-make/libs-and-bins/Makefile rename to src/test/run-make-fulldeps/libs-and-bins/Makefile diff --git a/src/test/run-make/libs-and-bins/foo.rs b/src/test/run-make-fulldeps/libs-and-bins/foo.rs similarity index 100% rename from src/test/run-make/libs-and-bins/foo.rs rename to src/test/run-make-fulldeps/libs-and-bins/foo.rs diff --git a/src/test/run-make/libs-through-symlinks/Makefile b/src/test/run-make-fulldeps/libs-through-symlinks/Makefile similarity index 100% rename from src/test/run-make/libs-through-symlinks/Makefile rename to src/test/run-make-fulldeps/libs-through-symlinks/Makefile diff --git a/src/test/run-make/libs-through-symlinks/bar.rs b/src/test/run-make-fulldeps/libs-through-symlinks/bar.rs similarity index 100% rename from src/test/run-make/libs-through-symlinks/bar.rs rename to src/test/run-make-fulldeps/libs-through-symlinks/bar.rs diff --git a/src/test/run-make/libs-through-symlinks/foo.rs b/src/test/run-make-fulldeps/libs-through-symlinks/foo.rs similarity index 100% rename from src/test/run-make/libs-through-symlinks/foo.rs rename to src/test/run-make-fulldeps/libs-through-symlinks/foo.rs diff --git a/src/test/run-make/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile similarity index 100% rename from src/test/run-make/libtest-json/Makefile rename to src/test/run-make-fulldeps/libtest-json/Makefile diff --git a/src/test/run-make/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs similarity index 100% rename from src/test/run-make/libtest-json/f.rs rename to src/test/run-make-fulldeps/libtest-json/f.rs diff --git a/src/test/run-make/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json similarity index 100% rename from src/test/run-make/libtest-json/output.json rename to src/test/run-make-fulldeps/libtest-json/output.json diff --git a/src/test/run-make/libtest-json/validate_json.py b/src/test/run-make-fulldeps/libtest-json/validate_json.py similarity index 100% rename from src/test/run-make/libtest-json/validate_json.py rename to src/test/run-make-fulldeps/libtest-json/validate_json.py diff --git a/src/test/run-make/link-arg/Makefile b/src/test/run-make-fulldeps/link-arg/Makefile similarity index 100% rename from src/test/run-make/link-arg/Makefile rename to src/test/run-make-fulldeps/link-arg/Makefile diff --git a/src/test/run-make/link-arg/empty.rs b/src/test/run-make-fulldeps/link-arg/empty.rs similarity index 100% rename from src/test/run-make/link-arg/empty.rs rename to src/test/run-make-fulldeps/link-arg/empty.rs diff --git a/src/test/run-make/link-cfg/Makefile b/src/test/run-make-fulldeps/link-cfg/Makefile similarity index 100% rename from src/test/run-make/link-cfg/Makefile rename to src/test/run-make-fulldeps/link-cfg/Makefile diff --git a/src/test/run-make/link-cfg/dep-with-staticlib.rs b/src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs similarity index 100% rename from src/test/run-make/link-cfg/dep-with-staticlib.rs rename to src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs diff --git a/src/test/run-make/link-cfg/dep.rs b/src/test/run-make-fulldeps/link-cfg/dep.rs similarity index 100% rename from src/test/run-make/link-cfg/dep.rs rename to src/test/run-make-fulldeps/link-cfg/dep.rs diff --git a/src/test/run-make/link-cfg/no-deps.rs b/src/test/run-make-fulldeps/link-cfg/no-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/no-deps.rs rename to src/test/run-make-fulldeps/link-cfg/no-deps.rs diff --git a/src/test/run-make/link-cfg/return1.c b/src/test/run-make-fulldeps/link-cfg/return1.c similarity index 100% rename from src/test/run-make/link-cfg/return1.c rename to src/test/run-make-fulldeps/link-cfg/return1.c diff --git a/src/test/run-make/link-cfg/return2.c b/src/test/run-make-fulldeps/link-cfg/return2.c similarity index 100% rename from src/test/run-make/link-cfg/return2.c rename to src/test/run-make-fulldeps/link-cfg/return2.c diff --git a/src/test/run-make/link-cfg/return3.c b/src/test/run-make-fulldeps/link-cfg/return3.c similarity index 100% rename from src/test/run-make/link-cfg/return3.c rename to src/test/run-make-fulldeps/link-cfg/return3.c diff --git a/src/test/run-make/link-cfg/with-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/with-deps.rs rename to src/test/run-make-fulldeps/link-cfg/with-deps.rs diff --git a/src/test/run-make/link-cfg/with-staticlib-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/with-staticlib-deps.rs rename to src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs diff --git a/src/test/run-make/link-path-order/Makefile b/src/test/run-make-fulldeps/link-path-order/Makefile similarity index 100% rename from src/test/run-make/link-path-order/Makefile rename to src/test/run-make-fulldeps/link-path-order/Makefile diff --git a/src/test/run-make/link-path-order/correct.c b/src/test/run-make-fulldeps/link-path-order/correct.c similarity index 100% rename from src/test/run-make/link-path-order/correct.c rename to src/test/run-make-fulldeps/link-path-order/correct.c diff --git a/src/test/run-make/link-path-order/main.rs b/src/test/run-make-fulldeps/link-path-order/main.rs similarity index 100% rename from src/test/run-make/link-path-order/main.rs rename to src/test/run-make-fulldeps/link-path-order/main.rs diff --git a/src/test/run-make/link-path-order/wrong.c b/src/test/run-make-fulldeps/link-path-order/wrong.c similarity index 100% rename from src/test/run-make/link-path-order/wrong.c rename to src/test/run-make-fulldeps/link-path-order/wrong.c diff --git a/src/test/run-make/linkage-attr-on-static/Makefile b/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile similarity index 100% rename from src/test/run-make/linkage-attr-on-static/Makefile rename to src/test/run-make-fulldeps/linkage-attr-on-static/Makefile diff --git a/src/test/run-make/linkage-attr-on-static/bar.rs b/src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs similarity index 100% rename from src/test/run-make/linkage-attr-on-static/bar.rs rename to src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs diff --git a/src/test/run-make/linkage-attr-on-static/foo.c b/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c similarity index 100% rename from src/test/run-make/linkage-attr-on-static/foo.c rename to src/test/run-make-fulldeps/linkage-attr-on-static/foo.c diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile similarity index 100% rename from src/test/run-make/linker-output-non-utf8/Makefile rename to src/test/run-make-fulldeps/linker-output-non-utf8/Makefile diff --git a/src/test/run-make/linker-output-non-utf8/exec.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs similarity index 100% rename from src/test/run-make/linker-output-non-utf8/exec.rs rename to src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs diff --git a/src/test/run-make/linker-output-non-utf8/library.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/library.rs similarity index 100% rename from src/test/run-make/linker-output-non-utf8/library.rs rename to src/test/run-make-fulldeps/linker-output-non-utf8/library.rs diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make-fulldeps/llvm-pass/Makefile similarity index 100% rename from src/test/run-make/llvm-pass/Makefile rename to src/test/run-make-fulldeps/llvm-pass/Makefile diff --git a/src/test/run-make/llvm-pass/llvm-function-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc similarity index 100% rename from src/test/run-make/llvm-pass/llvm-function-pass.so.cc rename to src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc diff --git a/src/test/run-make/llvm-pass/llvm-module-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc similarity index 100% rename from src/test/run-make/llvm-pass/llvm-module-pass.so.cc rename to src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc diff --git a/src/test/run-make/llvm-pass/main.rs b/src/test/run-make-fulldeps/llvm-pass/main.rs similarity index 100% rename from src/test/run-make/llvm-pass/main.rs rename to src/test/run-make-fulldeps/llvm-pass/main.rs diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make-fulldeps/llvm-pass/plugin.rs similarity index 100% rename from src/test/run-make/llvm-pass/plugin.rs rename to src/test/run-make-fulldeps/llvm-pass/plugin.rs diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/Makefile rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs diff --git a/src/test/run-make/long-linker-command-lines/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines/Makefile similarity index 100% rename from src/test/run-make/long-linker-command-lines/Makefile rename to src/test/run-make-fulldeps/long-linker-command-lines/Makefile diff --git a/src/test/run-make/long-linker-command-lines/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs similarity index 100% rename from src/test/run-make/long-linker-command-lines/foo.rs rename to src/test/run-make-fulldeps/long-linker-command-lines/foo.rs diff --git a/src/test/run-make/longjmp-across-rust/Makefile b/src/test/run-make-fulldeps/longjmp-across-rust/Makefile similarity index 100% rename from src/test/run-make/longjmp-across-rust/Makefile rename to src/test/run-make-fulldeps/longjmp-across-rust/Makefile diff --git a/src/test/run-make/longjmp-across-rust/foo.c b/src/test/run-make-fulldeps/longjmp-across-rust/foo.c similarity index 100% rename from src/test/run-make/longjmp-across-rust/foo.c rename to src/test/run-make-fulldeps/longjmp-across-rust/foo.c diff --git a/src/test/run-make/longjmp-across-rust/main.rs b/src/test/run-make-fulldeps/longjmp-across-rust/main.rs similarity index 100% rename from src/test/run-make/longjmp-across-rust/main.rs rename to src/test/run-make-fulldeps/longjmp-across-rust/main.rs diff --git a/src/test/run-make/ls-metadata/Makefile b/src/test/run-make-fulldeps/ls-metadata/Makefile similarity index 100% rename from src/test/run-make/ls-metadata/Makefile rename to src/test/run-make-fulldeps/ls-metadata/Makefile diff --git a/src/test/run-make/ls-metadata/foo.rs b/src/test/run-make-fulldeps/ls-metadata/foo.rs similarity index 100% rename from src/test/run-make/ls-metadata/foo.rs rename to src/test/run-make-fulldeps/ls-metadata/foo.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/Makefile b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/Makefile rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile diff --git a/src/test/run-make/lto-no-link-whole-rlib/bar.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/bar.c rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c diff --git a/src/test/run-make/lto-no-link-whole-rlib/foo.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/foo.c rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib1.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/lib1.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib2.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/lib2.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/main.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/main.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs diff --git a/src/test/run-make/lto-readonly-lib/Makefile b/src/test/run-make-fulldeps/lto-readonly-lib/Makefile similarity index 100% rename from src/test/run-make/lto-readonly-lib/Makefile rename to src/test/run-make-fulldeps/lto-readonly-lib/Makefile diff --git a/src/test/run-make/lto-readonly-lib/lib.rs b/src/test/run-make-fulldeps/lto-readonly-lib/lib.rs similarity index 100% rename from src/test/run-make/lto-readonly-lib/lib.rs rename to src/test/run-make-fulldeps/lto-readonly-lib/lib.rs diff --git a/src/test/run-make/lto-readonly-lib/main.rs b/src/test/run-make-fulldeps/lto-readonly-lib/main.rs similarity index 100% rename from src/test/run-make/lto-readonly-lib/main.rs rename to src/test/run-make-fulldeps/lto-readonly-lib/main.rs diff --git a/src/test/run-make/lto-smoke-c/Makefile b/src/test/run-make-fulldeps/lto-smoke-c/Makefile similarity index 100% rename from src/test/run-make/lto-smoke-c/Makefile rename to src/test/run-make-fulldeps/lto-smoke-c/Makefile diff --git a/src/test/run-make/lto-smoke-c/bar.c b/src/test/run-make-fulldeps/lto-smoke-c/bar.c similarity index 100% rename from src/test/run-make/lto-smoke-c/bar.c rename to src/test/run-make-fulldeps/lto-smoke-c/bar.c diff --git a/src/test/run-make/lto-smoke-c/foo.rs b/src/test/run-make-fulldeps/lto-smoke-c/foo.rs similarity index 100% rename from src/test/run-make/lto-smoke-c/foo.rs rename to src/test/run-make-fulldeps/lto-smoke-c/foo.rs diff --git a/src/test/run-make/lto-smoke/Makefile b/src/test/run-make-fulldeps/lto-smoke/Makefile similarity index 100% rename from src/test/run-make/lto-smoke/Makefile rename to src/test/run-make-fulldeps/lto-smoke/Makefile diff --git a/src/test/run-make/lto-smoke/lib.rs b/src/test/run-make-fulldeps/lto-smoke/lib.rs similarity index 100% rename from src/test/run-make/lto-smoke/lib.rs rename to src/test/run-make-fulldeps/lto-smoke/lib.rs diff --git a/src/test/run-make/lto-smoke/main.rs b/src/test/run-make-fulldeps/lto-smoke/main.rs similarity index 100% rename from src/test/run-make/lto-smoke/main.rs rename to src/test/run-make-fulldeps/lto-smoke/main.rs diff --git a/src/test/run-make/manual-crate-name/Makefile b/src/test/run-make-fulldeps/manual-crate-name/Makefile similarity index 100% rename from src/test/run-make/manual-crate-name/Makefile rename to src/test/run-make-fulldeps/manual-crate-name/Makefile diff --git a/src/test/run-make/manual-crate-name/bar.rs b/src/test/run-make-fulldeps/manual-crate-name/bar.rs similarity index 100% rename from src/test/run-make/manual-crate-name/bar.rs rename to src/test/run-make-fulldeps/manual-crate-name/bar.rs diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make-fulldeps/manual-link/Makefile similarity index 100% rename from src/test/run-make/manual-link/Makefile rename to src/test/run-make-fulldeps/manual-link/Makefile diff --git a/src/test/run-make/manual-link/bar.c b/src/test/run-make-fulldeps/manual-link/bar.c similarity index 100% rename from src/test/run-make/manual-link/bar.c rename to src/test/run-make-fulldeps/manual-link/bar.c diff --git a/src/test/run-make/manual-link/foo.c b/src/test/run-make-fulldeps/manual-link/foo.c similarity index 100% rename from src/test/run-make/manual-link/foo.c rename to src/test/run-make-fulldeps/manual-link/foo.c diff --git a/src/test/run-make/manual-link/foo.rs b/src/test/run-make-fulldeps/manual-link/foo.rs similarity index 100% rename from src/test/run-make/manual-link/foo.rs rename to src/test/run-make-fulldeps/manual-link/foo.rs diff --git a/src/test/run-make/manual-link/main.rs b/src/test/run-make-fulldeps/manual-link/main.rs similarity index 100% rename from src/test/run-make/manual-link/main.rs rename to src/test/run-make-fulldeps/manual-link/main.rs diff --git a/src/test/run-make/many-crates-but-no-match/Makefile b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile similarity index 100% rename from src/test/run-make/many-crates-but-no-match/Makefile rename to src/test/run-make-fulldeps/many-crates-but-no-match/Makefile diff --git a/src/test/run-make/many-crates-but-no-match/crateA1.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA1.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateA2.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA2.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateA3.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA3.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateB.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateB.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateC.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateC.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs diff --git a/src/test/run-make/metadata-flag-frobs-symbols/Makefile b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/Makefile rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile diff --git a/src/test/run-make/metadata-flag-frobs-symbols/bar.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/bar.rs rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs diff --git a/src/test/run-make/metadata-flag-frobs-symbols/foo.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/foo.rs rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs diff --git a/src/test/run-make/min-global-align/Makefile b/src/test/run-make-fulldeps/min-global-align/Makefile similarity index 100% rename from src/test/run-make/min-global-align/Makefile rename to src/test/run-make-fulldeps/min-global-align/Makefile diff --git a/src/test/run-make/min-global-align/min_global_align.rs b/src/test/run-make-fulldeps/min-global-align/min_global_align.rs similarity index 100% rename from src/test/run-make/min-global-align/min_global_align.rs rename to src/test/run-make-fulldeps/min-global-align/min_global_align.rs diff --git a/src/test/run-make/mismatching-target-triples/Makefile b/src/test/run-make-fulldeps/mismatching-target-triples/Makefile similarity index 100% rename from src/test/run-make/mismatching-target-triples/Makefile rename to src/test/run-make-fulldeps/mismatching-target-triples/Makefile diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make-fulldeps/mismatching-target-triples/bar.rs similarity index 100% rename from src/test/run-make/mismatching-target-triples/bar.rs rename to src/test/run-make-fulldeps/mismatching-target-triples/bar.rs diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make-fulldeps/mismatching-target-triples/foo.rs similarity index 100% rename from src/test/run-make/mismatching-target-triples/foo.rs rename to src/test/run-make-fulldeps/mismatching-target-triples/foo.rs diff --git a/src/test/run-make/missing-crate-dependency/Makefile b/src/test/run-make-fulldeps/missing-crate-dependency/Makefile similarity index 100% rename from src/test/run-make/missing-crate-dependency/Makefile rename to src/test/run-make-fulldeps/missing-crate-dependency/Makefile diff --git a/src/test/run-make/missing-crate-dependency/crateA.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateA.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs diff --git a/src/test/run-make/missing-crate-dependency/crateB.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateB.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs diff --git a/src/test/run-make/missing-crate-dependency/crateC.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateC.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs diff --git a/src/test/run-make/mixing-deps/Makefile b/src/test/run-make-fulldeps/mixing-deps/Makefile similarity index 100% rename from src/test/run-make/mixing-deps/Makefile rename to src/test/run-make-fulldeps/mixing-deps/Makefile diff --git a/src/test/run-make/mixing-deps/both.rs b/src/test/run-make-fulldeps/mixing-deps/both.rs similarity index 100% rename from src/test/run-make/mixing-deps/both.rs rename to src/test/run-make-fulldeps/mixing-deps/both.rs diff --git a/src/test/run-make/mixing-deps/dylib.rs b/src/test/run-make-fulldeps/mixing-deps/dylib.rs similarity index 100% rename from src/test/run-make/mixing-deps/dylib.rs rename to src/test/run-make-fulldeps/mixing-deps/dylib.rs diff --git a/src/test/run-make/mixing-deps/prog.rs b/src/test/run-make-fulldeps/mixing-deps/prog.rs similarity index 100% rename from src/test/run-make/mixing-deps/prog.rs rename to src/test/run-make-fulldeps/mixing-deps/prog.rs diff --git a/src/test/run-make/mixing-formats/Makefile b/src/test/run-make-fulldeps/mixing-formats/Makefile similarity index 100% rename from src/test/run-make/mixing-formats/Makefile rename to src/test/run-make-fulldeps/mixing-formats/Makefile diff --git a/src/test/run-make/mixing-formats/bar1.rs b/src/test/run-make-fulldeps/mixing-formats/bar1.rs similarity index 100% rename from src/test/run-make/mixing-formats/bar1.rs rename to src/test/run-make-fulldeps/mixing-formats/bar1.rs diff --git a/src/test/run-make/mixing-formats/bar2.rs b/src/test/run-make-fulldeps/mixing-formats/bar2.rs similarity index 100% rename from src/test/run-make/mixing-formats/bar2.rs rename to src/test/run-make-fulldeps/mixing-formats/bar2.rs diff --git a/src/test/run-make/mixing-formats/baz.rs b/src/test/run-make-fulldeps/mixing-formats/baz.rs similarity index 100% rename from src/test/run-make/mixing-formats/baz.rs rename to src/test/run-make-fulldeps/mixing-formats/baz.rs diff --git a/src/test/run-make/mixing-formats/baz2.rs b/src/test/run-make-fulldeps/mixing-formats/baz2.rs similarity index 100% rename from src/test/run-make/mixing-formats/baz2.rs rename to src/test/run-make-fulldeps/mixing-formats/baz2.rs diff --git a/src/test/run-make/mixing-formats/foo.rs b/src/test/run-make-fulldeps/mixing-formats/foo.rs similarity index 100% rename from src/test/run-make/mixing-formats/foo.rs rename to src/test/run-make-fulldeps/mixing-formats/foo.rs diff --git a/src/test/run-make/mixing-libs/Makefile b/src/test/run-make-fulldeps/mixing-libs/Makefile similarity index 100% rename from src/test/run-make/mixing-libs/Makefile rename to src/test/run-make-fulldeps/mixing-libs/Makefile diff --git a/src/test/run-make/mixing-libs/dylib.rs b/src/test/run-make-fulldeps/mixing-libs/dylib.rs similarity index 100% rename from src/test/run-make/mixing-libs/dylib.rs rename to src/test/run-make-fulldeps/mixing-libs/dylib.rs diff --git a/src/test/run-make/mixing-libs/prog.rs b/src/test/run-make-fulldeps/mixing-libs/prog.rs similarity index 100% rename from src/test/run-make/mixing-libs/prog.rs rename to src/test/run-make-fulldeps/mixing-libs/prog.rs diff --git a/src/test/run-make/mixing-libs/rlib.rs b/src/test/run-make-fulldeps/mixing-libs/rlib.rs similarity index 100% rename from src/test/run-make/mixing-libs/rlib.rs rename to src/test/run-make-fulldeps/mixing-libs/rlib.rs diff --git a/src/test/run-make/msvc-opt-minsize/Makefile b/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile similarity index 100% rename from src/test/run-make/msvc-opt-minsize/Makefile rename to src/test/run-make-fulldeps/msvc-opt-minsize/Makefile diff --git a/src/test/run-make/msvc-opt-minsize/foo.rs b/src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs similarity index 100% rename from src/test/run-make/msvc-opt-minsize/foo.rs rename to src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs diff --git a/src/test/run-make/multiple-emits/Makefile b/src/test/run-make-fulldeps/multiple-emits/Makefile similarity index 100% rename from src/test/run-make/multiple-emits/Makefile rename to src/test/run-make-fulldeps/multiple-emits/Makefile diff --git a/src/test/run-make/multiple-emits/foo.rs b/src/test/run-make-fulldeps/multiple-emits/foo.rs similarity index 100% rename from src/test/run-make/multiple-emits/foo.rs rename to src/test/run-make-fulldeps/multiple-emits/foo.rs diff --git a/src/test/run-make/no-builtins-lto/Makefile b/src/test/run-make-fulldeps/no-builtins-lto/Makefile similarity index 100% rename from src/test/run-make/no-builtins-lto/Makefile rename to src/test/run-make-fulldeps/no-builtins-lto/Makefile diff --git a/src/test/run-make/no-builtins-lto/main.rs b/src/test/run-make-fulldeps/no-builtins-lto/main.rs similarity index 100% rename from src/test/run-make/no-builtins-lto/main.rs rename to src/test/run-make-fulldeps/no-builtins-lto/main.rs diff --git a/src/test/run-make/no-builtins-lto/no_builtins.rs b/src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs similarity index 100% rename from src/test/run-make/no-builtins-lto/no_builtins.rs rename to src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs diff --git a/src/test/run-make/no-duplicate-libs/Makefile b/src/test/run-make-fulldeps/no-duplicate-libs/Makefile similarity index 100% rename from src/test/run-make/no-duplicate-libs/Makefile rename to src/test/run-make-fulldeps/no-duplicate-libs/Makefile diff --git a/src/test/run-make/no-duplicate-libs/bar.c b/src/test/run-make-fulldeps/no-duplicate-libs/bar.c similarity index 100% rename from src/test/run-make/no-duplicate-libs/bar.c rename to src/test/run-make-fulldeps/no-duplicate-libs/bar.c diff --git a/src/test/run-make/no-duplicate-libs/foo.c b/src/test/run-make-fulldeps/no-duplicate-libs/foo.c similarity index 100% rename from src/test/run-make/no-duplicate-libs/foo.c rename to src/test/run-make-fulldeps/no-duplicate-libs/foo.c diff --git a/src/test/run-make/no-duplicate-libs/main.rs b/src/test/run-make-fulldeps/no-duplicate-libs/main.rs similarity index 100% rename from src/test/run-make/no-duplicate-libs/main.rs rename to src/test/run-make-fulldeps/no-duplicate-libs/main.rs diff --git a/src/test/run-make/no-integrated-as/Makefile b/src/test/run-make-fulldeps/no-integrated-as/Makefile similarity index 100% rename from src/test/run-make/no-integrated-as/Makefile rename to src/test/run-make-fulldeps/no-integrated-as/Makefile diff --git a/src/test/run-make/no-integrated-as/hello.rs b/src/test/run-make-fulldeps/no-integrated-as/hello.rs similarity index 100% rename from src/test/run-make/no-integrated-as/hello.rs rename to src/test/run-make-fulldeps/no-integrated-as/hello.rs diff --git a/src/test/run-make/no-intermediate-extras/Makefile b/src/test/run-make-fulldeps/no-intermediate-extras/Makefile similarity index 100% rename from src/test/run-make/no-intermediate-extras/Makefile rename to src/test/run-make-fulldeps/no-intermediate-extras/Makefile diff --git a/src/test/run-make/no-intermediate-extras/foo.rs b/src/test/run-make-fulldeps/no-intermediate-extras/foo.rs similarity index 100% rename from src/test/run-make/no-intermediate-extras/foo.rs rename to src/test/run-make-fulldeps/no-intermediate-extras/foo.rs diff --git a/src/test/run-make/obey-crate-type-flag/Makefile b/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile similarity index 100% rename from src/test/run-make/obey-crate-type-flag/Makefile rename to src/test/run-make-fulldeps/obey-crate-type-flag/Makefile diff --git a/src/test/run-make/obey-crate-type-flag/test.rs b/src/test/run-make-fulldeps/obey-crate-type-flag/test.rs similarity index 100% rename from src/test/run-make/obey-crate-type-flag/test.rs rename to src/test/run-make-fulldeps/obey-crate-type-flag/test.rs diff --git a/src/test/run-make/output-filename-conflicts-with-directory/Makefile b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile similarity index 100% rename from src/test/run-make/output-filename-conflicts-with-directory/Makefile rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile diff --git a/src/test/run-make/output-filename-conflicts-with-directory/foo.rs b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs similarity index 100% rename from src/test/run-make/output-filename-conflicts-with-directory/foo.rs rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/Makefile rename to src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile diff --git a/src/test/run-make/output-filename-overwrites-input/bar.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/bar.rs rename to src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/foo.rs rename to src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs diff --git a/src/test/run-make/output-type-permutations/Makefile b/src/test/run-make-fulldeps/output-type-permutations/Makefile similarity index 100% rename from src/test/run-make/output-type-permutations/Makefile rename to src/test/run-make-fulldeps/output-type-permutations/Makefile diff --git a/src/test/run-make/output-type-permutations/foo.rs b/src/test/run-make-fulldeps/output-type-permutations/foo.rs similarity index 100% rename from src/test/run-make/output-type-permutations/foo.rs rename to src/test/run-make-fulldeps/output-type-permutations/foo.rs diff --git a/src/test/run-make/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile similarity index 100% rename from src/test/run-make/output-with-hyphens/Makefile rename to src/test/run-make-fulldeps/output-with-hyphens/Makefile diff --git a/src/test/run-make/output-with-hyphens/foo-bar.rs b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs similarity index 100% rename from src/test/run-make/output-with-hyphens/foo-bar.rs rename to src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs diff --git a/src/test/run-make/prefer-dylib/Makefile b/src/test/run-make-fulldeps/prefer-dylib/Makefile similarity index 100% rename from src/test/run-make/prefer-dylib/Makefile rename to src/test/run-make-fulldeps/prefer-dylib/Makefile diff --git a/src/test/run-make/prefer-dylib/bar.rs b/src/test/run-make-fulldeps/prefer-dylib/bar.rs similarity index 100% rename from src/test/run-make/prefer-dylib/bar.rs rename to src/test/run-make-fulldeps/prefer-dylib/bar.rs diff --git a/src/test/run-make/prefer-dylib/foo.rs b/src/test/run-make-fulldeps/prefer-dylib/foo.rs similarity index 100% rename from src/test/run-make/prefer-dylib/foo.rs rename to src/test/run-make-fulldeps/prefer-dylib/foo.rs diff --git a/src/test/run-make/prefer-rlib/Makefile b/src/test/run-make-fulldeps/prefer-rlib/Makefile similarity index 100% rename from src/test/run-make/prefer-rlib/Makefile rename to src/test/run-make-fulldeps/prefer-rlib/Makefile diff --git a/src/test/run-make/prefer-rlib/bar.rs b/src/test/run-make-fulldeps/prefer-rlib/bar.rs similarity index 100% rename from src/test/run-make/prefer-rlib/bar.rs rename to src/test/run-make-fulldeps/prefer-rlib/bar.rs diff --git a/src/test/run-make/prefer-rlib/foo.rs b/src/test/run-make-fulldeps/prefer-rlib/foo.rs similarity index 100% rename from src/test/run-make/prefer-rlib/foo.rs rename to src/test/run-make-fulldeps/prefer-rlib/foo.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/Makefile b/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/Makefile rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/input.pp.rs rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/input.rs rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs diff --git a/src/test/run-make/pretty-expanded/Makefile b/src/test/run-make-fulldeps/pretty-expanded/Makefile similarity index 100% rename from src/test/run-make/pretty-expanded/Makefile rename to src/test/run-make-fulldeps/pretty-expanded/Makefile diff --git a/src/test/run-make/pretty-expanded/input.rs b/src/test/run-make-fulldeps/pretty-expanded/input.rs similarity index 100% rename from src/test/run-make/pretty-expanded/input.rs rename to src/test/run-make-fulldeps/pretty-expanded/input.rs diff --git a/src/test/run-make/pretty-print-path-suffix/Makefile b/src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/Makefile rename to src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile diff --git a/src/test/run-make/pretty-print-path-suffix/foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/foo.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp diff --git a/src/test/run-make/pretty-print-path-suffix/foo_method.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/foo_method.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp diff --git a/src/test/run-make/pretty-print-path-suffix/input.rs b/src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/input.rs rename to src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs diff --git a/src/test/run-make/pretty-print-path-suffix/nest_foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/nest_foo.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp diff --git a/src/test/run-make/pretty-print-to-file/Makefile b/src/test/run-make-fulldeps/pretty-print-to-file/Makefile similarity index 100% rename from src/test/run-make/pretty-print-to-file/Makefile rename to src/test/run-make-fulldeps/pretty-print-to-file/Makefile diff --git a/src/test/run-make/pretty-print-to-file/input.pp b/src/test/run-make-fulldeps/pretty-print-to-file/input.pp similarity index 100% rename from src/test/run-make/pretty-print-to-file/input.pp rename to src/test/run-make-fulldeps/pretty-print-to-file/input.pp diff --git a/src/test/run-make/pretty-print-to-file/input.rs b/src/test/run-make-fulldeps/pretty-print-to-file/input.rs similarity index 100% rename from src/test/run-make/pretty-print-to-file/input.rs rename to src/test/run-make-fulldeps/pretty-print-to-file/input.rs diff --git a/src/test/run-make/print-cfg/Makefile b/src/test/run-make-fulldeps/print-cfg/Makefile similarity index 100% rename from src/test/run-make/print-cfg/Makefile rename to src/test/run-make-fulldeps/print-cfg/Makefile diff --git a/src/test/run-make/print-target-list/Makefile b/src/test/run-make-fulldeps/print-target-list/Makefile similarity index 100% rename from src/test/run-make/print-target-list/Makefile rename to src/test/run-make-fulldeps/print-target-list/Makefile diff --git a/src/test/run-make/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile similarity index 100% rename from src/test/run-make/profile/Makefile rename to src/test/run-make-fulldeps/profile/Makefile diff --git a/src/test/run-make/profile/test.rs b/src/test/run-make-fulldeps/profile/test.rs similarity index 100% rename from src/test/run-make/profile/test.rs rename to src/test/run-make-fulldeps/profile/test.rs diff --git a/src/test/run-make/prune-link-args/Makefile b/src/test/run-make-fulldeps/prune-link-args/Makefile similarity index 100% rename from src/test/run-make/prune-link-args/Makefile rename to src/test/run-make-fulldeps/prune-link-args/Makefile diff --git a/src/test/run-make/prune-link-args/empty.rs b/src/test/run-make-fulldeps/prune-link-args/empty.rs similarity index 100% rename from src/test/run-make/prune-link-args/empty.rs rename to src/test/run-make-fulldeps/prune-link-args/empty.rs diff --git a/src/test/run-make/relocation-model/Makefile b/src/test/run-make-fulldeps/relocation-model/Makefile similarity index 100% rename from src/test/run-make/relocation-model/Makefile rename to src/test/run-make-fulldeps/relocation-model/Makefile diff --git a/src/test/run-make/relocation-model/foo.rs b/src/test/run-make-fulldeps/relocation-model/foo.rs similarity index 100% rename from src/test/run-make/relocation-model/foo.rs rename to src/test/run-make-fulldeps/relocation-model/foo.rs diff --git a/src/test/run-make/relro-levels/Makefile b/src/test/run-make-fulldeps/relro-levels/Makefile similarity index 100% rename from src/test/run-make/relro-levels/Makefile rename to src/test/run-make-fulldeps/relro-levels/Makefile diff --git a/src/test/run-make/relro-levels/hello.rs b/src/test/run-make-fulldeps/relro-levels/hello.rs similarity index 100% rename from src/test/run-make/relro-levels/hello.rs rename to src/test/run-make-fulldeps/relro-levels/hello.rs diff --git a/src/test/run-make/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile similarity index 100% rename from src/test/run-make/reproducible-build/Makefile rename to src/test/run-make-fulldeps/reproducible-build/Makefile diff --git a/src/test/run-make/reproducible-build/linker.rs b/src/test/run-make-fulldeps/reproducible-build/linker.rs similarity index 100% rename from src/test/run-make/reproducible-build/linker.rs rename to src/test/run-make-fulldeps/reproducible-build/linker.rs diff --git a/src/test/run-make/reproducible-build/reproducible-build-aux.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs similarity index 100% rename from src/test/run-make/reproducible-build/reproducible-build-aux.rs rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs diff --git a/src/test/run-make/reproducible-build/reproducible-build.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs similarity index 100% rename from src/test/run-make/reproducible-build/reproducible-build.rs rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs diff --git a/src/test/run-make/rlib-chain/Makefile b/src/test/run-make-fulldeps/rlib-chain/Makefile similarity index 100% rename from src/test/run-make/rlib-chain/Makefile rename to src/test/run-make-fulldeps/rlib-chain/Makefile diff --git a/src/test/run-make/rlib-chain/m1.rs b/src/test/run-make-fulldeps/rlib-chain/m1.rs similarity index 100% rename from src/test/run-make/rlib-chain/m1.rs rename to src/test/run-make-fulldeps/rlib-chain/m1.rs diff --git a/src/test/run-make/rlib-chain/m2.rs b/src/test/run-make-fulldeps/rlib-chain/m2.rs similarity index 100% rename from src/test/run-make/rlib-chain/m2.rs rename to src/test/run-make-fulldeps/rlib-chain/m2.rs diff --git a/src/test/run-make/rlib-chain/m3.rs b/src/test/run-make-fulldeps/rlib-chain/m3.rs similarity index 100% rename from src/test/run-make/rlib-chain/m3.rs rename to src/test/run-make-fulldeps/rlib-chain/m3.rs diff --git a/src/test/run-make/rlib-chain/m4.rs b/src/test/run-make-fulldeps/rlib-chain/m4.rs similarity index 100% rename from src/test/run-make/rlib-chain/m4.rs rename to src/test/run-make-fulldeps/rlib-chain/m4.rs diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/Makefile rename to src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile diff --git a/src/test/run-make/rustc-macro-dep-files/bar.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/bar.rs rename to src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs diff --git a/src/test/run-make/rustc-macro-dep-files/foo.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/foo.rs rename to src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs diff --git a/src/test/run-make/rustdoc-error-lines/Makefile b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile similarity index 100% rename from src/test/run-make/rustdoc-error-lines/Makefile rename to src/test/run-make-fulldeps/rustdoc-error-lines/Makefile diff --git a/src/test/run-make/rustdoc-error-lines/input.rs b/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs similarity index 100% rename from src/test/run-make/rustdoc-error-lines/input.rs rename to src/test/run-make-fulldeps/rustdoc-error-lines/input.rs diff --git a/src/test/run-make/rustdoc-output-path/Makefile b/src/test/run-make-fulldeps/rustdoc-output-path/Makefile similarity index 100% rename from src/test/run-make/rustdoc-output-path/Makefile rename to src/test/run-make-fulldeps/rustdoc-output-path/Makefile diff --git a/src/test/run-make/rustdoc-output-path/foo.rs b/src/test/run-make-fulldeps/rustdoc-output-path/foo.rs similarity index 100% rename from src/test/run-make/rustdoc-output-path/foo.rs rename to src/test/run-make-fulldeps/rustdoc-output-path/foo.rs diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile similarity index 100% rename from src/test/run-make/sanitizer-address/Makefile rename to src/test/run-make-fulldeps/sanitizer-address/Makefile diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs similarity index 100% rename from src/test/run-make/sanitizer-address/overflow.rs rename to src/test/run-make-fulldeps/sanitizer-address/overflow.rs diff --git a/src/test/run-make/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile diff --git a/src/test/run-make/sanitizer-cdylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs diff --git a/src/test/run-make/sanitizer-cdylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/program.rs rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs diff --git a/src/test/run-make/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile diff --git a/src/test/run-make/sanitizer-dylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs diff --git a/src/test/run-make/sanitizer-dylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/program.rs rename to src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs diff --git a/src/test/run-make/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile similarity index 100% rename from src/test/run-make/sanitizer-invalid-cratetype/Makefile rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile diff --git a/src/test/run-make/sanitizer-invalid-cratetype/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs similarity index 100% rename from src/test/run-make/sanitizer-invalid-cratetype/hello.rs rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile similarity index 100% rename from src/test/run-make/sanitizer-invalid-target/Makefile rename to src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile diff --git a/src/test/run-make/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs similarity index 100% rename from src/test/run-make/sanitizer-invalid-target/hello.rs rename to src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile similarity index 100% rename from src/test/run-make/sanitizer-leak/Makefile rename to src/test/run-make-fulldeps/sanitizer-leak/Makefile diff --git a/src/test/run-make/sanitizer-leak/leak.rs b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs similarity index 100% rename from src/test/run-make/sanitizer-leak/leak.rs rename to src/test/run-make-fulldeps/sanitizer-leak/leak.rs diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile similarity index 100% rename from src/test/run-make/sanitizer-memory/Makefile rename to src/test/run-make-fulldeps/sanitizer-memory/Makefile diff --git a/src/test/run-make/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs similarity index 100% rename from src/test/run-make/sanitizer-memory/uninit.rs rename to src/test/run-make-fulldeps/sanitizer-memory/uninit.rs diff --git a/src/test/run-make/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile diff --git a/src/test/run-make/sanitizer-staticlib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs diff --git a/src/test/run-make/sanitizer-staticlib-link/program.c b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/program.c rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c diff --git a/src/test/run-make/save-analysis-fail/Makefile b/src/test/run-make-fulldeps/save-analysis-fail/Makefile similarity index 100% rename from src/test/run-make/save-analysis-fail/Makefile rename to src/test/run-make-fulldeps/save-analysis-fail/Makefile diff --git a/src/test/run-make/save-analysis-fail/SameDir.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SameDir.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs diff --git a/src/test/run-make/save-analysis-fail/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SameDir3.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs diff --git a/src/test/run-make/save-analysis-fail/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SubDir/mod.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs diff --git a/src/test/run-make/save-analysis-fail/foo.rs b/src/test/run-make-fulldeps/save-analysis-fail/foo.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/foo.rs rename to src/test/run-make-fulldeps/save-analysis-fail/foo.rs diff --git a/src/test/run-make/save-analysis-fail/krate2.rs b/src/test/run-make-fulldeps/save-analysis-fail/krate2.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/krate2.rs rename to src/test/run-make-fulldeps/save-analysis-fail/krate2.rs diff --git a/src/test/run-make/save-analysis/Makefile b/src/test/run-make-fulldeps/save-analysis/Makefile similarity index 100% rename from src/test/run-make/save-analysis/Makefile rename to src/test/run-make-fulldeps/save-analysis/Makefile diff --git a/src/test/run-make/save-analysis/SameDir.rs b/src/test/run-make-fulldeps/save-analysis/SameDir.rs similarity index 100% rename from src/test/run-make/save-analysis/SameDir.rs rename to src/test/run-make-fulldeps/save-analysis/SameDir.rs diff --git a/src/test/run-make/save-analysis/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis/SameDir3.rs similarity index 100% rename from src/test/run-make/save-analysis/SameDir3.rs rename to src/test/run-make-fulldeps/save-analysis/SameDir3.rs diff --git a/src/test/run-make/save-analysis/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs similarity index 100% rename from src/test/run-make/save-analysis/SubDir/mod.rs rename to src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs diff --git a/src/test/run-make/save-analysis/extra-docs.md b/src/test/run-make-fulldeps/save-analysis/extra-docs.md similarity index 100% rename from src/test/run-make/save-analysis/extra-docs.md rename to src/test/run-make-fulldeps/save-analysis/extra-docs.md diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make-fulldeps/save-analysis/foo.rs similarity index 100% rename from src/test/run-make/save-analysis/foo.rs rename to src/test/run-make-fulldeps/save-analysis/foo.rs diff --git a/src/test/run-make/save-analysis/krate2.rs b/src/test/run-make-fulldeps/save-analysis/krate2.rs similarity index 100% rename from src/test/run-make/save-analysis/krate2.rs rename to src/test/run-make-fulldeps/save-analysis/krate2.rs diff --git a/src/test/run-make/sepcomp-cci-copies/Makefile b/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/Makefile rename to src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile diff --git a/src/test/run-make/sepcomp-cci-copies/cci_lib.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/cci_lib.rs rename to src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs diff --git a/src/test/run-make/sepcomp-cci-copies/foo.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/foo.rs rename to src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs diff --git a/src/test/run-make/sepcomp-inlining/Makefile b/src/test/run-make-fulldeps/sepcomp-inlining/Makefile similarity index 100% rename from src/test/run-make/sepcomp-inlining/Makefile rename to src/test/run-make-fulldeps/sepcomp-inlining/Makefile diff --git a/src/test/run-make/sepcomp-inlining/foo.rs b/src/test/run-make-fulldeps/sepcomp-inlining/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-inlining/foo.rs rename to src/test/run-make-fulldeps/sepcomp-inlining/foo.rs diff --git a/src/test/run-make/sepcomp-separate/Makefile b/src/test/run-make-fulldeps/sepcomp-separate/Makefile similarity index 100% rename from src/test/run-make/sepcomp-separate/Makefile rename to src/test/run-make-fulldeps/sepcomp-separate/Makefile diff --git a/src/test/run-make/sepcomp-separate/foo.rs b/src/test/run-make-fulldeps/sepcomp-separate/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-separate/foo.rs rename to src/test/run-make-fulldeps/sepcomp-separate/foo.rs diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make-fulldeps/simd-ffi/Makefile similarity index 100% rename from src/test/run-make/simd-ffi/Makefile rename to src/test/run-make-fulldeps/simd-ffi/Makefile diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs similarity index 100% rename from src/test/run-make/simd-ffi/simd.rs rename to src/test/run-make-fulldeps/simd-ffi/simd.rs diff --git a/src/test/run-make/simple-dylib/Makefile b/src/test/run-make-fulldeps/simple-dylib/Makefile similarity index 100% rename from src/test/run-make/simple-dylib/Makefile rename to src/test/run-make-fulldeps/simple-dylib/Makefile diff --git a/src/test/run-make/simple-dylib/bar.rs b/src/test/run-make-fulldeps/simple-dylib/bar.rs similarity index 100% rename from src/test/run-make/simple-dylib/bar.rs rename to src/test/run-make-fulldeps/simple-dylib/bar.rs diff --git a/src/test/run-make/simple-dylib/foo.rs b/src/test/run-make-fulldeps/simple-dylib/foo.rs similarity index 100% rename from src/test/run-make/simple-dylib/foo.rs rename to src/test/run-make-fulldeps/simple-dylib/foo.rs diff --git a/src/test/run-make/simple-rlib/Makefile b/src/test/run-make-fulldeps/simple-rlib/Makefile similarity index 100% rename from src/test/run-make/simple-rlib/Makefile rename to src/test/run-make-fulldeps/simple-rlib/Makefile diff --git a/src/test/run-make/simple-rlib/bar.rs b/src/test/run-make-fulldeps/simple-rlib/bar.rs similarity index 100% rename from src/test/run-make/simple-rlib/bar.rs rename to src/test/run-make-fulldeps/simple-rlib/bar.rs diff --git a/src/test/run-make/simple-rlib/foo.rs b/src/test/run-make-fulldeps/simple-rlib/foo.rs similarity index 100% rename from src/test/run-make/simple-rlib/foo.rs rename to src/test/run-make-fulldeps/simple-rlib/foo.rs diff --git a/src/test/run-make/stable-symbol-names/Makefile b/src/test/run-make-fulldeps/stable-symbol-names/Makefile similarity index 100% rename from src/test/run-make/stable-symbol-names/Makefile rename to src/test/run-make-fulldeps/stable-symbol-names/Makefile diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names1.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs similarity index 100% rename from src/test/run-make/stable-symbol-names/stable-symbol-names1.rs rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names2.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs similarity index 100% rename from src/test/run-make/stable-symbol-names/stable-symbol-names2.rs rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs diff --git a/src/test/run-make/static-dylib-by-default/Makefile b/src/test/run-make-fulldeps/static-dylib-by-default/Makefile similarity index 100% rename from src/test/run-make/static-dylib-by-default/Makefile rename to src/test/run-make-fulldeps/static-dylib-by-default/Makefile diff --git a/src/test/run-make/static-dylib-by-default/bar.rs b/src/test/run-make-fulldeps/static-dylib-by-default/bar.rs similarity index 100% rename from src/test/run-make/static-dylib-by-default/bar.rs rename to src/test/run-make-fulldeps/static-dylib-by-default/bar.rs diff --git a/src/test/run-make/static-dylib-by-default/foo.rs b/src/test/run-make-fulldeps/static-dylib-by-default/foo.rs similarity index 100% rename from src/test/run-make/static-dylib-by-default/foo.rs rename to src/test/run-make-fulldeps/static-dylib-by-default/foo.rs diff --git a/src/test/run-make/static-dylib-by-default/main.c b/src/test/run-make-fulldeps/static-dylib-by-default/main.c similarity index 100% rename from src/test/run-make/static-dylib-by-default/main.c rename to src/test/run-make-fulldeps/static-dylib-by-default/main.c diff --git a/src/test/run-make/static-nobundle/Makefile b/src/test/run-make-fulldeps/static-nobundle/Makefile similarity index 100% rename from src/test/run-make/static-nobundle/Makefile rename to src/test/run-make-fulldeps/static-nobundle/Makefile diff --git a/src/test/run-make/static-nobundle/aaa.c b/src/test/run-make-fulldeps/static-nobundle/aaa.c similarity index 100% rename from src/test/run-make/static-nobundle/aaa.c rename to src/test/run-make-fulldeps/static-nobundle/aaa.c diff --git a/src/test/run-make/static-nobundle/bbb.rs b/src/test/run-make-fulldeps/static-nobundle/bbb.rs similarity index 100% rename from src/test/run-make/static-nobundle/bbb.rs rename to src/test/run-make-fulldeps/static-nobundle/bbb.rs diff --git a/src/test/run-make/static-nobundle/ccc.rs b/src/test/run-make-fulldeps/static-nobundle/ccc.rs similarity index 100% rename from src/test/run-make/static-nobundle/ccc.rs rename to src/test/run-make-fulldeps/static-nobundle/ccc.rs diff --git a/src/test/run-make/static-nobundle/ddd.rs b/src/test/run-make-fulldeps/static-nobundle/ddd.rs similarity index 100% rename from src/test/run-make/static-nobundle/ddd.rs rename to src/test/run-make-fulldeps/static-nobundle/ddd.rs diff --git a/src/test/run-make/static-unwinding/Makefile b/src/test/run-make-fulldeps/static-unwinding/Makefile similarity index 100% rename from src/test/run-make/static-unwinding/Makefile rename to src/test/run-make-fulldeps/static-unwinding/Makefile diff --git a/src/test/run-make/static-unwinding/lib.rs b/src/test/run-make-fulldeps/static-unwinding/lib.rs similarity index 100% rename from src/test/run-make/static-unwinding/lib.rs rename to src/test/run-make-fulldeps/static-unwinding/lib.rs diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make-fulldeps/static-unwinding/main.rs similarity index 100% rename from src/test/run-make/static-unwinding/main.rs rename to src/test/run-make-fulldeps/static-unwinding/main.rs diff --git a/src/test/run-make/staticlib-blank-lib/Makefile b/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile similarity index 100% rename from src/test/run-make/staticlib-blank-lib/Makefile rename to src/test/run-make-fulldeps/staticlib-blank-lib/Makefile diff --git a/src/test/run-make/staticlib-blank-lib/foo.rs b/src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs similarity index 100% rename from src/test/run-make/staticlib-blank-lib/foo.rs rename to src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make-fulldeps/stdin-non-utf8/Makefile similarity index 100% rename from src/test/run-make/stdin-non-utf8/Makefile rename to src/test/run-make-fulldeps/stdin-non-utf8/Makefile diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make-fulldeps/stdin-non-utf8/non-utf8 similarity index 100% rename from src/test/run-make/stdin-non-utf8/non-utf8 rename to src/test/run-make-fulldeps/stdin-non-utf8/non-utf8 diff --git a/src/test/run-make/suspicious-library/Makefile b/src/test/run-make-fulldeps/suspicious-library/Makefile similarity index 100% rename from src/test/run-make/suspicious-library/Makefile rename to src/test/run-make-fulldeps/suspicious-library/Makefile diff --git a/src/test/run-make/suspicious-library/bar.rs b/src/test/run-make-fulldeps/suspicious-library/bar.rs similarity index 100% rename from src/test/run-make/suspicious-library/bar.rs rename to src/test/run-make-fulldeps/suspicious-library/bar.rs diff --git a/src/test/run-make/suspicious-library/foo.rs b/src/test/run-make-fulldeps/suspicious-library/foo.rs similarity index 100% rename from src/test/run-make/suspicious-library/foo.rs rename to src/test/run-make-fulldeps/suspicious-library/foo.rs diff --git a/src/test/run-make/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile similarity index 100% rename from src/test/run-make/symbol-visibility/Makefile rename to src/test/run-make-fulldeps/symbol-visibility/Makefile diff --git a/src/test/run-make/symbol-visibility/a_cdylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/a_cdylib.rs rename to src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs diff --git a/src/test/run-make/symbol-visibility/a_rust_dylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/a_rust_dylib.rs rename to src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs diff --git a/src/test/run-make/symbol-visibility/an_executable.rs b/src/test/run-make-fulldeps/symbol-visibility/an_executable.rs similarity index 100% rename from src/test/run-make/symbol-visibility/an_executable.rs rename to src/test/run-make-fulldeps/symbol-visibility/an_executable.rs diff --git a/src/test/run-make/symbol-visibility/an_rlib.rs b/src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/an_rlib.rs rename to src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs diff --git a/src/test/run-make/symbols-are-reasonable/Makefile b/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile similarity index 100% rename from src/test/run-make/symbols-are-reasonable/Makefile rename to src/test/run-make-fulldeps/symbols-are-reasonable/Makefile diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs similarity index 100% rename from src/test/run-make/symbols-are-reasonable/lib.rs rename to src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs diff --git a/src/test/run-make/symbols-include-type-name/Makefile b/src/test/run-make-fulldeps/symbols-include-type-name/Makefile similarity index 100% rename from src/test/run-make/symbols-include-type-name/Makefile rename to src/test/run-make-fulldeps/symbols-include-type-name/Makefile diff --git a/src/test/run-make/symbols-include-type-name/lib.rs b/src/test/run-make-fulldeps/symbols-include-type-name/lib.rs similarity index 100% rename from src/test/run-make/symbols-include-type-name/lib.rs rename to src/test/run-make-fulldeps/symbols-include-type-name/lib.rs diff --git a/src/test/run-make/symlinked-extern/Makefile b/src/test/run-make-fulldeps/symlinked-extern/Makefile similarity index 100% rename from src/test/run-make/symlinked-extern/Makefile rename to src/test/run-make-fulldeps/symlinked-extern/Makefile diff --git a/src/test/run-make/symlinked-extern/bar.rs b/src/test/run-make-fulldeps/symlinked-extern/bar.rs similarity index 100% rename from src/test/run-make/symlinked-extern/bar.rs rename to src/test/run-make-fulldeps/symlinked-extern/bar.rs diff --git a/src/test/run-make/symlinked-extern/baz.rs b/src/test/run-make-fulldeps/symlinked-extern/baz.rs similarity index 100% rename from src/test/run-make/symlinked-extern/baz.rs rename to src/test/run-make-fulldeps/symlinked-extern/baz.rs diff --git a/src/test/run-make/symlinked-extern/foo.rs b/src/test/run-make-fulldeps/symlinked-extern/foo.rs similarity index 100% rename from src/test/run-make/symlinked-extern/foo.rs rename to src/test/run-make-fulldeps/symlinked-extern/foo.rs diff --git a/src/test/run-make/symlinked-libraries/Makefile b/src/test/run-make-fulldeps/symlinked-libraries/Makefile similarity index 100% rename from src/test/run-make/symlinked-libraries/Makefile rename to src/test/run-make-fulldeps/symlinked-libraries/Makefile diff --git a/src/test/run-make/symlinked-libraries/bar.rs b/src/test/run-make-fulldeps/symlinked-libraries/bar.rs similarity index 100% rename from src/test/run-make/symlinked-libraries/bar.rs rename to src/test/run-make-fulldeps/symlinked-libraries/bar.rs diff --git a/src/test/run-make/symlinked-libraries/foo.rs b/src/test/run-make-fulldeps/symlinked-libraries/foo.rs similarity index 100% rename from src/test/run-make/symlinked-libraries/foo.rs rename to src/test/run-make-fulldeps/symlinked-libraries/foo.rs diff --git a/src/test/run-make/symlinked-rlib/Makefile b/src/test/run-make-fulldeps/symlinked-rlib/Makefile similarity index 100% rename from src/test/run-make/symlinked-rlib/Makefile rename to src/test/run-make-fulldeps/symlinked-rlib/Makefile diff --git a/src/test/run-make/symlinked-rlib/bar.rs b/src/test/run-make-fulldeps/symlinked-rlib/bar.rs similarity index 100% rename from src/test/run-make/symlinked-rlib/bar.rs rename to src/test/run-make-fulldeps/symlinked-rlib/bar.rs diff --git a/src/test/run-make/symlinked-rlib/foo.rs b/src/test/run-make-fulldeps/symlinked-rlib/foo.rs similarity index 100% rename from src/test/run-make/symlinked-rlib/foo.rs rename to src/test/run-make-fulldeps/symlinked-rlib/foo.rs diff --git a/src/test/run-make/sysroot-crates-are-unstable/Makefile b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile similarity index 100% rename from src/test/run-make/sysroot-crates-are-unstable/Makefile rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile diff --git a/src/test/run-make/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py similarity index 100% rename from src/test/run-make/sysroot-crates-are-unstable/test.py rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py diff --git a/src/test/run-make/target-cpu-native/Makefile b/src/test/run-make-fulldeps/target-cpu-native/Makefile similarity index 100% rename from src/test/run-make/target-cpu-native/Makefile rename to src/test/run-make-fulldeps/target-cpu-native/Makefile diff --git a/src/test/run-make/target-cpu-native/foo.rs b/src/test/run-make-fulldeps/target-cpu-native/foo.rs similarity index 100% rename from src/test/run-make/target-cpu-native/foo.rs rename to src/test/run-make-fulldeps/target-cpu-native/foo.rs diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make-fulldeps/target-specs/Makefile similarity index 100% rename from src/test/run-make/target-specs/Makefile rename to src/test/run-make-fulldeps/target-specs/Makefile diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make-fulldeps/target-specs/foo.rs similarity index 100% rename from src/test/run-make/target-specs/foo.rs rename to src/test/run-make-fulldeps/target-specs/foo.rs diff --git a/src/test/run-make/target-specs/my-awesome-platform.json b/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-awesome-platform.json rename to src/test/run-make-fulldeps/target-specs/my-awesome-platform.json diff --git a/src/test/run-make/target-specs/my-incomplete-platform.json b/src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-incomplete-platform.json rename to src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json diff --git a/src/test/run-make/target-specs/my-invalid-platform.json b/src/test/run-make-fulldeps/target-specs/my-invalid-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-invalid-platform.json rename to src/test/run-make-fulldeps/target-specs/my-invalid-platform.json diff --git a/src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json rename to src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json diff --git a/src/test/run-make/target-without-atomics/Makefile b/src/test/run-make-fulldeps/target-without-atomics/Makefile similarity index 100% rename from src/test/run-make/target-without-atomics/Makefile rename to src/test/run-make-fulldeps/target-without-atomics/Makefile diff --git a/src/test/run-make/test-harness/Makefile b/src/test/run-make-fulldeps/test-harness/Makefile similarity index 100% rename from src/test/run-make/test-harness/Makefile rename to src/test/run-make-fulldeps/test-harness/Makefile diff --git a/src/test/run-make/test-harness/test-ignore-cfg.rs b/src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs similarity index 100% rename from src/test/run-make/test-harness/test-ignore-cfg.rs rename to src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs diff --git a/src/test/run-make/tools.mk b/src/test/run-make-fulldeps/tools.mk similarity index 100% rename from src/test/run-make/tools.mk rename to src/test/run-make-fulldeps/tools.mk diff --git a/src/test/run-make/treat-err-as-bug/Makefile b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile similarity index 100% rename from src/test/run-make/treat-err-as-bug/Makefile rename to src/test/run-make-fulldeps/treat-err-as-bug/Makefile diff --git a/src/test/run-make/treat-err-as-bug/err.rs b/src/test/run-make-fulldeps/treat-err-as-bug/err.rs similarity index 100% rename from src/test/run-make/treat-err-as-bug/err.rs rename to src/test/run-make-fulldeps/treat-err-as-bug/err.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/Makefile rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateA.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateA.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateB.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateB.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateC.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs diff --git a/src/test/run-make/use-extern-for-plugins/Makefile b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile similarity index 100% rename from src/test/run-make/use-extern-for-plugins/Makefile rename to src/test/run-make-fulldeps/use-extern-for-plugins/Makefile diff --git a/src/test/run-make/use-extern-for-plugins/bar.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/bar.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs diff --git a/src/test/run-make/use-extern-for-plugins/baz.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/baz.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs diff --git a/src/test/run-make/use-extern-for-plugins/foo.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/foo.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs diff --git a/src/test/run-make/used/Makefile b/src/test/run-make-fulldeps/used/Makefile similarity index 100% rename from src/test/run-make/used/Makefile rename to src/test/run-make-fulldeps/used/Makefile diff --git a/src/test/run-make/used/used.rs b/src/test/run-make-fulldeps/used/used.rs similarity index 100% rename from src/test/run-make/used/used.rs rename to src/test/run-make-fulldeps/used/used.rs diff --git a/src/test/run-make/version/Makefile b/src/test/run-make-fulldeps/version/Makefile similarity index 100% rename from src/test/run-make/version/Makefile rename to src/test/run-make-fulldeps/version/Makefile diff --git a/src/test/run-make/volatile-intrinsics/Makefile b/src/test/run-make-fulldeps/volatile-intrinsics/Makefile similarity index 100% rename from src/test/run-make/volatile-intrinsics/Makefile rename to src/test/run-make-fulldeps/volatile-intrinsics/Makefile diff --git a/src/test/run-make/volatile-intrinsics/main.rs b/src/test/run-make-fulldeps/volatile-intrinsics/main.rs similarity index 100% rename from src/test/run-make/volatile-intrinsics/main.rs rename to src/test/run-make-fulldeps/volatile-intrinsics/main.rs diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make-fulldeps/weird-output-filenames/Makefile similarity index 100% rename from src/test/run-make/weird-output-filenames/Makefile rename to src/test/run-make-fulldeps/weird-output-filenames/Makefile diff --git a/src/test/run-make/weird-output-filenames/foo.rs b/src/test/run-make-fulldeps/weird-output-filenames/foo.rs similarity index 100% rename from src/test/run-make/weird-output-filenames/foo.rs rename to src/test/run-make-fulldeps/weird-output-filenames/foo.rs diff --git a/src/test/run-make/windows-spawn/Makefile b/src/test/run-make-fulldeps/windows-spawn/Makefile similarity index 100% rename from src/test/run-make/windows-spawn/Makefile rename to src/test/run-make-fulldeps/windows-spawn/Makefile diff --git a/src/test/run-make/windows-spawn/hello.rs b/src/test/run-make-fulldeps/windows-spawn/hello.rs similarity index 100% rename from src/test/run-make/windows-spawn/hello.rs rename to src/test/run-make-fulldeps/windows-spawn/hello.rs diff --git a/src/test/run-make/windows-spawn/spawn.rs b/src/test/run-make-fulldeps/windows-spawn/spawn.rs similarity index 100% rename from src/test/run-make/windows-spawn/spawn.rs rename to src/test/run-make-fulldeps/windows-spawn/spawn.rs diff --git a/src/test/run-make/windows-subsystem/Makefile b/src/test/run-make-fulldeps/windows-subsystem/Makefile similarity index 100% rename from src/test/run-make/windows-subsystem/Makefile rename to src/test/run-make-fulldeps/windows-subsystem/Makefile diff --git a/src/test/run-make/windows-subsystem/console.rs b/src/test/run-make-fulldeps/windows-subsystem/console.rs similarity index 100% rename from src/test/run-make/windows-subsystem/console.rs rename to src/test/run-make-fulldeps/windows-subsystem/console.rs diff --git a/src/test/run-make/windows-subsystem/windows.rs b/src/test/run-make-fulldeps/windows-subsystem/windows.rs similarity index 100% rename from src/test/run-make/windows-subsystem/windows.rs rename to src/test/run-make-fulldeps/windows-subsystem/windows.rs diff --git a/src/test/run-make/wasm-custom-section/Makefile b/src/test/run-make/wasm-custom-section/Makefile new file mode 100644 index 0000000000000..399951e516314 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown + $(NODE) foo.js $(TMPDIR)/bar.wasm +else +all: +endif diff --git a/src/test/run-make/wasm-custom-section/bar.rs b/src/test/run-make/wasm-custom-section/bar.rs new file mode 100644 index 0000000000000..e3db36d6dbd4c --- /dev/null +++ b/src/test/run-make/wasm-custom-section/bar.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "cdylib"] +#![feature(wasm_custom_section)] +#![deny(warnings)] + +extern crate foo; + +#[wasm_custom_section = "foo"] +const A: [u8; 2] = [5, 6]; + +#[wasm_custom_section = "baz"] +const B: [u8; 2] = [7, 8]; + +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/run-make/wasm-custom-section/foo.js b/src/test/run-make/wasm-custom-section/foo.js new file mode 100644 index 0000000000000..df69354f3a400 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/foo.js @@ -0,0 +1,46 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let sections = WebAssembly.Module.customSections(m, "baz"); +console.log('section baz', sections); +assert.strictEqual(sections.length, 1); +let section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 2); +assert.strictEqual(section[0], 7); +assert.strictEqual(section[1], 8); + +sections = WebAssembly.Module.customSections(m, "bar"); +console.log('section bar', sections); +assert.strictEqual(sections.length, 1, "didn't pick up `bar` section from dependency"); +section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 2); +assert.strictEqual(section[0], 3); +assert.strictEqual(section[1], 4); + +sections = WebAssembly.Module.customSections(m, "foo"); +console.log('section foo', sections); +assert.strictEqual(sections.length, 1, "didn't create `foo` section"); +section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections"); +assert.strictEqual(section[0], 5); +assert.strictEqual(section[1], 6); +assert.strictEqual(section[2], 1); +assert.strictEqual(section[3], 2); + +process.exit(1); diff --git a/src/test/run-make/wasm-custom-section/foo.rs b/src/test/run-make/wasm-custom-section/foo.rs new file mode 100644 index 0000000000000..44d1efd7c2d62 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/foo.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(wasm_custom_section)] +#![deny(warnings)] + +#[wasm_custom_section = "foo"] +const A: [u8; 2] = [1, 2]; + +#[wasm_custom_section = "bar"] +const B: [u8; 2] = [3, 4]; diff --git a/src/test/ui/feature-gate-wasm_custom_section.rs b/src/test/ui/feature-gate-wasm_custom_section.rs new file mode 100644 index 0000000000000..c695ef4ff068f --- /dev/null +++ b/src/test/ui/feature-gate-wasm_custom_section.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable +const A: [u8; 2] = [1, 2]; + +fn main() {} diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr new file mode 100644 index 0000000000000..5977ec9edad5f --- /dev/null +++ b/src/test/ui/feature-gate-wasm_custom_section.stderr @@ -0,0 +1,11 @@ +error[E0658]: attribute is currently unstable + --> $DIR/feature-gate-wasm_custom_section.rs:11:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(wasm_custom_section)] to the crate attributes to enable + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0658" diff --git a/src/test/ui/wasm-custom-section/malformed.rs b/src/test/ui/wasm-custom-section/malformed.rs new file mode 100644 index 0000000000000..13b1685a48072 --- /dev/null +++ b/src/test/ui/wasm-custom-section/malformed.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section] //~ ERROR: must be of the form +const A: [u8; 1] = [0]; + +#[wasm_custom_section(foo)] //~ ERROR: must be of the form +const B: [u8; 1] = [0]; + +fn main() {} diff --git a/src/test/ui/wasm-custom-section/malformed.stderr b/src/test/ui/wasm-custom-section/malformed.stderr new file mode 100644 index 0000000000000..c716c824aebda --- /dev/null +++ b/src/test/ui/wasm-custom-section/malformed.stderr @@ -0,0 +1,14 @@ +error: must be of the form #[wasm_custom_section = "foo"] + --> $DIR/malformed.rs:13:1 + | +LL | #[wasm_custom_section] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: must be of the form #[wasm_custom_section = "foo"] + --> $DIR/malformed.rs:16:1 + | +LL | #[wasm_custom_section(foo)] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/wasm-custom-section/not-const.rs b/src/test/ui/wasm-custom-section/not-const.rs new file mode 100644 index 0000000000000..68077fb2fe4ac --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-const.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +static A: [u8; 2] = [1, 2]; + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +struct B {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +enum C {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +impl B {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +mod d {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-const.stderr b/src/test/ui/wasm-custom-section/not-const.stderr new file mode 100644 index 0000000000000..17c85b3e848eb --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-const.stderr @@ -0,0 +1,38 @@ +error: only allowed on consts + --> $DIR/not-const.rs:13:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:16:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:19:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:22:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:25:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:28:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/wasm-custom-section/not-slice.rs b/src/test/ui/wasm-custom-section/not-slice.rs new file mode 100644 index 0000000000000..2d91641a5f756 --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-slice.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section = "foo"] +const A: u8 = 0; //~ ERROR: must be an array of bytes + +#[wasm_custom_section = "foo"] +const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes + +#[wasm_custom_section = "foo"] +const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes + +fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-slice.stderr b/src/test/ui/wasm-custom-section/not-slice.stderr new file mode 100644 index 0000000000000..f2563ce0dddc1 --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-slice.stderr @@ -0,0 +1,20 @@ +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:14:1 + | +LL | const A: u8 = 0; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^ + +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:17:1 + | +LL | const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:20:1 + | +LL | const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 43220af4893bb..93b1b1f08e63f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2396,13 +2396,6 @@ impl<'test> TestCx<'test> { .env("S", src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env( - "RUSTDOC", - cwd.join(&self.config - .rustdoc_path - .as_ref() - .expect("--rustdoc-path passed")), - ) .env("TMPDIR", &tmpdir) .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) @@ -2417,6 +2410,14 @@ impl<'test> TestCx<'test> { .env_remove("MFLAGS") .env_remove("CARGO_MAKEFLAGS"); + if let Some(ref rustdoc) = self.config.rustdoc_path { + cmd.env("RUSTDOC", cwd.join(rustdoc)); + } + + if let Some(ref node) = self.config.nodejs { + cmd.env("NODE", node); + } + if let Some(ref linker) = self.config.linker { cmd.env("RUSTC_LINKER", linker); } From d889957dab5ee0778f9dd64faeafc8872645efed Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 Feb 2018 14:28:17 -0800 Subject: [PATCH 218/546] rustc: Add a `#[wasm_import_module]` attribute This commit adds a new attribute to the Rust compiler specific to the wasm target (and no other targets). The `#[wasm_import_module]` attribute is used to specify the module that a name is imported from, and is used like so: #[wasm_import_module = "./foo.js"] extern { fn some_js_function(); } Here the import of the symbol `some_js_function` is tagged with the `./foo.js` module in the wasm output file. Wasm-the-format includes two fields on all imports, a module and a field. The field is the symbol name (`some_js_function` above) and the module has historically unconditionally been `"env"`. I'm not sure if this `"env"` convention has asm.js or LLVM roots, but regardless we'd like the ability to configure it! The proposed ES module integration with wasm (aka a wasm module is "just another ES module") requires that the import module of wasm imports is interpreted as an ES module import, meaning that you'll need to encode paths, NPM packages, etc. As a result, we'll need this to be something other than `"env"`! Unfortunately neither our version of LLVM nor LLD supports custom import modules (aka anything not `"env"`). My hope is that by the time LLVM 7 is released both will have support, but in the meantime this commit adds some primitive encoding/decoding of wasm files to the compiler. This way rustc postprocesses the wasm module that LLVM emits to ensure it's got all the imports we'd like to have in it. Eventually I'd ideally like to unconditionally require this attribute to be placed on all `extern { ... }` blocks. For now though it seemed prudent to add it as an unstable attribute, so for now it's not required (as that'd force usage of a feature gate). Hopefully it doesn't take too long to "stabilize" this! cc rust-lang-nursery/rust-wasm#29 --- src/ci/docker/wasm32-unknown/Dockerfile | 1 + src/librustc/dep_graph/dep_node.rs | 3 + src/librustc/hir/check_attr.rs | 43 ++- src/librustc/ich/impls_cstore.rs | 7 +- src/librustc/middle/cstore.rs | 6 + src/librustc/ty/maps/config.rs | 18 ++ src/librustc/ty/maps/mod.rs | 9 +- src/librustc/ty/maps/plumbing.rs | 5 + src/librustc_metadata/creader.rs | 20 +- src/librustc_metadata/cstore.rs | 6 +- src/librustc_metadata/cstore_impl.rs | 22 +- src/librustc_metadata/decoder.rs | 10 +- src/librustc_metadata/encoder.rs | 12 +- src/librustc_metadata/foreign_modules.rs | 48 ++++ src/librustc_metadata/lib.rs | 1 + src/librustc_metadata/native_libs.rs | 7 +- src/librustc_metadata/schema.rs | 3 +- src/librustc_trans/attributes.rs | 46 ++++ src/librustc_trans/back/link.rs | 1 + src/librustc_trans/back/wasm.rs | 249 ++++++++++++++++-- src/librustc_trans/base.rs | 52 +++- src/librustc_trans/lib.rs | 3 + src/libsyntax/feature_gate.rs | 7 + src/test/run-make/wasm-custom-section/foo.js | 2 +- src/test/run-make/wasm-import-module/Makefile | 10 + src/test/run-make/wasm-import-module/bar.rs | 29 ++ src/test/run-make/wasm-import-module/foo.js | 28 ++ src/test/run-make/wasm-import-module/foo.rs | 18 ++ .../feature-gate-wasm_custom_section.stderr | 2 +- .../ui/feature-gate-wasm_import_module.rs | 15 ++ .../ui/feature-gate-wasm_import_module.stderr | 11 + src/test/ui/wasm-import-module.rs | 20 ++ src/test/ui/wasm-import-module.stderr | 14 + 33 files changed, 653 insertions(+), 75 deletions(-) create mode 100644 src/librustc_metadata/foreign_modules.rs create mode 100644 src/test/run-make/wasm-import-module/Makefile create mode 100644 src/test/run-make/wasm-import-module/bar.rs create mode 100644 src/test/run-make/wasm-import-module/foo.js create mode 100644 src/test/run-make/wasm-import-module/foo.rs create mode 100644 src/test/ui/feature-gate-wasm_import_module.rs create mode 100644 src/test/ui/feature-gate-wasm_import_module.stderr create mode 100644 src/test/ui/wasm-import-module.rs create mode 100644 src/test/ui/wasm-import-module.stderr diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/wasm32-unknown/Dockerfile index 0972eb85191a9..6c0ec1ad9d4e1 100644 --- a/src/ci/docker/wasm32-unknown/Dockerfile +++ b/src/ci/docker/wasm32-unknown/Dockerfile @@ -26,6 +26,7 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lld ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ + src/test/run-make \ src/test/ui \ src/test/run-pass \ src/test/compile-fail \ diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 09d7ce599ab03..8bcec79d99f17 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -593,6 +593,7 @@ define_dep_nodes!( <'tcx> [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId }, [] AllTraitImplementations(CrateNum), + [] DllimportForeignItems(CrateNum), [] IsDllimportForeignItem(DefId), [] IsStaticallyIncludedForeignItem(DefId), [] NativeLibraryKind(DefId), @@ -655,6 +656,8 @@ define_dep_nodes!( <'tcx> [input] Features, [] ProgramClausesFor(DefId), + [] WasmImportModuleMap(CrateNum), + [] ForeignModules(CrateNum), ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index f141cac161483..9b2647ad4db2b 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -26,6 +26,7 @@ enum Target { Union, Enum, Const, + ForeignMod, Other, } @@ -37,6 +38,7 @@ impl Target { hir::ItemUnion(..) => Target::Union, hir::ItemEnum(..) => Target::Enum, hir::ItemConst(..) => Target::Const, + hir::ItemForeignMod(..) => Target::ForeignMod, _ => Target::Other, } } @@ -57,25 +59,42 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { .emit(); } + let mut has_wasm_import_module = false; for attr in &item.attrs { - if let Some(name) = attr.name() { - if name == "inline" { - self.check_inline(attr, item, target) + if attr.check_name("inline") { + self.check_inline(attr, item, target) + } else if attr.check_name("wasm_import_module") { + has_wasm_import_module = true; + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "\ + must be of the form #[wasm_import_module = \"...\"]"); + } + if target != Target::ForeignMod { + self.tcx.sess.span_err(attr.span, "\ + must only be attached to foreign modules"); + } + } else if attr.check_name("wasm_custom_section") { + if target != Target::Const { + self.tcx.sess.span_err(attr.span, "only allowed on consts"); } - if name == "wasm_custom_section" { - if target != Target::Const { - self.tcx.sess.span_err(attr.span, "only allowed on consts"); - } - - if attr.value_str().is_none() { - self.tcx.sess.span_err(attr.span, "must be of the form \ - #[wasm_custom_section = \"foo\"]"); - } + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "must be of the form \ + #[wasm_custom_section = \"foo\"]"); } } } + if target == Target::ForeignMod && + !has_wasm_import_module && + self.tcx.sess.target.target.arch == "wasm32" && + false // FIXME: eventually enable this warning when stable + { + self.tcx.sess.span_warn(item.span, "\ + must have a #[wasm_import_module = \"...\"] attribute, this \ + will become a hard error before too long"); + } + self.check_repr(item, target); } diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index 18a02ff5c5882..0071850e1052b 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -33,7 +33,12 @@ impl_stable_hash_for!(struct middle::cstore::NativeLibrary { kind, name, cfg, - foreign_items + foreign_module +}); + +impl_stable_hash_for!(struct middle::cstore::ForeignModule { + foreign_items, + def_id }); impl_stable_hash_for!(enum middle::cstore::LinkagePreference { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 3c451d7ae46a1..add9b621596b6 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -132,7 +132,13 @@ pub struct NativeLibrary { pub kind: NativeLibraryKind, pub name: Symbol, pub cfg: Option, + pub foreign_module: Option, +} + +#[derive(Clone, Hash, RustcEncodable, RustcDecodable)] +pub struct ForeignModule { pub foreign_items: Vec, + pub def_id: DefId, } pub enum LoadedMacro { diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 0b41c3ab2fa20..7565e90df986f 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -430,6 +430,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("looking up the foreign modules of a linked crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> { fn describe(_tcx: TyCtxt, _: CrateNum) -> String { format!("looking up the plugin registrar for a crate") @@ -705,6 +711,18 @@ impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("wasm import module map") + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("wasm import module map") + } +} + macro_rules! impl_disk_cacheable_query( ($query_name:ident, |$key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2b4c1992762ea..c16ad0d8ca140 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -18,7 +18,7 @@ use infer::canonical::{Canonical, QueryResult}; use lint; use middle::borrowck::BorrowCheckResult; use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, - ExternBodyNestedBodies}; + ExternBodyNestedBodies, ForeignModule}; use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody}; use middle::privacy::AccessLevels; use middle::reachable::ReachableSet; @@ -320,6 +320,9 @@ define_maps! { <'tcx> [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc>, + + [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc>, + [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option, [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, @@ -331,6 +334,8 @@ define_maps! { <'tcx> [] fn all_trait_implementations: AllTraitImplementations(CrateNum) -> Lrc>, + [] fn dllimport_foreign_items: DllimportForeignItems(CrateNum) + -> Lrc>, [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool, [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool, [] fn native_library_kind: NativeLibraryKind(DefId) @@ -426,6 +431,8 @@ define_maps! { <'tcx> [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc>, + [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum) + -> Lrc>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 910c00b832ef8..46106d8ec0e91 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -886,6 +886,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, force!(all_trait_implementations, krate!()); } + DepKind::DllimportForeignItems => { + force!(dllimport_foreign_items, krate!()); + } DepKind::IsDllimportForeignItem => { force!(is_dllimport_foreign_item, def_id!()); } @@ -941,6 +944,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); } + DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); } + DepKind::ForeignModules => { force!(foreign_modules, krate!()); } } true diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a0546b369a8eb..baaf57c890898 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,7 +12,6 @@ use cstore::{self, CStore, CrateSource, MetadataBlob}; use locator::{self, CratePaths}; -use native_libs::relevant_lib; use schema::CrateRoot; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; @@ -230,7 +229,7 @@ impl<'a> CrateLoader<'a> { .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) .collect(); - let mut cmeta = cstore::CrateMetadata { + let cmeta = cstore::CrateMetadata { name, extern_crate: Lock::new(None), def_path_table: Lrc::new(def_path_table), @@ -250,25 +249,8 @@ impl<'a> CrateLoader<'a> { rlib, rmeta, }, - // Initialize this with an empty set. The field is populated below - // after we were able to deserialize its contents. - dllimport_foreign_items: FxHashSet(), }; - let dllimports: FxHashSet<_> = cmeta - .root - .native_libraries - .decode((&cmeta, self.sess)) - .filter(|lib| relevant_lib(self.sess, lib) && - lib.kind == cstore::NativeLibraryKind::NativeUnknown) - .flat_map(|lib| { - assert!(lib.foreign_items.iter().all(|def_id| def_id.krate == cnum)); - lib.foreign_items.into_iter().map(|def_id| def_id.index) - }) - .collect(); - - cmeta.dllimport_foreign_items = dllimports; - let cmeta = Lrc::new(cmeta); self.cstore.set_crate_data(cnum, cmeta.clone()); (cnum, cmeta) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index bd5ad93946e3c..53986f0741005 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -20,7 +20,7 @@ use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc::session::{Session, CrateDisambiguator}; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; -use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap}; +use rustc::util::nodemap::{FxHashMap, NodeMap}; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use syntax::{ast, attr}; @@ -30,7 +30,7 @@ use syntax_pos; pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; pub use rustc::middle::cstore::NativeLibraryKind::*; -pub use rustc::middle::cstore::{CrateSource, LibSource}; +pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule}; pub use cstore_impl::{provide, provide_extern}; @@ -84,8 +84,6 @@ pub struct CrateMetadata { pub source: CrateSource, pub proc_macros: Option)>>, - // Foreign items imported from a dylib (Windows only) - pub dllimport_foreign_items: FxHashSet, } pub struct CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 3c2f984ef8b3f..e911a03bbe2b5 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -12,6 +12,7 @@ use cstore; use encoder; use link_args; use native_libs; +use foreign_modules; use schema; use rustc::ty::maps::QueryConfig; @@ -197,6 +198,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, Lrc::new(reachable_non_generics) } native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) } + foreign_modules => { Lrc::new(cdata.get_foreign_modules(tcx.sess)) } plugin_registrar_fn => { cdata.root.plugin_registrar_fn.map(|index| { DefId { krate: def_id.krate, index } @@ -224,9 +226,6 @@ provide! { <'tcx> tcx, def_id, other, cdata, Lrc::new(result) } - is_dllimport_foreign_item => { - cdata.is_dllimport_foreign_item(def_id.index) - } visibility => { cdata.get_visibility(def_id.index) } dep_kind => { let r = *cdata.dep_kind.lock(); @@ -306,13 +305,28 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { tcx.native_libraries(id.krate) .iter() .filter(|lib| native_libs::relevant_lib(&tcx.sess, lib)) - .find(|l| l.foreign_items.contains(&id)) + .find(|lib| { + let fm_id = match lib.foreign_module { + Some(id) => id, + None => return false, + }; + tcx.foreign_modules(id.krate) + .iter() + .find(|m| m.def_id == fm_id) + .expect("failed to find foreign module") + .foreign_items + .contains(&id) + }) .map(|l| l.kind) }, native_libraries: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(native_libs::collect(tcx)) }, + foreign_modules: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + Lrc::new(foreign_modules::collect(tcx)) + }, link_args: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(link_args::collect(tcx)) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0e5df3142af64..e72f9ddd82abe 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -10,7 +10,7 @@ // Decoding metadata from a single crate's metadata -use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; +use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; use schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; @@ -1031,6 +1031,10 @@ impl<'a, 'tcx> CrateMetadata { self.root.native_libraries.decode((self, sess)).collect() } + pub fn get_foreign_modules(&self, sess: &Session) -> Vec { + self.root.foreign_modules.decode((self, sess)).collect() + } + pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> { self.root .dylib_dependency_formats @@ -1103,10 +1107,6 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool { - self.dllimport_foreign_items.contains(&id) - } - pub fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 56981b8f4a1e9..39de1ec852ec4 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -14,7 +14,7 @@ use isolated_encoder::IsolatedEncoder; use schema::*; use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary, - EncodedMetadata}; + EncodedMetadata, ForeignModule}; use rustc::hir::def::CtorKind; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; use rustc::hir::map::definitions::DefPathTable; @@ -412,6 +412,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ()); let native_lib_bytes = self.position() - i; + let foreign_modules = self.tracked( + IsolatedEncoder::encode_foreign_modules, + ()); + // Encode codemap i = self.position(); let codemap = self.encode_codemap(); @@ -480,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { lang_items, lang_items_missing, native_libraries, + foreign_modules, codemap, def_path_table, impls, @@ -1337,6 +1342,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { self.lazy_seq(used_libraries.iter().cloned()) } + fn encode_foreign_modules(&mut self, _: ()) -> LazySeq { + let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE); + self.lazy_seq(foreign_modules.iter().cloned()) + } + fn encode_crate_deps(&mut self, _: ()) -> LazySeq { let crates = self.tcx.crates(); diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs new file mode 100644 index 0000000000000..c44d891b7f39a --- /dev/null +++ b/src/librustc_metadata/foreign_modules.rs @@ -0,0 +1,48 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir; +use rustc::middle::cstore::ForeignModule; +use rustc::ty::TyCtxt; + +pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { + let mut collector = Collector { + tcx, + modules: Vec::new(), + }; + tcx.hir.krate().visit_all_item_likes(&mut collector); + return collector.modules +} + +struct Collector<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + modules: Vec, +} + +impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { + fn visit_item(&mut self, it: &'tcx hir::Item) { + let fm = match it.node { + hir::ItemForeignMod(ref fm) => fm, + _ => return, + }; + + let foreign_items = fm.items.iter() + .map(|it| self.tcx.hir.local_def_id(it.id)) + .collect(); + self.modules.push(ForeignModule { + foreign_items, + def_id: self.tcx.hir.local_def_id(it.id), + }); + } + + fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem) {} + fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem) {} +} diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index f77c22bd89544..8509966744948 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -56,6 +56,7 @@ mod isolated_encoder; mod schema; mod native_libs; mod link_args; +mod foreign_modules; pub mod creader; pub mod cstore; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 2504f8dc251f9..4bb6d8fb87cf5 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -105,14 +105,11 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { } else { None }; - let foreign_items = fm.items.iter() - .map(|it| self.tcx.hir.local_def_id(it.id)) - .collect(); let lib = NativeLibrary { name: n, kind, cfg, - foreign_items, + foreign_module: Some(self.tcx.hir.local_def_id(it.id)), }; self.register_native_lib(Some(m.span), lib); } @@ -218,7 +215,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { name: Symbol::intern(new_name.unwrap_or(name)), kind: if let Some(k) = kind { k } else { cstore::NativeUnknown }, cfg: None, - foreign_items: Vec::new(), + foreign_module: None, }; self.register_native_lib(None, lib); } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 001772623e75b..9832794529701 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -15,8 +15,8 @@ use rustc::hir; use rustc::hir::def::{self, CtorKind}; use rustc::hir::def_id::{DefIndex, DefId, CrateNum}; use rustc::ich::StableHashingContext; -use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; +use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::lang_items; use rustc::mir; use rustc::session::CrateDisambiguator; @@ -200,6 +200,7 @@ pub struct CrateRoot { pub lang_items: LazySeq<(DefIndex, usize)>, pub lang_items_missing: LazySeq, pub native_libraries: LazySeq, + pub foreign_modules: LazySeq, pub codemap: LazySeq, pub def_path_table: Lazy, pub impls: LazySeq, diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 16253aa92acc7..df78ccdd2298a 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -18,6 +18,7 @@ use rustc::session::config::Sanitizer; use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::fx::FxHashMap; use llvm::{self, Attribute, ValueRef}; use llvm::AttributePlace::Function; @@ -141,6 +142,20 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { llfn, llvm::AttributePlace::Function, cstr("target-features\0"), &val); } + + // Note that currently the `wasm-import-module` doesn't do anything, but + // eventually LLVM 7 should read this and ferry the appropriate import + // module to the output file. + if cx.tcx.sess.target.target.arch == "wasm32" { + if let Some(module) = wasm_import_module(cx.tcx, id) { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + cstr("wasm-import-module\0"), + &module, + ); + } + } } fn cstr(s: &'static str) -> &CStr { @@ -170,6 +185,8 @@ pub fn provide(providers: &mut Providers) { tcx.hir.krate().visit_all_item_likes(&mut finder); Lrc::new(finder.list) }; + + provide_extern(providers); } struct WasmSectionFinder<'a, 'tcx: 'a> { @@ -192,3 +209,32 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> { fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} } + +pub fn provide_extern(providers: &mut Providers) { + providers.wasm_import_module_map = |tcx, cnum| { + let mut ret = FxHashMap(); + for lib in tcx.foreign_modules(cnum).iter() { + let attrs = tcx.get_attrs(lib.def_id); + let mut module = None; + for attr in attrs.iter().filter(|a| a.check_name("wasm_import_module")) { + module = attr.value_str(); + } + let module = match module { + Some(s) => s, + None => continue, + }; + for id in lib.foreign_items.iter() { + assert_eq!(id.krate, cnum); + ret.insert(*id, module.to_string()); + } + } + + Lrc::new(ret) + } +} + +fn wasm_import_module(tcx: TyCtxt, id: DefId) -> Option { + tcx.wasm_import_module_map(id.krate) + .get(&id) + .map(|s| CString::new(&s[..]).unwrap()) +} diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 8e8ba823b6f8d..542cdc5baad32 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -813,6 +813,7 @@ fn link_natively(sess: &Session, } if sess.opts.target_triple == "wasm32-unknown-unknown" { + wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports); wasm::add_custom_sections(&out_filename, &trans.crate_info.wasm_custom_sections); } diff --git a/src/librustc_trans/back/wasm.rs b/src/librustc_trans/back/wasm.rs index 99f1e4b7e78fe..d6d386c9fbe77 100644 --- a/src/librustc_trans/back/wasm.rs +++ b/src/librustc_trans/back/wasm.rs @@ -8,37 +8,254 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::collections::BTreeMap; use std::fs; use std::path::Path; -use std::collections::BTreeMap; +use std::str; +use rustc_data_structures::fx::FxHashMap; use serialize::leb128; +// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec +const WASM_IMPORT_SECTION_ID: u8 = 2; + +const WASM_EXTERNAL_KIND_FUNCTION: u8 = 0; +const WASM_EXTERNAL_KIND_TABLE: u8 = 1; +const WASM_EXTERNAL_KIND_MEMORY: u8 = 2; +const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3; + +/// Append all the custom sections listed in `sections` to the wasm binary +/// specified at `path`. +/// +/// LLVM 6 which we're using right now doesn't have the ability to create custom +/// sections in wasm files nor does LLD have the ability to merge these sections +/// into one larger section when linking. It's expected that this will +/// eventually get implemented, however! +/// +/// Until that time though this is a custom implementation in rustc to append +/// all sections to a wasm file to the finished product that LLD produces. +/// +/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097, +/// although after that support will need to be in LLD as well. pub fn add_custom_sections(path: &Path, sections: &BTreeMap>) { - let mut wasm = fs::read(path).expect("failed to read wasm output"); + if sections.len() == 0 { + return + } + + let wasm = fs::read(path).expect("failed to read wasm output"); // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section + let mut wasm = WasmEncoder { data: wasm }; for (section, bytes) in sections { // write the `id` identifier, 0 for a custom section - let len = wasm.len(); - leb128::write_u32_leb128(&mut wasm, len, 0); + wasm.byte(0); // figure out how long our name descriptor will be - let mut name = Vec::new(); - leb128::write_u32_leb128(&mut name, 0, section.len() as u32); - name.extend_from_slice(section.as_bytes()); + let mut name = WasmEncoder::new(); + name.str(section); + + // write the length of the payload followed by all its contents + wasm.u32((bytes.len() + name.data.len()) as u32); + wasm.data.extend_from_slice(&name.data); + wasm.data.extend_from_slice(bytes); + } + + fs::write(path, &wasm.data).expect("failed to write wasm output"); +} + +/// Rewrite the module imports are listed from in a wasm module given the field +/// name to module name mapping in `import_map`. +/// +/// LLVM 6 which we're using right now doesn't have the ability to configure the +/// module a wasm symbol is import from. Rather all imported symbols come from +/// the bland `"env"` module unconditionally. Furthermore we'd *also* need +/// support in LLD for preserving these import modules, which it unfortunately +/// currently does not. +/// +/// This function is intended as a hack for now where we manually rewrite the +/// wasm output by LLVM to have the correct import modules listed. The +/// `#[wasm_import_module]` attribute in Rust translates to the module that each +/// symbol is imported from, so here we manually go through the wasm file, +/// decode it, rewrite imports, and then rewrite the wasm module. +/// +/// Support for this was added to LLVM in +/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still +/// needs to be added (AFAIK at the time of this writing) to LLD +pub fn rewrite_imports(path: &Path, import_map: &FxHashMap) { + if import_map.len() == 0 { + return + } + + let wasm = fs::read(path).expect("failed to read wasm output"); + let mut ret = WasmEncoder::new(); + ret.data.extend(&wasm[..8]); + + // skip the 8 byte wasm/version header + for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) { + ret.byte(id); + if id == WASM_IMPORT_SECTION_ID { + info!("rewriting import section"); + let data = rewrite_import_section( + &mut WasmDecoder::new(raw), + import_map, + ); + ret.bytes(&data); + } else { + info!("carry forward section {}, {} bytes long", id, raw.len()); + ret.bytes(raw); + } + } + + fs::write(path, &ret.data).expect("failed to write wasm output"); + + fn rewrite_import_section( + wasm: &mut WasmDecoder, + import_map: &FxHashMap, + ) + -> Vec + { + let mut dst = WasmEncoder::new(); + let n = wasm.u32(); + dst.u32(n); + info!("rewriting {} imports", n); + for _ in 0..n { + rewrite_import_entry(wasm, &mut dst, import_map); + } + return dst.data + } + + fn rewrite_import_entry(wasm: &mut WasmDecoder, + dst: &mut WasmEncoder, + import_map: &FxHashMap) { + // More info about the binary format here is available at: + // https://webassembly.github.io/spec/core/binary/modules.html#import-section + // + // Note that you can also find the whole point of existence of this + // function here, where we map the `module` name to a different one if + // we've got one listed. + let module = wasm.str(); + let field = wasm.str(); + let new_module = if module == "env" { + import_map.get(field).map(|s| &**s).unwrap_or(module) + } else { + module + }; + info!("import rewrite ({} => {}) / {}", module, new_module, field); + dst.str(new_module); + dst.str(field); + let kind = wasm.byte(); + dst.byte(kind); + match kind { + WASM_EXTERNAL_KIND_FUNCTION => dst.u32(wasm.u32()), + WASM_EXTERNAL_KIND_TABLE => { + dst.byte(wasm.byte()); // element_type + dst.limits(wasm.limits()); + } + WASM_EXTERNAL_KIND_MEMORY => dst.limits(wasm.limits()), + WASM_EXTERNAL_KIND_GLOBAL => { + dst.byte(wasm.byte()); // content_type + dst.bool(wasm.bool()); // mutable + } + b => panic!("unknown kind: {}", b), + } + } +} - // write the length of the payload - let len = wasm.len(); - let total_len = bytes.len() + name.len(); - leb128::write_u32_leb128(&mut wasm, len, total_len as u32); +struct WasmSections<'a>(WasmDecoder<'a>); - // write out the name section - wasm.extend(name); +impl<'a> Iterator for WasmSections<'a> { + type Item = (u8, &'a [u8]); - // and now the payload itself - wasm.extend_from_slice(bytes); + fn next(&mut self) -> Option<(u8, &'a [u8])> { + if self.0.data.len() == 0 { + return None + } + + // see https://webassembly.github.io/spec/core/binary/modules.html#sections + let id = self.0.byte(); + let section_len = self.0.u32(); + info!("new section {} / {} bytes", id, section_len); + let section = self.0.skip(section_len as usize); + Some((id, section)) } +} + +struct WasmDecoder<'a> { + data: &'a [u8], +} - fs::write(path, &wasm).expect("failed to write wasm output"); +impl<'a> WasmDecoder<'a> { + fn new(data: &'a [u8]) -> WasmDecoder<'a> { + WasmDecoder { data } + } + + fn byte(&mut self) -> u8 { + self.skip(1)[0] + } + + fn u32(&mut self) -> u32 { + let (n, l1) = leb128::read_u32_leb128(self.data); + self.data = &self.data[l1..]; + return n + } + + fn skip(&mut self, amt: usize) -> &'a [u8] { + let (data, rest) = self.data.split_at(amt); + self.data = rest; + data + } + + fn str(&mut self) -> &'a str { + let len = self.u32(); + str::from_utf8(self.skip(len as usize)).unwrap() + } + + fn bool(&mut self) -> bool { + self.byte() == 1 + } + + fn limits(&mut self) -> (u32, Option) { + let has_max = self.bool(); + (self.u32(), if has_max { Some(self.u32()) } else { None }) + } +} + +struct WasmEncoder { + data: Vec, +} + +impl WasmEncoder { + fn new() -> WasmEncoder { + WasmEncoder { data: Vec::new() } + } + + fn u32(&mut self, val: u32) { + let at = self.data.len(); + leb128::write_u32_leb128(&mut self.data, at, val); + } + + fn byte(&mut self, val: u8) { + self.data.push(val); + } + + fn bytes(&mut self, val: &[u8]) { + self.u32(val.len() as u32); + self.data.extend_from_slice(val); + } + + fn str(&mut self, val: &str) { + self.bytes(val.as_bytes()) + } + + fn bool(&mut self, b: bool) { + self.byte(b as u8); + } + + fn limits(&mut self, limits: (u32, Option)) { + self.bool(limits.1.is_some()); + self.u32(limits.0); + if let Some(c) = limits.1 { + self.u32(c); + } + } } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 11f952bc5bc77..56eece9f31e7e 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -72,6 +72,7 @@ use type_::Type; use type_of::LayoutLlvmExt; use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; +use rustc_data_structures::sync::Lrc; use std::any::Any; use std::collections::BTreeMap; @@ -1072,14 +1073,15 @@ impl CrateInfo { used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), used_crate_source: FxHashMap(), wasm_custom_sections: BTreeMap::new(), + wasm_imports: FxHashMap(), }; - let load_wasm_sections = tcx.sess.crate_types.borrow() + let load_wasm_items = tcx.sess.crate_types.borrow() .iter() .any(|c| *c != config::CrateTypeRlib) && tcx.sess.opts.target_triple == "wasm32-unknown-unknown"; - if load_wasm_sections { + if load_wasm_items { info!("attempting to load all wasm sections"); for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() { let (name, contents) = fetch_wasm_section(tcx, id); @@ -1087,6 +1089,7 @@ impl CrateInfo { .or_insert(Vec::new()) .extend(contents); } + info.load_wasm_imports(tcx, LOCAL_CRATE); } for &cnum in tcx.crates().iter() { @@ -1108,19 +1111,27 @@ impl CrateInfo { if tcx.is_no_builtins(cnum) { info.is_no_builtins.insert(cnum); } - if load_wasm_sections { + if load_wasm_items { for &id in tcx.wasm_custom_sections(cnum).iter() { let (name, contents) = fetch_wasm_section(tcx, id); info.wasm_custom_sections.entry(name) .or_insert(Vec::new()) .extend(contents); } + info.load_wasm_imports(tcx, cnum); } } - return info } + + fn load_wasm_imports(&mut self, tcx: TyCtxt, cnum: CrateNum) { + for (&id, module) in tcx.wasm_import_module_map(cnum).iter() { + let instance = Instance::mono(tcx, id); + let import_name = tcx.symbol_name(instance); + self.wasm_imports.insert(import_name.to_string(), module.clone()); + } + } } fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool { @@ -1248,6 +1259,39 @@ pub fn provide(providers: &mut Providers) { .expect(&format!("failed to find cgu with name {:?}", name)) }; providers.compile_codegen_unit = compile_codegen_unit; + + provide_extern(providers); +} + +pub fn provide_extern(providers: &mut Providers) { + providers.dllimport_foreign_items = |tcx, krate| { + let module_map = tcx.foreign_modules(krate); + let module_map = module_map.iter() + .map(|lib| (lib.def_id, lib)) + .collect::>(); + + let dllimports = tcx.native_libraries(krate) + .iter() + .filter(|lib| { + if lib.kind != cstore::NativeLibraryKind::NativeUnknown { + return false + } + let cfg = match lib.cfg { + Some(ref cfg) => cfg, + None => return true, + }; + attr::cfg_matches(cfg, &tcx.sess.parse_sess, None) + }) + .filter_map(|lib| lib.foreign_module) + .map(|id| &module_map[&id]) + .flat_map(|module| module.foreign_items.iter().cloned()) + .collect(); + Lrc::new(dllimports) + }; + + providers.is_dllimport_foreign_item = |tcx, def_id| { + tcx.dllimport_foreign_items(def_id.krate).contains(&def_id) + }; } pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bb2aeca374882..9f654c8ab29c0 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -216,6 +216,8 @@ impl TransCrate for LlvmTransCrate { fn provide_extern(&self, providers: &mut ty::maps::Providers) { back::symbol_export::provide_extern(providers); + base::provide_extern(providers); + attributes::provide_extern(providers); } fn trans_crate<'a, 'tcx>( @@ -403,6 +405,7 @@ struct CrateInfo { used_crates_static: Vec<(CrateNum, LibSource)>, used_crates_dynamic: Vec<(CrateNum, LibSource)>, wasm_custom_sections: BTreeMap>, + wasm_imports: FxHashMap, } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index dbcfee208ca2d..270cee26948e3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -454,6 +454,9 @@ declare_features! ( // The #[wasm_custom_section] attribute (active, wasm_custom_section, "1.26.0", None, None), + + // The #![wasm_import_module] attribute + (active, wasm_import_module, "1.26.0", None, None), ); declare_features! ( @@ -920,6 +923,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "the `#[no_debug]` attribute was an experimental feature that has been \ deprecated due to lack of demand", cfg_fn!(no_debug))), + ("wasm_import_module", Normal, Gated(Stability::Unstable, + "wasm_import_module", + "experimental attribute", + cfg_fn!(wasm_import_module))), ("omit_gdb_pretty_printer_section", Whitelisted, Gated(Stability::Unstable, "omit_gdb_pretty_printer_section", "the `#[omit_gdb_pretty_printer_section]` \ diff --git a/src/test/run-make/wasm-custom-section/foo.js b/src/test/run-make/wasm-custom-section/foo.js index df69354f3a400..e7a4cfc344efb 100644 --- a/src/test/run-make/wasm-custom-section/foo.js +++ b/src/test/run-make/wasm-custom-section/foo.js @@ -43,4 +43,4 @@ assert.strictEqual(section[1], 6); assert.strictEqual(section[2], 1); assert.strictEqual(section[3], 2); -process.exit(1); +process.exit(0); diff --git a/src/test/run-make/wasm-import-module/Makefile b/src/test/run-make/wasm-import-module/Makefile new file mode 100644 index 0000000000000..399951e516314 --- /dev/null +++ b/src/test/run-make/wasm-import-module/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown + $(NODE) foo.js $(TMPDIR)/bar.wasm +else +all: +endif diff --git a/src/test/run-make/wasm-import-module/bar.rs b/src/test/run-make/wasm-import-module/bar.rs new file mode 100644 index 0000000000000..9e659223c651c --- /dev/null +++ b/src/test/run-make/wasm-import-module/bar.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "cdylib"] +#![feature(wasm_import_module)] +#![deny(warnings)] + +extern crate foo; + +#[wasm_import_module = "./me"] +extern { + #[link_name = "me_in_dep"] + fn dep(); +} + +#[no_mangle] +pub extern fn foo() { + unsafe { + foo::dep(); + dep(); + } +} diff --git a/src/test/run-make/wasm-import-module/foo.js b/src/test/run-make/wasm-import-module/foo.js new file mode 100644 index 0000000000000..369962e55b1eb --- /dev/null +++ b/src/test/run-make/wasm-import-module/foo.js @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let imports = WebAssembly.Module.imports(m); +console.log('imports', imports); +assert.strictEqual(imports.length, 2); + +assert.strictEqual(imports[0].kind, 'function'); +assert.strictEqual(imports[1].kind, 'function'); + +let modules = [imports[0].module, imports[1].module]; +modules.sort(); + +assert.strictEqual(modules[0], './dep'); +assert.strictEqual(modules[1], './me'); diff --git a/src/test/run-make/wasm-import-module/foo.rs b/src/test/run-make/wasm-import-module/foo.rs new file mode 100644 index 0000000000000..bcd2ca70befaa --- /dev/null +++ b/src/test/run-make/wasm-import-module/foo.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(wasm_import_module)] +#![deny(warnings)] + +#[wasm_import_module = "./dep"] +extern { + pub fn dep(); +} diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr index 5977ec9edad5f..1b4415539f449 100644 --- a/src/test/ui/feature-gate-wasm_custom_section.stderr +++ b/src/test/ui/feature-gate-wasm_custom_section.stderr @@ -8,4 +8,4 @@ LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-wasm_import_module.rs b/src/test/ui/feature-gate-wasm_import_module.rs new file mode 100644 index 0000000000000..c5898a9c12697 --- /dev/null +++ b/src/test/ui/feature-gate-wasm_import_module.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[wasm_import_module = "test"] //~ ERROR: experimental +extern { +} + +fn main() {} diff --git a/src/test/ui/feature-gate-wasm_import_module.stderr b/src/test/ui/feature-gate-wasm_import_module.stderr new file mode 100644 index 0000000000000..bae5fa9d5956c --- /dev/null +++ b/src/test/ui/feature-gate-wasm_import_module.stderr @@ -0,0 +1,11 @@ +error[E0658]: experimental attribute + --> $DIR/feature-gate-wasm_import_module.rs:11:1 + | +LL | #[wasm_import_module = "test"] //~ ERROR: experimental + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(wasm_import_module)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/wasm-import-module.rs b/src/test/ui/wasm-import-module.rs new file mode 100644 index 0000000000000..0b743d9e486b6 --- /dev/null +++ b/src/test/ui/wasm-import-module.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_import_module)] + +#[wasm_import_module] //~ ERROR: must be of the form +extern {} + +#[wasm_import_module = "foo"] //~ ERROR: must only be attached to +fn foo() {} + +fn main() {} + diff --git a/src/test/ui/wasm-import-module.stderr b/src/test/ui/wasm-import-module.stderr new file mode 100644 index 0000000000000..bf301ce5269a7 --- /dev/null +++ b/src/test/ui/wasm-import-module.stderr @@ -0,0 +1,14 @@ +error: must be of the form #[wasm_import_module = "..."] + --> $DIR/wasm-import-module.rs:13:1 + | +LL | #[wasm_import_module] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^ + +error: must only be attached to foreign modules + --> $DIR/wasm-import-module.rs:16:1 + | +LL | #[wasm_import_module = "foo"] //~ ERROR: must only be attached to + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 73fa6d52ed99651940267affa941a1069cc20f35 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 20:49:05 +0000 Subject: [PATCH 219/546] Remove std/test documentation from compiler docs. --- src/bootstrap/dist.rs | 4 ++-- src/bootstrap/doc.rs | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e25a7e1852586..5563b153f5aff 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -163,7 +163,7 @@ impl Step for RustcDocs { let image = tmpdir(build).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); - let dst = image.join("share/doc/rustc/html"); + let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); let src = build.compiler_doc_out(host); cp_r(&src, &dst); @@ -179,7 +179,7 @@ impl Step for RustcDocs { .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rustc/html"); + .arg("--bulk-dirs=share/doc/rust/html"); build.run(&mut cmd); t!(fs::remove_dir_all(&image)); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index e525bdb98fc0c..44073a5b07572 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -690,17 +690,10 @@ impl Step for Rustc { builder.ensure(compile::Rustc { compiler, target }); let out_dir = build.stage_out(compiler, Mode::Librustc) .join(target).join("doc"); - - // See docs in std above for why we symlink - // - // This step must happen after other documentation steps. This - // invariant ensures that compiler documentation is not included - // in the standard documentation tarballs but that all the - // documentation from the standard documentation tarballs is included - // in the compiler documentation tarball. - let my_out = build.crate_doc_out(target); - build.clear_if_dirty(&my_out, &rustdoc); - t!(symlink_dir_force(&my_out, &out_dir)); + // We do not symlink to the same shared folder that already contains std library + // documentation from previous steps as we do not want to include that. + build.clear_if_dirty(&out, &rustdoc); + t!(symlink_dir_force(&out, &out_dir)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); @@ -720,7 +713,6 @@ impl Step for Rustc { } build.run(&mut cargo); - cp_r(&my_out, &out); } } From 1b26be575020c26b400b918342ac5c0c9ec76c58 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 04:24:27 -0400 Subject: [PATCH 220/546] rustfmt lowering.rs --- src/librustc/hir/lowering.rs | 2207 +++++++++++++++++++--------------- 1 file changed, 1249 insertions(+), 958 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f6bdfde15fc5f..f86e003f3630f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -43,8 +43,8 @@ use dep_graph::DepGraph; use hir; use hir::HirVec; -use hir::map::{Definitions, DefKey, DefPathData}; -use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace}; +use hir::map::{DefKey, DefPathData, Definitions}; +use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; use hir::def::{Def, PathResolution}; use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES}; use middle::cstore::CrateStore; @@ -63,10 +63,10 @@ use syntax::errors; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind}; +use syntax::codemap::{self, respan, CompilerDesugaringKind, Spanned}; use syntax::std_inject; -use syntax::symbol::{Symbol, keywords}; -use syntax::tokenstream::{TokenStream, TokenTree, Delimited}; +use syntax::symbol::{keywords, Symbol}; +use syntax::tokenstream::{Delimited, TokenStream, TokenTree}; use syntax::parse::token::Token; use syntax::util::small_vector::SmallVector; use syntax::visit::{self, Visitor}; @@ -80,13 +80,13 @@ pub struct LoweringContext<'a> { // Use to assign ids to hir nodes that do not directly correspond to an ast node sess: &'a Session, - cstore: &'a dyn CrateStore, + cstore: &'a CrateStore, // As we walk the AST we must keep track of the current 'parent' def id (in // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. parent_def: Option, - resolver: &'a mut dyn Resolver, + resolver: &'a mut Resolver, name_map: FxHashMap, /// The items being lowered are collected here. @@ -154,8 +154,13 @@ pub trait Resolver { /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves /// it based on `is_value`. - fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>, - components: &[&str], is_value: bool) -> hir::Path; + fn resolve_str_path( + &mut self, + span: Span, + crate_root: Option<&str>, + components: &[&str], + is_value: bool, + ) -> hir::Path; } #[derive(Clone, Copy, Debug)] @@ -176,12 +181,13 @@ enum ImplTraitContext { Disallowed, } -pub fn lower_crate(sess: &Session, - cstore: &dyn CrateStore, - dep_graph: &DepGraph, - krate: &Crate, - resolver: &mut dyn Resolver) - -> hir::Crate { +pub fn lower_crate( + sess: &Session, + cstore: &CrateStore, + dep_graph: &DepGraph, + krate: &Crate, + resolver: &mut Resolver, +) -> hir::Crate { // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to // incr. comp. yet. @@ -222,7 +228,7 @@ enum ParamMode { /// Any path in a type context. Explicit, /// The `module::Type` in `module::Type::method` in an expression. - Optional + Optional, } struct LoweredNodeId { @@ -252,13 +258,15 @@ impl<'a> LoweringContext<'a> { self.lctx.allocate_hir_id_counter(item.id, item); match item.node { - ItemKind::Struct(_, ref generics) | - ItemKind::Union(_, ref generics) | - ItemKind::Enum(_, ref generics) | - ItemKind::Ty(_, ref generics) | - ItemKind::Trait(_, _, ref generics, ..) => { + ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) + | ItemKind::Enum(_, ref generics) + | ItemKind::Ty(_, ref generics) + | ItemKind::Trait(_, _, ref generics, ..) => { let def_id = self.lctx.resolver.definitions().local_def_id(item.id); - let count = generics.params.iter() + let count = generics + .params + .iter() .filter(|param| param.is_lifetime_param()) .count(); self.lctx.type_def_lifetime_params.insert(def_id, count); @@ -285,7 +293,8 @@ impl<'a> LoweringContext<'a> { impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> { fn with_trait_impl_ref(&mut self, trait_impl_ref: &Option, f: F) - where F: FnOnce(&mut Self) + where + F: FnOnce(&mut Self), { let old = self.lctx.is_in_trait_impl; self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { @@ -311,22 +320,24 @@ impl<'a> LoweringContext<'a> { if item_lowered { let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node { - hir::Item_::ItemImpl(_,_,_,ref generics,..) | - hir::Item_::ItemTrait(_,_,ref generics,..) => - generics.lifetimes().cloned().collect::>(), + hir::Item_::ItemImpl(_, _, _, ref generics, ..) + | hir::Item_::ItemTrait(_, _, ref generics, ..) => { + generics.lifetimes().cloned().collect::>() + } _ => Vec::new(), }; - 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); - } - }); + 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); + } + }); } } @@ -379,27 +390,26 @@ impl<'a> LoweringContext<'a> { } } - fn allocate_hir_id_counter(&mut self, - owner: NodeId, - debug: &T) { + fn allocate_hir_id_counter(&mut self, owner: NodeId, debug: &T) { if self.item_local_id_counters.insert(owner, 0).is_some() { - bug!("Tried to allocate item_local_id_counter for {:?} twice", debug); + bug!( + "Tried to allocate item_local_id_counter for {:?} twice", + debug + ); } // Always allocate the first HirId for the owner itself self.lower_node_id_with_owner(owner, owner); } - fn lower_node_id_generic(&mut self, - ast_node_id: NodeId, - alloc_hir_id: F) - -> LoweredNodeId - where F: FnOnce(&mut Self) -> hir::HirId + fn lower_node_id_generic(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId + where + F: FnOnce(&mut Self) -> hir::HirId, { if ast_node_id == DUMMY_NODE_ID { return LoweredNodeId { node_id: DUMMY_NODE_ID, hir_id: hir::DUMMY_HIR_ID, - } + }; } let min_size = ast_node_id.as_usize() + 1; @@ -427,11 +437,12 @@ impl<'a> LoweringContext<'a> { } fn with_hir_id_owner(&mut self, owner: NodeId, f: F) - where F: FnOnce(&mut Self) + where + F: FnOnce(&mut Self), { let counter = self.item_local_id_counters - .insert(owner, HIR_ID_COUNTER_LOCKED) - .unwrap(); + .insert(owner, HIR_ID_COUNTER_LOCKED) + .unwrap(); let def_index = self.resolver.definitions().opt_def_index(owner).unwrap(); self.current_hir_id_owner.push((def_index, counter)); f(self); @@ -440,7 +451,9 @@ impl<'a> LoweringContext<'a> { debug_assert!(def_index == new_def_index); debug_assert!(new_counter >= counter); - let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap(); + let prev = self.item_local_id_counters + .insert(owner, new_counter) + .unwrap(); debug_assert!(prev == HIR_ID_COUNTER_LOCKED); } @@ -452,9 +465,8 @@ impl<'a> LoweringContext<'a> { /// properly. Calling the method twice with the same NodeId is fine though. fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId { self.lower_node_id_generic(ast_node_id, |this| { - let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner - .last_mut() - .unwrap(); + let &mut (def_index, ref mut local_id_counter) = + this.current_hir_id_owner.last_mut().unwrap(); let local_id = *local_id_counter; *local_id_counter += 1; hir::HirId { @@ -464,14 +476,9 @@ impl<'a> LoweringContext<'a> { }) } - fn lower_node_id_with_owner(&mut self, - ast_node_id: NodeId, - owner: NodeId) - -> LoweredNodeId { + fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId { self.lower_node_id_generic(ast_node_id, |this| { - let local_id_counter = this.item_local_id_counters - .get_mut(&owner) - .unwrap(); + let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap(); let local_id = *local_id_counter; // We want to be sure not to modify the counter in the map while it @@ -489,8 +496,7 @@ impl<'a> LoweringContext<'a> { }) } - fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) - -> hir::BodyId { + fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId { let body = hir::Body { arguments: decl.map_or(hir_vec![], |decl| { decl.inputs.iter().map(|x| self.lower_arg(x)).collect() @@ -524,8 +530,7 @@ impl<'a> LoweringContext<'a> { Symbol::gensym(s) } - fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span - { + fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(codemap::ExpnInfo { call_site: span, @@ -545,8 +550,10 @@ impl<'a> LoweringContext<'a> { fn collect_in_band_defs( &mut self, parent_id: Option, - f: F - ) -> (Vec, T) where F: FnOnce(&mut LoweringContext) -> T + f: F, + ) -> (Vec, T) + where + F: FnOnce(&mut LoweringContext) -> T, { assert!(!self.is_collecting_in_band_lifetimes); assert!(self.lifetimes_to_define.is_empty()); @@ -562,7 +569,9 @@ impl<'a> LoweringContext<'a> { let lifetimes_to_define = self.lifetimes_to_define.split_off(0); let mut params = match parent_id { - Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| { + 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 @@ -572,7 +581,7 @@ impl<'a> LoweringContext<'a> { DefPathData::LifetimeDef(name.as_str()), DefIndexAddressSpace::High, Mark::root(), - span + span, ); hir::GenericParam::Lifetime(hir::LifetimeDef { @@ -585,11 +594,16 @@ impl<'a> LoweringContext<'a> { pure_wrt_drop: false, in_band: true, }) - }).collect(), + }) + .collect(), None => Vec::new(), }; - params.extend(in_band_ty_params.into_iter().map(|tp| hir::GenericParam::Type(tp))); + params.extend( + in_band_ty_params + .into_iter() + .map(|tp| hir::GenericParam::Type(tp)), + ); (params, res) } @@ -598,11 +612,9 @@ impl<'a> LoweringContext<'a> { // 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( - &mut self, - lt_defs: &[LifetimeDef], - f: F - ) -> T where F: FnOnce(&mut LoweringContext) -> T + fn with_in_scope_lifetime_defs(&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); @@ -619,11 +631,9 @@ impl<'a> LoweringContext<'a> { // 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( - &mut self, - lt_defs: &[hir::LifetimeDef], - f: F - ) -> T where F: FnOnce(&mut LoweringContext) -> T + fn with_parent_impl_lifetime_defs(&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()); @@ -641,41 +651,50 @@ impl<'a> LoweringContext<'a> { &mut self, generics: &Generics, parent_id: Option, - f: F + f: F, ) -> (hir::Generics, T) - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { - let (in_band_defs, (mut lowered_generics, res)) = - self.with_in_scope_lifetime_defs( - &generics.params - .iter() - .filter_map(|p| match *p { - GenericParam::Lifetime(ref ld) => Some(ld.clone()), - _ => None, - }) - .collect::>(), - |this| { - this.collect_in_band_defs(parent_id, |this| { - (this.lower_generics(generics), f(this)) - }) - } - ); + let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs( + &generics + .params + .iter() + .filter_map(|p| match *p { + GenericParam::Lifetime(ref ld) => Some(ld.clone()), + _ => None, + }) + .collect::>(), + |this| { + this.collect_in_band_defs(parent_id, |this| { + (this.lower_generics(generics), f(this)) + }) + }, + ); - lowered_generics.params = - lowered_generics.params.iter().cloned().chain(in_band_defs).collect(); + lowered_generics.params = lowered_generics + .params + .iter() + .cloned() + .chain(in_band_defs) + .collect(); (lowered_generics, res) } fn with_catch_scope(&mut self, catch_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let len = self.catch_scopes.len(); self.catch_scopes.push(catch_id); let result = f(self); - assert_eq!(len + 1, self.catch_scopes.len(), - "catch scopes should be added and removed in stack order"); + assert_eq!( + len + 1, + self.catch_scopes.len(), + "catch scopes should be added and removed in stack order" + ); self.catch_scopes.pop().unwrap(); @@ -683,17 +702,19 @@ impl<'a> LoweringContext<'a> { } fn lower_body(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId - where F: FnOnce(&mut LoweringContext) -> hir::Expr + where + F: FnOnce(&mut LoweringContext) -> hir::Expr, { let prev = mem::replace(&mut self.is_generator, false); let result = f(self); let r = self.record_body(result, decl); self.is_generator = prev; - return r + return r; } fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { // We're no longer in the base loop's condition; we're in another loop. let was_in_loop_condition = self.is_in_loop_condition; @@ -703,8 +724,11 @@ impl<'a> LoweringContext<'a> { self.loop_scopes.push(loop_id); let result = f(self); - assert_eq!(len + 1, self.loop_scopes.len(), - "Loop scopes should be added and removed in stack order"); + assert_eq!( + len + 1, + self.loop_scopes.len(), + "Loop scopes should be added and removed in stack order" + ); self.loop_scopes.pop().unwrap(); @@ -714,7 +738,8 @@ impl<'a> LoweringContext<'a> { } fn with_loop_condition_scope(&mut self, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = true; @@ -727,7 +752,8 @@ impl<'a> LoweringContext<'a> { } fn with_new_scopes(&mut self, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; @@ -744,7 +770,8 @@ impl<'a> LoweringContext<'a> { } fn with_parent_def(&mut self, parent_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let old_def = self.parent_def; self.parent_def = { @@ -771,16 +798,19 @@ impl<'a> LoweringContext<'a> { if ident.ctxt == SyntaxContext::empty() { return ident.name; } - *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident)) + *self.name_map + .entry(ident) + .or_insert_with(|| Symbol::from_ident(ident)) } fn lower_label(&mut self, label: Option