From 5eafae22ceb0e4fae835a5eb7518a55e75061e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 7 Dec 2018 16:18:38 +0200 Subject: [PATCH 01/28] Remove confusing comment about ideally using `!` for `c_void` Using `!` for `c_void` would have the problem that pointers and potentially references to an uninhabited type would be created, and at least for references this is UB. Also document in addition that newtype wrappers around `c_void` are not recommended for representing opaque types (as a workaround for `extern type` not being stable) but instead refer to the Nomicon. --- src/libcore/ffi.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index d7a112eb90df8..02e92af853452 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -13,11 +13,12 @@ use ::fmt; /// and `*mut c_void` is equivalent to C's `void*`. That said, this is /// *not* the same as C's `void` return type, which is Rust's `()` type. /// -/// Ideally, this type would be equivalent to [`!`], but currently it may -/// be more ideal to use `c_void` for FFI purposes. +/// To model pointers to opaque types in FFI, until `extern type` is +/// stabilized, it is recommended to use a newtype wrapper around an empty +/// byte array. See the [Nomicon] for details. /// -/// [`!`]: ../../std/primitive.never.html /// [pointer]: ../../std/primitive.pointer.html +/// [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs // N.B., for LLVM to recognize the void pointer type and by extension // functions like malloc(), we need to have it represented as i8* in // LLVM bitcode. The enum used here ensures this and prevents misuse From 8de8880b7b74cb0294c6d8c75c24656130278509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 10 Dec 2018 10:10:42 +0200 Subject: [PATCH 02/28] Update code comments of `c_void` to explain the reasoning for its current implementation We need at least two variants of the enum as otherwise the compiler complains about the #[repr(u8)] attribute and we also need at least one variant as otherwise the enum would be uninhabitated and dereferencing pointers to it would be UB. As such, mark the variants not unstable because they should not actually exist but because they are temporary implementation details until `extern type` is stable and can be used instead. --- src/libcore/ffi.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 02e92af853452..22e219d51f41f 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -22,16 +22,18 @@ use ::fmt; // N.B., for LLVM to recognize the void pointer type and by extension // functions like malloc(), we need to have it represented as i8* in // LLVM bitcode. The enum used here ensures this and prevents misuse -// of the "raw" type by only having private variants.. We need two +// of the "raw" type by only having private variants. We need two // variants, because the compiler complains about the repr attribute -// otherwise. +// otherwise and we need at least one variant as otherwise the enum +// would be uninhabited and at least dereferencing such pointers would +// be UB. #[repr(u8)] #[stable(feature = "raw_os", since = "1.1.0")] pub enum c_void { - #[unstable(feature = "c_void_variant", reason = "should not have to exist", + #[unstable(feature = "c_void_variant", reason = "temporary implementation detail", issue = "0")] #[doc(hidden)] __variant1, - #[unstable(feature = "c_void_variant", reason = "should not have to exist", + #[unstable(feature = "c_void_variant", reason = "temporary implementation detail", issue = "0")] #[doc(hidden)] __variant2, } From 96678df83821407f2112028cc0099866cb548c49 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 5 Jan 2019 12:41:12 -0500 Subject: [PATCH 03/28] Cleanup PartialEq docs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cleanup the `impl PartialEq for Book` implementation - Implement `impl PartialEq for BookFormat` so it’s symmetric - Fixes https://github.com/rust-lang/rust/issues/53844. - Removes the last example since it appears to be redundant with the previous two examples. --- src/libcore/cmp.rs | 56 ++++++++-------------------------------------- 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index f420d0d00a401..cf24e08e2e706 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -107,67 +107,29 @@ use self::Ordering::*; /// format: BookFormat, /// } /// +/// // Implement == comparisons /// impl PartialEq for Book { /// fn eq(&self, other: &BookFormat) -> bool { -/// match (&self.format, other) { -/// (BookFormat::Paperback, BookFormat::Paperback) => true, -/// (BookFormat::Hardback, BookFormat::Hardback) => true, -/// (BookFormat::Ebook, BookFormat::Ebook) => true, -/// (_, _) => false, -/// } +/// self.format == *other /// } /// } /// -/// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; -/// -/// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); -/// ``` -/// -/// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, -/// we've changed what type we can use on the right side of the `==` operator. -/// This lets us use it in the `assert!` statements at the bottom. -/// -/// You can also combine these implementations to let the `==` operator work with -/// two different types: -/// -/// ``` -/// enum BookFormat { -/// Paperback, -/// Hardback, -/// Ebook, -/// } -/// -/// struct Book { -/// isbn: i32, -/// format: BookFormat, -/// } -/// -/// impl PartialEq for Book { -/// fn eq(&self, other: &BookFormat) -> bool { -/// match (&self.format, other) { -/// (&BookFormat::Paperback, &BookFormat::Paperback) => true, -/// (&BookFormat::Hardback, &BookFormat::Hardback) => true, -/// (&BookFormat::Ebook, &BookFormat::Ebook) => true, -/// (_, _) => false, -/// } -/// } -/// } -/// -/// impl PartialEq for Book { +/// // Implement == comparisons +/// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { -/// self.isbn == other.isbn +/// *other == self.format /// } /// } /// /// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; -/// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; /// /// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); -/// assert!(b1 == b2); +/// assert!(BookFormat::Ebook != b1); /// ``` /// +/// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, +/// we allow `BookFormat`s to be compared with `Book`s. +/// /// # Examples /// /// ``` From 0d3dfdf6aadd7dd241956fa234bdd01de7291e5f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 5 Jan 2019 22:52:13 -0500 Subject: [PATCH 04/28] Fix compile error --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index cf24e08e2e706..89afe7057b17b 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -117,7 +117,7 @@ use self::Ordering::*; /// // Implement == comparisons /// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { -/// *other == self.format +/// *self == other.format /// } /// } /// From 319a2c1cc2a4d99d5b1d6fb424c77963fd668f24 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 6 Jan 2019 11:08:34 -0500 Subject: [PATCH 05/28] add missing derive to fix compile error --- src/libcore/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 89afe7057b17b..5b78aa632d17f 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -65,6 +65,7 @@ use self::Ordering::*; /// the same book if their ISBN matches, even if the formats differ: /// /// ``` +/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, From bbbabdfc52eaa897c965bf10f50af4fc1512d4f0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 6 Jan 2019 15:18:22 -0500 Subject: [PATCH 06/28] Update cmp.rs --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 5b78aa632d17f..64e37ec5a56cb 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -65,7 +65,6 @@ use self::Ordering::*; /// the same book if their ISBN matches, even if the formats differ: /// /// ``` -/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, @@ -97,6 +96,7 @@ use self::Ordering::*; /// For example, let's tweak our previous code a bit: /// /// ``` +/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, From 6c60662b26847a0d8670d298d6a5e95fade576df Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Fri, 4 Jan 2019 11:12:54 -0600 Subject: [PATCH 07/28] Use correct tracking issue for c_variadic Fixes #57306 --- src/libcore/ffi.rs | 22 +++++++++++----------- src/libstd/ffi/mod.rs | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 0717a88b6b8f3..8a35051434dd4 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -49,7 +49,7 @@ impl fmt::Debug for c_void { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] extern { type VaListImpl; } @@ -74,7 +74,7 @@ impl fmt::Debug for VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { stack: *mut (), gr_top: *mut (), @@ -90,7 +90,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { gpr: u8, fpr: u8, @@ -106,7 +106,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { gp_offset: i32, fp_offset: i32, @@ -120,7 +120,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] #[repr(transparent)] pub struct VaList<'a>(&'a mut VaListImpl); @@ -140,7 +140,7 @@ mod sealed_trait { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub trait VaArgSafe {} } @@ -150,7 +150,7 @@ macro_rules! impl_va_arg_safe { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for $t {} )+ } @@ -163,12 +163,12 @@ impl_va_arg_safe!{f64} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for *mut T {} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for *const T {} impl<'a> VaList<'a> { @@ -176,7 +176,7 @@ impl<'a> VaList<'a> { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub unsafe fn arg(&mut self) -> T { va_arg(self) } @@ -185,7 +185,7 @@ impl<'a> VaList<'a> { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub unsafe fn copy(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy>) -> R { #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 62081e713f139..7a38f0ebd5a57 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -169,7 +169,7 @@ pub use core::ffi::c_void; #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub use core::ffi::VaList; mod c_str; From 423a5bb5c437c2ce81d4150490d0cccfdbc33a4c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:00:14 -0500 Subject: [PATCH 08/28] add comment explaining what the derive does --- src/libcore/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 64e37ec5a56cb..72ff9cca9fd86 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -96,6 +96,7 @@ use self::Ordering::*; /// For example, let's tweak our previous code a bit: /// /// ``` +/// // The derive implements == comparisons /// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, From 1445a065ded1bc7e73e7a358f9bc971e908e9181 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:17:49 -0500 Subject: [PATCH 09/28] bring back the example i removed, also add symmetry and simplify impl --- src/libcore/cmp.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 72ff9cca9fd86..db72b7bb9d2da 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -132,6 +132,48 @@ use self::Ordering::*; /// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, /// we allow `BookFormat`s to be compared with `Book`s. /// +/// You can also combine these implementations to let the `==` operator work with +/// two different types: +/// +/// ``` +/// #[derive(PartialEq)] +/// enum BookFormat { +/// Paperback, +/// Hardback, +/// Ebook, +/// } +/// +/// struct Book { +/// isbn: i32, +/// format: BookFormat, +/// } +/// +/// impl PartialEq for Book { +/// fn eq(&self, other: &BookFormat) -> bool { +/// self.format == *other +/// } +/// } +/// +/// impl PartialEq for BookFormat { +/// fn eq(&self, other: &Book) -> bool { +/// *self == other.format +/// } +/// } +/// +/// impl PartialEq for Book { +/// fn eq(&self, other: &Book) -> bool { +/// self.isbn == other.isbn +/// } +/// } +/// +/// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; +/// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; +/// +/// assert!(b1 == BookFormat::Paperback); +/// assert!(b1 != BookFormat::Ebook); +/// assert!(b1 == b2); +/// ``` +/// /// # Examples /// /// ``` From 0394dce7884562651906a84e3a32dc8ad2a50ac8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:19:02 -0500 Subject: [PATCH 10/28] whitespace --- src/libcore/cmp.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index db72b7bb9d2da..65792607a2824 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -142,33 +142,33 @@ use self::Ordering::*; /// Hardback, /// Ebook, /// } -/// +/// /// struct Book { /// isbn: i32, /// format: BookFormat, /// } -/// +/// /// impl PartialEq for Book { /// fn eq(&self, other: &BookFormat) -> bool { /// self.format == *other /// } /// } -/// +/// /// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { /// *self == other.format /// } /// } -/// +/// /// impl PartialEq for Book { /// fn eq(&self, other: &Book) -> bool { /// self.isbn == other.isbn /// } /// } -/// +/// /// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; /// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; -/// +/// /// assert!(b1 == BookFormat::Paperback); /// assert!(b1 != BookFormat::Ebook); /// assert!(b1 == b2); From ebdd072e3b1d4b3eb39048c27be4e9b2ccc849a8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Jan 2019 00:04:47 +0300 Subject: [PATCH 11/28] resolve: Add a test for issue #57539 --- src/test/ui/imports/issue-57539.rs | 8 ++++++++ src/test/ui/imports/issue-57539.stderr | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/imports/issue-57539.rs create mode 100644 src/test/ui/imports/issue-57539.stderr diff --git a/src/test/ui/imports/issue-57539.rs b/src/test/ui/imports/issue-57539.rs new file mode 100644 index 0000000000000..90b74eb464779 --- /dev/null +++ b/src/test/ui/imports/issue-57539.rs @@ -0,0 +1,8 @@ +// edition:2018 + +mod core { + use core; //~ ERROR `core` is ambiguous + use crate::*; +} + +fn main() {} diff --git a/src/test/ui/imports/issue-57539.stderr b/src/test/ui/imports/issue-57539.stderr new file mode 100644 index 0000000000000..3f745fd8204bf --- /dev/null +++ b/src/test/ui/imports/issue-57539.stderr @@ -0,0 +1,18 @@ +error[E0659]: `core` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-57539.rs:4:9 + | +LL | use core; //~ ERROR `core` is ambiguous + | ^^^^ ambiguous name + | + = note: `core` could refer to a built-in extern crate + = help: use `::core` to refer to this extern crate unambiguously +note: `core` could also refer to the module imported here + --> $DIR/issue-57539.rs:5:9 + | +LL | use crate::*; + | ^^^^^^^^ + = help: use `self::core` to refer to this module unambiguously + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. From c6632725c1c72569eb8f017461809648fd9e9c93 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Tue, 13 Nov 2018 16:25:51 -0800 Subject: [PATCH 12/28] Support passing cflags/cxxflags/ldflags to LLVM build This may be needed with some host compilers. --- config.toml.example | 5 +++++ src/bootstrap/config.rs | 10 ++++++++++ src/bootstrap/configure.py | 4 ++++ src/bootstrap/native.rs | 15 ++++++++++++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/config.toml.example b/config.toml.example index 23943d34b7ca8..24293fc864c5f 100644 --- a/config.toml.example +++ b/config.toml.example @@ -90,6 +90,11 @@ # with clang-cl, so this is special in that it only compiles LLVM with clang-cl #clang-cl = '/path/to/clang-cl.exe' +# Pass extra compiler and linker flags to the LLVM CMake build. +#cflags = "-fextra-flag" +#cxxflags = "-fextra-flag" +#ldflags = "-Wl,extra-flag" + # Use libc++ when building LLVM instead of libstdc++. This is the default on # platforms already use libc++ as the default C++ library, but this option # allows you to use libc++ even on platforms when it's not. You need to ensure diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9421817ae6d8e..a2989f0cffa6e 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -82,6 +82,9 @@ pub struct Config { pub lldb_enabled: bool, pub llvm_tools_enabled: bool, + pub llvm_cflags: Option, + pub llvm_cxxflags: Option, + pub llvm_ldflags: Option, pub llvm_use_libcxx: bool, // rust codegen options @@ -254,6 +257,9 @@ struct Llvm { link_shared: Option, version_suffix: Option, clang_cl: Option, + cflags: Option, + cxxflags: Option, + ldflags: Option, use_libcxx: Option, } @@ -516,6 +522,10 @@ impl Config { config.llvm_link_jobs = llvm.link_jobs; config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); + + config.llvm_cflags = llvm.cflags.clone(); + config.llvm_cxxflags = llvm.cxxflags.clone(); + config.llvm_ldflags = llvm.ldflags.clone(); set(&mut config.llvm_use_libcxx, llvm.use_libcxx); } diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index b0c3c9702498d..7b70236dfe8e6 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -64,6 +64,10 @@ def v(*args): o("missing-tools", "dist.missing-tools", "allow failures when building tools") o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++") +o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags") +o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") +o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") + # Optimization and debugging options. These may be overridden by the release # channel, etc. o("optimize", "rust.optimize", "build optimized rust code") diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index cb9c86df55080..f5bacd63e6803 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -358,7 +358,11 @@ fn configure_cmake(builder: &Builder, } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); - cfg.define("CMAKE_C_FLAGS", builder.cflags(target, GitRepo::Llvm).join(" ")); + let mut cflags = builder.cflags(target, GitRepo::Llvm).join(" "); + if let Some(ref s) = builder.config.llvm_cxxflags { + cflags.push_str(&format!(" {}", s)); + } + cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" "); if builder.config.llvm_static_stdcpp && !target.contains("windows") && @@ -366,6 +370,9 @@ fn configure_cmake(builder: &Builder, { cxxflags.push_str(" -static-libstdc++"); } + if let Some(ref s) = builder.config.llvm_cxxflags { + cxxflags.push_str(&format!(" {}", s)); + } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { if ar.is_absolute() { @@ -383,6 +390,12 @@ fn configure_cmake(builder: &Builder, } } + if let Some(ref s) = builder.config.llvm_ldflags { + cfg.define("CMAKE_SHARED_LINKER_FLAGS", s); + cfg.define("CMAKE_MODULE_LINKER_FLAGS", s); + cfg.define("CMAKE_EXE_LINKER_FLAGS", s); + } + if env::var_os("SCCACHE_ERROR_LOG").is_some() { cfg.env("RUST_LOG", "sccache=warn"); } From f4ded5b5591b3ec1446422dd9d62d404d4335753 Mon Sep 17 00:00:00 2001 From: Michael Bradshaw Date: Mon, 24 Dec 2018 16:07:10 -0700 Subject: [PATCH 13/28] Add a regression test for mutating a non-mut #[thread_local] --- src/test/ui/thread-local-mutation.nll.stderr | 9 +++++++++ src/test/ui/thread-local-mutation.rs | 18 ++++++++++++++++++ src/test/ui/thread-local-mutation.stderr | 9 +++++++++ 3 files changed, 36 insertions(+) create mode 100644 src/test/ui/thread-local-mutation.nll.stderr create mode 100644 src/test/ui/thread-local-mutation.rs create mode 100644 src/test/ui/thread-local-mutation.stderr diff --git a/src/test/ui/thread-local-mutation.nll.stderr b/src/test/ui/thread-local-mutation.nll.stderr new file mode 100644 index 0000000000000..0a3664b0d9d40 --- /dev/null +++ b/src/test/ui/thread-local-mutation.nll.stderr @@ -0,0 +1,9 @@ +error[E0594]: cannot assign to immutable static item `S` + --> $DIR/thread-local-mutation.rs:11:5 + | +LL | S = "after"; //~ ERROR cannot assign to immutable + | ^^^^^^^^^^^ cannot assign + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/thread-local-mutation.rs b/src/test/ui/thread-local-mutation.rs new file mode 100644 index 0000000000000..e738225ce2a48 --- /dev/null +++ b/src/test/ui/thread-local-mutation.rs @@ -0,0 +1,18 @@ +// Regression test for #54901: immutable thread locals could be mutated. See: +// https://github.com/rust-lang/rust/issues/29594#issuecomment-328177697 +// https://github.com/rust-lang/rust/issues/54901 + +#![feature(thread_local)] + +#[thread_local] +static S: &str = "before"; + +fn set_s() { + S = "after"; //~ ERROR cannot assign to immutable +} + +fn main() { + println!("{}", S); + set_s(); + println!("{}", S); +} diff --git a/src/test/ui/thread-local-mutation.stderr b/src/test/ui/thread-local-mutation.stderr new file mode 100644 index 0000000000000..bf298523e1b73 --- /dev/null +++ b/src/test/ui/thread-local-mutation.stderr @@ -0,0 +1,9 @@ +error[E0594]: cannot assign to immutable thread-local static item + --> $DIR/thread-local-mutation.rs:11:5 + | +LL | S = "after"; //~ ERROR cannot assign to immutable + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. From e5e9867f604b9f656d529deb04a6b99338770c9e Mon Sep 17 00:00:00 2001 From: AB1908 Date: Tue, 15 Jan 2019 08:26:29 +0000 Subject: [PATCH 14/28] Pass a default value when unwrapping a span Fixes #57323 --- src/librustc_metadata/native_libs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index d35d64957b7b4..1f00086e32fe1 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -163,7 +163,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { !self.tcx.features().static_nobundle { feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, "static_nobundle", - span.unwrap(), + span.unwrap_or_else(|| syntax_pos::DUMMY_SP), GateIssue::Language, "kind=\"static-nobundle\" is feature gated"); } From 93b55365b59767f87ac2a2e42876ad46210a0e55 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 15 Jan 2019 11:27:58 -0500 Subject: [PATCH 15/28] use structured macro and path resolve suggestions --- src/librustc_resolve/lib.rs | 24 ++++++++++--- src/test/ui/resolve/resolve-hint-macro.stderr | 2 +- ...uggest-path-instead-of-mod-dot-item.stderr | 36 ++++++++++++------- .../try-block/try-block-in-edition2015.stderr | 2 +- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a25009ccfb49c..439d149227203 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3321,7 +3321,12 @@ impl<'a> Resolver<'a> { if let Some(def) = def { match (def, source) { (Def::Macro(..), _) => { - err.span_label(span, format!("did you mean `{}!(...)`?", path_str)); + err.span_suggestion_with_applicability( + span, + "use `!` to invoke the macro", + format!("{}!", path_str), + Applicability::MaybeIncorrect, + ); return (err, candidates); } (Def::TyAlias(..), PathSource::Trait(_)) => { @@ -3333,13 +3338,22 @@ impl<'a> Resolver<'a> { } (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { ExprKind::Field(_, ident) => { - err.span_label(parent.span, format!("did you mean `{}::{}`?", - path_str, ident)); + err.span_suggestion_with_applicability( + parent.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect, + ); return (err, candidates); } ExprKind::MethodCall(ref segment, ..) => { - err.span_label(parent.span, format!("did you mean `{}::{}(...)`?", - path_str, segment.ident)); + let span = parent.span.with_hi(segment.ident.span.hi()); + err.span_suggestion_with_applicability( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); return (err, candidates); } _ => {} diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr index 4f6d0f695df44..ebe3c36f21eb1 100644 --- a/src/test/ui/resolve/resolve-hint-macro.stderr +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, found macro `assert` --> $DIR/resolve-hint-macro.rs:2:5 | LL | assert(true); - | ^^^^^^ did you mean `assert!(...)`? + | ^^^^^^ help: use `!` to invoke the macro: `assert!` error: aborting due to previous error diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index 8a9426bfee862..b7b158ce7efa6 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -4,15 +4,15 @@ error[E0423]: expected value, found module `a` LL | a.I | ^-- | | - | did you mean `a::I`? + | help: use the path separator to refer to an item: `a::I` error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5 | LL | a.g() - | ^---- + | ^-- | | - | did you mean `a::g(...)`? + | help: use the path separator to refer to an item: `a::g` error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5 @@ -20,16 +20,21 @@ error[E0423]: expected value, found module `a` LL | a.b.J | ^-- | | - | did you mean `a::b`? + | help: use the path separator to refer to an item: `a::b` error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5 | LL | a::b.J - | ^^^--- - | | | - | | help: a constant with a similar name exists: `I` - | did you mean `a::b::J`? + | ^^^^ +help: a constant with a similar name exists + | +LL | a::I.J + | ^ +help: use the path separator to refer to an item + | +LL | a::b::J + | error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5 @@ -37,7 +42,7 @@ error[E0423]: expected value, found module `a` LL | a.b.f(); | ^-- | | - | did you mean `a::b`? + | help: use the path separator to refer to an item: `a::b` error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12 @@ -51,10 +56,15 @@ error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5 | LL | a::b.f() - | ^^^----- - | | | - | | help: a constant with a similar name exists: `I` - | did you mean `a::b::f(...)`? + | ^^^^ +help: a constant with a similar name exists + | +LL | a::I.f() + | ^ +help: use the path separator to refer to an item + | +LL | a::b::f() + | ^^^^^^^ error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5 diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index 63650086bcaa9..a7b81060d3dc6 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -15,7 +15,7 @@ error[E0574]: expected struct, variant or union type, found macro `try` --> $DIR/try-block-in-edition2015.rs:4:33 | LL | let try_result: Option<_> = try { - | ^^^ did you mean `try!(...)`? + | ^^^ help: use `!` to invoke the macro: `try!` error: aborting due to 2 previous errors From ed717f30ec3006e465ed4d68adf31cabdf0329fa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jan 2019 17:57:06 +0100 Subject: [PATCH 16/28] Fix sources sidebar not showing up --- src/librustdoc/html/render.rs | 2 +- src/librustdoc/html/static/source-script.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 31e06cb1a045f..1d50afe2821ac 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1042,7 +1042,7 @@ themePicker.onblur = handleThemeButtonsBlur; all_sources.sort(); let mut w = try_err!(File::create(&dst), &dst); try_err!(writeln!(&mut w, - "var N = null;var sourcesIndex = {{}};\n{}", + "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();", all_sources.join("\n")), &dst); } diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 0affe1c6812f5..c5d6fa16f550e 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -137,5 +137,3 @@ function createSourceSidebar() { main.insertBefore(sidebar, main.firstChild); } - -createSourceSidebar(); From feda6040faa854f6bbe6ab9c7f11b59ec21ec1d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jan 2019 23:21:10 +0100 Subject: [PATCH 17/28] Fixes text becoming invisible when element targetted --- src/librustdoc/html/static/themes/dark.css | 8 +------- src/librustdoc/html/static/themes/light.css | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 1390be700634d..52a30967a2310 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -82,12 +82,6 @@ pre { border-bottom-color: #ddd; } -:target { background: #494a3d; } - -:target > .in-band { - background: #494a3d; -} - .content .method .where, .content .fn .where, .content .where.fmt-newline { @@ -252,7 +246,7 @@ a.test-arrow:hover{ color: #999; } -:target > code { +:target > code, :target > .in-band { background-color: #494a3d; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 2b04dd2388d45..d20fea666e61d 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -84,12 +84,6 @@ pre { border-bottom-color: #ddd; } -:target { background: #FDFFD3; } - -:target > .in-band { - background: #FDFFD3; -} - .content .method .where, .content .fn .where, .content .where.fmt-newline { @@ -247,7 +241,7 @@ a.test-arrow:hover{ color: #999; } -:target > code { +:target > code, :target > .in-band { background: #FDFFD3; } From 32b28340b20ea8b45d3e663dc81bb9092ecdeeb1 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 15 Jan 2019 21:21:24 -0500 Subject: [PATCH 18/28] demonstrate symmetry --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 65792607a2824..a2f719cf406fe 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -170,7 +170,7 @@ use self::Ordering::*; /// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; /// /// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); +/// assert!(BookFormat::Ebook != b1); /// assert!(b1 == b2); /// ``` /// From bd8ee511a53547851a251c0e4b490cd381e970e8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 15 Jan 2019 18:46:09 -0800 Subject: [PATCH 19/28] Add some links in std::fs. A few items were referenced, but did not have links. --- src/libstd/fs.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 119b3f7f9f296..3538816c1124c 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1121,7 +1121,9 @@ impl Permissions { /// writing. /// /// This operation does **not** modify the filesystem. To modify the - /// filesystem use the `fs::set_permissions` function. + /// filesystem use the [`fs::set_permissions`] function. + /// + /// [`fs::set_permissions`]: fn.set_permissions.html /// /// # Examples /// @@ -1639,10 +1641,15 @@ pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> io::Result<( /// /// The `dst` path will be a symbolic link pointing to the `src` path. /// On Windows, this will be a file symlink, not a directory symlink; -/// for this reason, the platform-specific `std::os::unix::fs::symlink` -/// and `std::os::windows::fs::{symlink_file, symlink_dir}` should be +/// for this reason, the platform-specific [`std::os::unix::fs::symlink`] +/// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be /// used instead to make the intent explicit. /// +/// [`std::os::unix::fs::symlink`]: ../os/unix/fs/fn.symlink.html +/// [`std::os::windows::fs::symlink_file`]: ../os/windows/fs/fn.symlink_file.html +/// [`symlink_dir`]: ../os/windows/fs/fn.symlink_dir.html +/// +/// /// # Examples /// /// ```no_run @@ -1795,7 +1802,7 @@ pub fn create_dir>(path: P) -> io::Result<()> { /// * If any directory in the path specified by `path` /// does not already exist and it could not be created otherwise. The specific /// error conditions for when a directory is being created (after it is -/// determined to not exist) are outlined by `fs::create_dir`. +/// determined to not exist) are outlined by [`fs::create_dir`]. /// /// Notable exception is made for situations where any of the directories /// specified in the `path` could not be created as it was being created concurrently. @@ -1803,6 +1810,8 @@ pub fn create_dir>(path: P) -> io::Result<()> { /// concurrently from multiple threads or processes is guaranteed not to fail /// due to a race condition with itself. /// +/// [`fs::create_dir`]: fn.create_dir.html +/// /// # Examples /// /// ```no_run @@ -1868,7 +1877,10 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// # Errors /// -/// See `file::remove_file` and `fs::remove_dir`. +/// See [`fs::remove_file`] and [`fs::remove_dir`]. +/// +/// [`fs::remove_file`]: fn.remove_file.html +/// [`fs::remove_dir`]: fn.remove_dir.html /// /// # Examples /// From ae4b14e837b613febc9a7ccfee4230fb22044a10 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Jan 2019 13:51:24 +1100 Subject: [PATCH 20/28] Use `Lit` rather than `P` in `hir::ExprKind`. It's simpler and makes some benchmark run up to 1% faster. It also makes `hir::ExprKind` more like `ast::ExprKind` (which underwent the equivalent change in #55777). --- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8badcbfc1b301..8cdc493e6fda7 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3775,7 +3775,7 @@ impl<'a> LoweringContext<'a> { let ohs = P(self.lower_expr(ohs)); hir::ExprKind::Unary(op, ohs) } - ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((*l).clone())), + ExprKind::Lit(ref l) => hir::ExprKind::Lit((*l).clone()), ExprKind::Cast(ref expr, ref ty) => { let expr = P(self.lower_expr(expr)); hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed())) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index fc4bd05476f6c..cf4bd27a0900a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1466,7 +1466,7 @@ pub enum ExprKind { /// A unary operation (For example: `!x`, `*x`) Unary(UnOp, P), /// A literal (For example: `1`, `"foo"`) - Lit(P), + Lit(Lit), /// A cast (`foo as f64`) Cast(P, P), Type(P, P), From dc455286205bc0b3be6a6c6dcefff0498a6f4bcf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Jan 2019 16:20:32 +1100 Subject: [PATCH 21/28] Remove `hir::Label`. It's identical to `ast::Label`. --- src/librustc/hir/mod.rs | 13 +------------ src/librustc/ich/impls_hir.rs | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index cf4bd27a0900a..aaef1c722be96 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -19,7 +19,7 @@ use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; use syntax::source_map::{self, Spanned}; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; -use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy}; +use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy}; use syntax::attr::InlineAttr; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; @@ -142,17 +142,6 @@ pub const DUMMY_HIR_ID: HirId = HirId { pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] -pub struct Label { - pub ident: Ident, -} - -impl fmt::Debug for Label { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "label({:?})", self.ident) - } -} - #[derive(Clone, RustcEncodable, RustcDecodable, Copy)] pub struct Lifetime { pub id: NodeId, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 8ff60e5f56225..f48059b328ff3 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -153,7 +153,7 @@ impl_stable_hash_for!(enum hir::LifetimeName { Error, }); -impl_stable_hash_for!(struct hir::Label { +impl_stable_hash_for!(struct ast::Label { ident }); From e4e888534eae603dfd0d9f9e75e8bb21d5e35f06 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 17 Jan 2019 00:39:15 +0100 Subject: [PATCH 22/28] Document Unpin in std::prelude documentation --- src/libstd/prelude/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index ec8318f3728eb..bf689bad559d3 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -44,8 +44,8 @@ //! The current version of the prelude (version 1) lives in //! [`std::prelude::v1`], and re-exports the following. //! -//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`]}. The marker -//! traits indicate fundamental properties of types. +//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`], [`Unpin`]}. The +//! marker traits indicate fundamental properties of types. //! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}. Various //! operations for both destructors and overloading `()`. //! * [`std::mem`]::[`drop`][`mem::drop`], a convenience function for explicitly @@ -108,6 +108,7 @@ //! [`Sync`]: ../marker/trait.Sync.html //! [`ToOwned`]: ../borrow/trait.ToOwned.html //! [`ToString`]: ../string/trait.ToString.html +//! [`Unpin`]: ../marker/trait.Unpin.html //! [`Vec`]: ../vec/struct.Vec.html //! [`Clone::clone`]: ../clone/trait.Clone.html#tymethod.clone //! [`mem::drop`]: ../mem/fn.drop.html From 22251a87be74865cc977f3fdcc995c1c467361c7 Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Wed, 16 Jan 2019 20:10:18 -0600 Subject: [PATCH 23/28] Enhance `Pin` impl applicability for `PartialEq` and `PartialOrd`. --- src/libcore/pin.rs | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 762e07549a52a..022481f463514 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -99,6 +99,7 @@ use fmt; use marker::{Sized, Unpin}; +use cmp::{self, PartialEq, PartialOrd}; use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; /// A pinned pointer. @@ -112,16 +113,59 @@ use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; /// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`pin` module]: ../../std/pin/index.html // -// Note: the derives below are allowed because they all only use `&P`, so they -// cannot move the value behind `pointer`. +// Note: the derives below, and the explicit `PartialEq` and `PartialOrd` +// implementations, are allowed because they all only use `&P`, so they cannot move +// the value behind `pointer`. #[stable(feature = "pin", since = "1.33.0")] #[fundamental] #[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Copy, Clone, Hash, Eq, Ord)] pub struct Pin

{ pointer: P, } +#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")] +impl PartialEq> for Pin

+where + P: PartialEq, +{ + + fn eq(&self, other: &Pin) -> bool { + self.pointer == other.pointer + } + + fn ne(&self, other: &Pin) -> bool { + self.pointer != other.pointer + } +} + +#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")] +impl PartialOrd> for Pin

+where + P: PartialOrd, +{ + + fn partial_cmp(&self, other: &Pin) -> Option { + self.pointer.partial_cmp(&other.pointer) + } + + fn lt(&self, other: &Pin) -> bool { + self.pointer < other.pointer + } + + fn le(&self, other: &Pin) -> bool { + self.pointer <= other.pointer + } + + fn gt(&self, other: &Pin) -> bool { + self.pointer > other.pointer + } + + fn ge(&self, other: &Pin) -> bool { + self.pointer >= other.pointer + } +} + impl Pin

where P::Target: Unpin, From 1e3f475d643603b9570710b13e20de587a22a5ea Mon Sep 17 00:00:00 2001 From: AB1908 Date: Thu, 17 Jan 2019 03:40:36 +0000 Subject: [PATCH 24/28] Add test for linking non-existent static library --- src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs | 6 ++++++ .../ui/feature-gate/feature-gate-static-nobundle-2.stderr | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs new file mode 100644 index 0000000000000..92844f9306d28 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs @@ -0,0 +1,6 @@ +//~ ERROR kind="static-nobundle" is feature gated +// Test the behavior of rustc when non-existent library is statically linked + +// compile-flags: -l static-nobundle=nonexistent + +fn main() {} diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr new file mode 100644 index 0000000000000..419c21901a02f --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr @@ -0,0 +1,7 @@ +error[E0658]: kind="static-nobundle" is feature gated (see issue #37403) + | + = help: add #![feature(static_nobundle)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From fefe1dacb6255304dab5c13fb669b1d9d40f9e03 Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Wed, 16 Jan 2019 23:03:29 -0600 Subject: [PATCH 25/28] Fix tidy errors. --- src/libcore/pin.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 022481f463514..7c09a36d89883 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -129,7 +129,6 @@ impl PartialEq> for Pin

where P: PartialEq, { - fn eq(&self, other: &Pin) -> bool { self.pointer == other.pointer } @@ -144,7 +143,6 @@ impl PartialOrd> for Pin

where P: PartialOrd, { - fn partial_cmp(&self, other: &Pin) -> Option { self.pointer.partial_cmp(&other.pointer) } From 25189874fb14b53c6647c337f34d77a7dd51a5a0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 17 Jan 2019 21:28:23 +0100 Subject: [PATCH 26/28] Fix non-clickable urls --- src/librustdoc/html/static/rustdoc.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8a8b7adcf7d4a..36765496ff4e9 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -391,10 +391,6 @@ h4 > code, h3 > code, .invisible > code { display: block; } -.in-band, code { - z-index: -5; -} - .invisible { width: 100%; display: inline-block; From e3ba6ed3f571119e2f9165805e77c20b5e7a14b4 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Thu, 17 Jan 2019 13:53:21 +0000 Subject: [PATCH 27/28] Fix suggestions given mulitple bad lifetimes When given multiple lifetimes prior to type parameters in generic parameters, do not ICE and print the correct suggestion. --- src/librustc_errors/lib.rs | 9 ++-- src/libsyntax/parse/parser.rs | 21 +++------ src/test/ui/lifetime-before-type-params.rs | 9 ++++ .../ui/lifetime-before-type-params.stderr | 47 +++++++++++++++++++ .../suggestions/suggest-move-lifetimes.stderr | 4 +- 5 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/lifetime-before-type-params.rs create mode 100644 src/test/ui/lifetime-before-type-params.stderr diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index a074441f8a179..3e25f98ccd27c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -135,10 +135,11 @@ impl CodeSuggestion { if let Some(line) = line_opt { if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) { let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi)); - buf.push_str(match hi_opt { - Some(hi) => &line[lo..hi], - None => &line[lo..], - }); + match hi_opt { + Some(hi) if hi > lo => buf.push_str(&line[lo..hi]), + Some(_) => (), + None => buf.push_str(&line[lo..]), + } } if let None = hi_opt { buf.push('\n'); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 823c786bded26..5b430d13516b4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5234,22 +5234,13 @@ impl<'a> Parser<'a> { kind: ast::GenericParamKind::Lifetime, }); if let Some(sp) = seen_ty_param { - let param_span = self.prev_span; - let ate_comma = self.eat(&token::Comma); - let remove_sp = if ate_comma { - param_span.until(self.span) - } else { - last_comma_span.unwrap_or(param_span).to(param_span) - }; - bad_lifetime_pos.push(param_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) { + let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); + bad_lifetime_pos.push(self.prev_span); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { suggestions.push((remove_sp, String::new())); - suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet))); - } - if ate_comma { - last_comma_span = Some(self.prev_span); - continue + suggestions.push(( + sp.shrink_to_lo(), + format!("{}, ", snippet))); } } } else if self.check_ident() { diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs new file mode 100644 index 0000000000000..9b905d4883a16 --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.rs @@ -0,0 +1,9 @@ +#![allow(unused)] +fn first() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn second<'a, T, 'b>() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn third() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn fourth<'a, T, 'b, U, 'c, V>() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr new file mode 100644 index 0000000000000..7ac8dffdfbe0c --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -0,0 +1,47 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:2:13 + | +LL | fn first() {} + | ^^ ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn first<'a, 'b, T>() {} + | ^^^ ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:4:18 + | +LL | fn second<'a, T, 'b>() {} + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn second<'a, 'b, T>() {} + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:6:16 + | +LL | fn third() {} + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn third<'a, T, U>() {} + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:8:18 + | +LL | fn fourth<'a, T, 'b, U, 'c, V>() {} + | ^^ ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn fourth<'a, 'b, 'c, T, U, V>() {} + | ^^^ ^^^ -- -- + +error[E0601]: `main` function not found in crate `lifetime_before_type_params` + | + = note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index 72a2cbe6bf6de..b36e927b5c0c6 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -16,7 +16,7 @@ LL | struct B { //~ ERROR lifetime parameters must be declared help: move the lifetime parameter prior to the first type parameter | LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared - | ^^^ -- + | ^^^ -- error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:10:16 @@ -36,7 +36,7 @@ LL | struct D { //~ ERROR lifetime parameters must be decla help: move the lifetime parameter prior to the first type parameter | LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared - | ^^^ ^^^ ^^^ --- + | ^^^ ^^^ ^^^ -- -- error: aborting due to 4 previous errors From ec3c5b0199045b3ae3959631998451543bd99518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:19:30 -0800 Subject: [PATCH 28/28] Use structured suggestion to surround struct literal with parenthesis --- src/librustc_resolve/lib.rs | 42 ++++++++++++++++++++++++---- src/test/ui/error-codes/E0423.stderr | 12 ++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 39be3cb744080..430edcafae26a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3369,6 +3369,29 @@ impl<'a> Resolver<'a> { Ok(ref snippet) if snippet == "{" => true, _ => false, }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); + } + break; + } + } + _ => break, + } + i += 1; + if i > 100 { // The bigger the span the more likely we're + break; // incorrect. Bound it to 100 chars long. + } + } match source { PathSource::Expr(Some(parent)) => { match parent.node { @@ -3395,11 +3418,20 @@ impl<'a> Resolver<'a> { } }, PathSource::Expr(None) if followed_by_brace == true => { - err.span_label( - span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), - ); + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion_with_applicability( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", + path_str), + ); + } return (err, candidates); }, _ => { diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index df9ed631a1c2e..3f3c78c68d097 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -29,19 +29,25 @@ error[E0423]: expected value, found struct `S` --> $DIR/E0423.rs:12:32 | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } - | ^ did you mean `(S { /* fields */ })`? + | ^--------------- + | | + | help: surround the struct literal with parenthesis: `(S { x: 1, y: 2 })` error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:15:8 | LL | if T {} == T {} { println!("Ok"); } - | ^ did you mean `(T { /* fields */ })`? + | ^--- + | | + | help: surround the struct literal with parenthesis: `(T {})` error[E0423]: expected value, found struct `std::ops::Range` --> $DIR/E0423.rs:21:14 | LL | for _ in std::ops::Range { start: 0, end: 10 } {} - | ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`? + | ^^^^^^^^^^^^^^^---------------------- + | | + | help: surround the struct literal with parenthesis: `(std::ops::Range { start: 0, end: 10 })` error: aborting due to 7 previous errors