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"); } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 86f28a957cd2c..d43a5c1032ce0 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -91,6 +91,8 @@ use self::Ordering::*; /// For example, let's tweak our previous code a bit: /// /// ``` +/// // The derive implements == comparisons +/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, @@ -102,31 +104,34 @@ 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 +/// } +/// } +/// +/// // Implement == comparisons +/// impl PartialEq for BookFormat { +/// fn eq(&self, other: &Book) -> bool { +/// *self == other.format /// } /// } /// /// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; /// /// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); +/// assert!(BookFormat::Ebook != b1); /// ``` /// /// 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. +/// 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, @@ -140,12 +145,13 @@ use self::Ordering::*; /// /// 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 +/// } +/// } +/// +/// impl PartialEq for BookFormat { +/// fn eq(&self, other: &Book) -> bool { +/// *self == other.format /// } /// } /// @@ -159,7 +165,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); /// ``` /// diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 0717a88b6b8f3..644380c69f2c7 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -12,24 +12,27 @@ 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 -// 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, } @@ -49,7 +52,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 +77,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 +93,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 +109,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 +123,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 +143,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 +153,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 +166,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 +179,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 +188,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/libcore/hint.rs b/src/libcore/hint.rs index 9e57a4ebc9919..ad5a2071a7381 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -49,3 +49,26 @@ use intrinsics; pub unsafe fn unreachable_unchecked() -> ! { intrinsics::unreachable() } + +/// Save power or switch hyperthreads in a busy-wait spin-loop. +/// +/// This function is deliberately more primitive than +/// [`std::thread::yield_now`](../../std/thread/fn.yield_now.html) and +/// does not directly yield to the system's scheduler. +/// In some cases it might be useful to use a combination of both functions. +/// Careful benchmarking is advised. +/// +/// On some platforms this function may not do anything at all. +#[inline] +#[unstable(feature = "renamed_spin_loop", issue = "55002")] +pub fn spin_loop() { + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + unsafe { + asm!("pause" ::: "memory" : "volatile"); + } + + #[cfg(target_arch = "aarch64")] + unsafe { + asm!("yield" ::: "memory" : "volatile"); + } +} 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, diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 99e6365d15ec0..8992e513e83a4 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -84,6 +84,8 @@ use intrinsics; use cell::UnsafeCell; use fmt; +use hint::spin_loop; + /// Save power or switch hyperthreads in a busy-wait spin-loop. /// /// This function is deliberately more primitive than @@ -96,15 +98,7 @@ use fmt; #[inline] #[stable(feature = "spin_loop_hint", since = "1.24.0")] pub fn spin_loop_hint() { - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - unsafe { - asm!("pause" ::: "memory" : "volatile"); - } - - #[cfg(target_arch = "aarch64")] - unsafe { - asm!("yield" ::: "memory" : "volatile"); - } + spin_loop() } /// A boolean type which can be safely shared between threads. diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 427fe51e6ff9c..d1067b70778ee 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -476,6 +476,9 @@ define_dep_nodes!( <'tcx> [] CheckModLoops(DefId), [] CheckModUnstableApiUsage(DefId), [] CheckModItemTypes(DefId), + [] CheckModPrivacy(DefId), + [] CheckModIntrinsics(DefId), + [] CheckModLiveness(DefId), [] CollectModItemTypes(DefId), [] Reachability, diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 501ef01d74c6e..0a0dff05cb1ab 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock}; +use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering}; use std::env; use std::hash::Hash; use std::collections::hash_map::Entry; @@ -58,7 +58,7 @@ struct DepGraphData { /// nodes and edges as well as all fingerprints of nodes that have them. previous: PreviousDepGraph, - colors: Lock, + colors: DepNodeColorMap, /// When we load, there may be `.o` files, cached mir, or other such /// things available to us. If we find that they are not dirty, we @@ -84,7 +84,7 @@ impl DepGraph { dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)), previous: prev_graph, - colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)), + colors: DepNodeColorMap::new(prev_graph_node_count), loaded_from_cache: Default::default(), })), } @@ -282,12 +282,11 @@ impl DepGraph { DepNodeColor::Red }; - let mut colors = data.colors.borrow_mut(); - debug_assert!(colors.get(prev_index).is_none(), + debug_assert!(data.colors.get(prev_index).is_none(), "DepGraph::with_task() - Duplicate DepNodeColor \ insertion for {:?}", key); - colors.insert(prev_index, color); + data.colors.insert(prev_index, color); } (result, dep_node_index) @@ -502,7 +501,7 @@ impl DepGraph { pub fn node_color(&self, dep_node: &DepNode) -> Option { if let Some(ref data) = self.data { if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) { - return data.colors.borrow().get(prev_index) + return data.colors.get(prev_index) } else { // This is a node that did not exist in the previous compilation // session, so we consider it to be red. @@ -513,56 +512,89 @@ impl DepGraph { None } - pub fn try_mark_green<'tcx>(&self, - tcx: TyCtxt<'_, 'tcx, 'tcx>, - dep_node: &DepNode) - -> Option { - debug!("try_mark_green({:?}) - BEGIN", dep_node); - let data = self.data.as_ref().unwrap(); + /// Try to read a node index for the node dep_node. + /// A node will have an index, when it's already been marked green, or when we can mark it + /// green. This function will mark the current task as a reader of the specified node, when + /// a node index can be found for that node. + pub fn try_mark_green_and_read( + &self, + tcx: TyCtxt<'_, '_, '_>, + dep_node: &DepNode + ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { + self.try_mark_green(tcx, dep_node).map(|(prev_index, dep_node_index)| { + debug_assert!(self.is_green(&dep_node)); + self.read_index(dep_node_index); + (prev_index, dep_node_index) + }) + } - #[cfg(not(parallel_queries))] - debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); - - if dep_node.kind.is_input() { - // We should only hit try_mark_green() for inputs that do not exist - // anymore in the current compilation session. Existing inputs are - // eagerly marked as either red/green before any queries are - // executed. - debug_assert!(dep_node.extract_def_id(tcx).is_none()); - debug!("try_mark_green({:?}) - END - DepNode is deleted input", dep_node); - return None; - } + pub fn try_mark_green( + &self, + tcx: TyCtxt<'_, '_, '_>, + dep_node: &DepNode + ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { + debug_assert!(!dep_node.kind.is_input()); + + // Return None if the dep graph is disabled + let data = self.data.as_ref()?; + + // Return None if the dep node didn't exist in the previous session + let prev_index = data.previous.node_to_index_opt(dep_node)?; - let (prev_deps, prev_dep_node_index) = match data.previous.edges_from(dep_node) { - Some(prev) => { + match data.colors.get(prev_index) { + Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)), + Some(DepNodeColor::Red) => None, + None => { // This DepNode and the corresponding query invocation existed // in the previous compilation session too, so we can try to // mark it as green by recursively marking all of its // dependencies green. - prev - } - None => { - // This DepNode did not exist in the previous compilation session, - // so we cannot mark it as green. - debug!("try_mark_green({:?}) - END - DepNode does not exist in \ - current compilation session anymore", dep_node); - return None + self.try_mark_previous_green( + tcx.global_tcx(), + data, + prev_index, + &dep_node + ).map(|dep_node_index| { + (prev_index, dep_node_index) + }) } - }; + } + } + + /// Try to mark a dep-node which existed in the previous compilation session as green + fn try_mark_previous_green<'tcx>( + &self, + tcx: TyCtxt<'_, 'tcx, 'tcx>, + data: &DepGraphData, + prev_dep_node_index: SerializedDepNodeIndex, + dep_node: &DepNode + ) -> Option { + debug!("try_mark_previous_green({:?}) - BEGIN", dep_node); - debug_assert!(data.colors.borrow().get(prev_dep_node_index).is_none()); + #[cfg(not(parallel_queries))] + { + debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); + debug_assert!(data.colors.get(prev_dep_node_index).is_none()); + } + + // We never try to mark inputs as green + debug_assert!(!dep_node.kind.is_input()); + + debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); + + let prev_deps = data.previous.edge_targets_from(prev_dep_node_index); let mut current_deps = SmallVec::new(); for &dep_dep_node_index in prev_deps { - let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); + let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { // This dependency has been marked as green before, we are // still fine and can continue with checking the other // dependencies. - debug!("try_mark_green({:?}) --- found dependency {:?} to \ + debug!("try_mark_previous_green({:?}) --- found dependency {:?} to \ be immediately green", dep_node, data.previous.index_to_node(dep_dep_node_index)); @@ -573,7 +605,7 @@ impl DepGraph { // compared to the previous compilation session. We cannot // mark the DepNode as green and also don't need to bother // with checking any of the other dependencies. - debug!("try_mark_green({:?}) - END - dependency {:?} was \ + debug!("try_mark_previous_green({:?}) - END - dependency {:?} was \ immediately red", dep_node, data.previous.index_to_node(dep_dep_node_index)); @@ -585,12 +617,18 @@ impl DepGraph { // We don't know the state of this dependency. If it isn't // an input node, let's try to mark it green recursively. if !dep_dep_node.kind.is_input() { - debug!("try_mark_green({:?}) --- state of dependency {:?} \ + debug!("try_mark_previous_green({:?}) --- state of dependency {:?} \ is unknown, trying to mark it green", dep_node, dep_dep_node); - if let Some(node_index) = self.try_mark_green(tcx, dep_dep_node) { - debug!("try_mark_green({:?}) --- managed to MARK \ + let node_index = self.try_mark_previous_green( + tcx, + data, + dep_dep_node_index, + dep_dep_node + ); + if let Some(node_index) = node_index { + debug!("try_mark_previous_green({:?}) --- managed to MARK \ dependency {:?} as green", dep_node, dep_dep_node); current_deps.push(node_index); continue; @@ -620,20 +658,20 @@ impl DepGraph { } // We failed to mark it green, so we try to force the query. - debug!("try_mark_green({:?}) --- trying to force \ + debug!("try_mark_previous_green({:?}) --- trying to force \ dependency {:?}", dep_node, dep_dep_node); if ::ty::query::force_from_dep_node(tcx, dep_dep_node) { - let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); + let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { - debug!("try_mark_green({:?}) --- managed to \ + debug!("try_mark_previous_green({:?}) --- managed to \ FORCE dependency {:?} to green", dep_node, dep_dep_node); current_deps.push(node_index); } Some(DepNodeColor::Red) => { - debug!("try_mark_green({:?}) - END - \ + debug!("try_mark_previous_green({:?}) - END - \ dependency {:?} was red after forcing", dep_node, dep_dep_node); @@ -641,7 +679,7 @@ impl DepGraph { } None => { if !tcx.sess.has_errors() { - bug!("try_mark_green() - Forcing the DepNode \ + bug!("try_mark_previous_green() - Forcing the DepNode \ should have set its color") } else { // If the query we just forced has resulted @@ -653,7 +691,7 @@ impl DepGraph { } } else { // The DepNode could not be forced. - debug!("try_mark_green({:?}) - END - dependency {:?} \ + debug!("try_mark_previous_green({:?}) - END - dependency {:?} \ could not be forced", dep_node, dep_dep_node); return None } @@ -705,16 +743,15 @@ impl DepGraph { } // ... and finally storing a "Green" entry in the color map. - let mut colors = data.colors.borrow_mut(); // Multiple threads can all write the same color here #[cfg(not(parallel_queries))] - debug_assert!(colors.get(prev_dep_node_index).is_none(), - "DepGraph::try_mark_green() - Duplicate DepNodeColor \ + debug_assert!(data.colors.get(prev_dep_node_index).is_none(), + "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ insertion for {:?}", dep_node); - colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); + data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); - debug!("try_mark_green({:?}) - END - successfully marked as green", dep_node); + debug!("try_mark_previous_green({:?}) - END - successfully marked as green", dep_node); Some(dep_node_index) } @@ -735,9 +772,8 @@ impl DepGraph { pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { let green_nodes: Vec = { let data = self.data.as_ref().unwrap(); - let colors = data.colors.borrow(); - colors.values.indices().filter_map(|prev_index| { - match colors.get(prev_index) { + data.colors.values.indices().filter_map(|prev_index| { + match data.colors.get(prev_index) { Some(DepNodeColor::Green(_)) => { let dep_node = data.previous.index_to_node(prev_index); if dep_node.cache_on_disk(tcx) { @@ -1035,7 +1071,7 @@ pub struct TaskDeps { // A data structure that stores Option values as a contiguous // array, using one u32 per entry. struct DepNodeColorMap { - values: IndexVec, + values: IndexVec, } const COMPRESSED_NONE: u32 = 0; @@ -1045,12 +1081,12 @@ const COMPRESSED_FIRST_GREEN: u32 = 2; impl DepNodeColorMap { fn new(size: usize) -> DepNodeColorMap { DepNodeColorMap { - values: IndexVec::from_elem_n(COMPRESSED_NONE, size) + values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(), } } fn get(&self, index: SerializedDepNodeIndex) -> Option { - match self.values[index] { + match self.values[index].load(Ordering::Acquire) { COMPRESSED_NONE => None, COMPRESSED_RED => Some(DepNodeColor::Red), value => Some(DepNodeColor::Green(DepNodeIndex::from_u32( @@ -1059,10 +1095,10 @@ impl DepNodeColorMap { } } - fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) { - self.values[index] = match color { + fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) { + self.values[index].store(match color { DepNodeColor::Red => COMPRESSED_RED, DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN, - } + }, Ordering::Release) } } diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 76d2954b4e35c..ea5350ac97fee 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -19,14 +19,11 @@ impl PreviousDepGraph { } #[inline] - pub fn edges_from(&self, - dep_node: &DepNode) - -> Option<(&[SerializedDepNodeIndex], SerializedDepNodeIndex)> { - self.index - .get(dep_node) - .map(|&node_index| { - (self.data.edge_targets_from(node_index), node_index) - }) + pub fn edge_targets_from( + &self, + dep_node_index: SerializedDepNodeIndex + ) -> &[SerializedDepNodeIndex] { + self.data.edge_targets_from(dep_node_index) } #[inline] diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 869baef1f5afc..d9ca37c937bc7 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -509,6 +509,21 @@ impl<'hir> Map<'hir> { &self.forest.krate.attrs } + pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId) + { + let node_id = self.as_local_node_id(module).unwrap(); + self.read(node_id); + match self.find_entry(node_id).unwrap().node { + Node::Item(&Item { + span, + node: ItemKind::Mod(ref m), + .. + }) => (m, span, node_id), + Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id), + _ => panic!("not a module") + } + } + pub fn visit_item_likes_in_module(&self, module: DefId, visitor: &mut V) where V: ItemLikeVisitor<'hir> { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c8d137a42b2e8..a0bd4f01cd231 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -368,6 +368,12 @@ declare_lint! { report_in_external_macro: true } +declare_lint! { + pub AMBIGUOUS_ASSOCIATED_ITEMS, + Warn, + "ambiguous associated items" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -433,6 +439,7 @@ impl LintPass for HardwiredLints { parser::QUESTION_MARK_MACRO_SEP, parser::ILL_FORMED_ATTRIBUTE_INPUT, DEPRECATED_IN_FUTURE, + AMBIGUOUS_ASSOCIATED_ITEMS, ) } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 1716daaa107c4..a0f7954eb0c55 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -2,6 +2,7 @@ use hir::def::Def; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; +use ty::query::{Providers, queries}; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; @@ -10,10 +11,23 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut visitor = ItemVisitor { - tcx, + for &module in tcx.hir().krate().modules.keys() { + queries::check_mod_intrinsics::ensure(tcx, tcx.hir().local_def_id(module)); + } +} + +fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module( + module_def_id, + &mut ItemVisitor { tcx }.as_deep_visitor() + ); +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_intrinsics, + ..*providers }; - tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); } struct ItemVisitor<'a, 'tcx: 'a> { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a78cf1a471b4b..0a1802a4e12c9 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -100,6 +100,7 @@ use self::VarKind::*; use hir::def::*; use hir::Node; use ty::{self, TyCtxt}; +use ty::query::{Providers, queries}; use lint; use errors::Applicability; use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; @@ -114,8 +115,9 @@ use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; -use hir::{Expr, HirId}; use hir; +use hir::{Expr, HirId}; +use hir::def_id::DefId; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; /// For use with `propagate_through_loop`. @@ -179,11 +181,24 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); } } +fn check_mod_liveness<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx).as_deep_visitor()); +} + pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir().krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor()); + for &module in tcx.hir().krate().modules.keys() { + queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module)); + } tcx.sess.abort_if_errors(); } +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_liveness, + ..*providers + }; +} + impl fmt::Debug for LiveNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ln({})", self.get()) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 42adc6a87fdba..e65beae4ee851 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -6,7 +6,7 @@ use std::str::FromStr; use session::{early_error, early_warn, Session}; use session::search_paths::SearchPath; -use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; +use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use rustc_target::spec::{Target, TargetTriple}; use lint; use middle::cstore; @@ -808,13 +808,16 @@ macro_rules! options { pub const parse_cross_lang_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \ or the path to the linker plugin"); + pub const parse_merge_functions: Option<&str> = + Some("one of: `disabled`, `trampolines`, or `aliases`"); } #[allow(dead_code)] mod $mod_set { use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto}; - use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; + use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use std::path::PathBuf; + use std::str::FromStr; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -1046,6 +1049,14 @@ macro_rules! options { }; true } + + fn parse_merge_functions(slot: &mut Option, v: Option<&str>) -> bool { + match v.and_then(|s| MergeFunctions::from_str(s).ok()) { + Some(mergefunc) => *slot = Some(mergefunc), + _ => return false, + } + true + } } ) } @@ -1376,6 +1387,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries (default: PLT is disabled if full relro is enabled)"), + merge_functions: Option = (None, parse_merge_functions, [TRACKED], + "control the operation of the MergeFunctions LLVM pass, taking + the same values as the target option of the same name"), } pub fn default_lib_output() -> CrateType { @@ -2394,7 +2408,7 @@ mod dep_tracking { use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes, Passes, Sanitizer, LtoCli, CrossLangLto}; use syntax::feature_gate::UnstableFeatures; - use rustc_target::spec::{PanicStrategy, RelroLevel, TargetTriple}; + use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple}; use syntax::edition::Edition; pub trait DepTrackingHash { @@ -2437,12 +2451,14 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option<(String, u64)>); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(CrateType); + impl_dep_tracking_hash_via_hash!(MergeFunctions); impl_dep_tracking_hash_via_hash!(PanicStrategy); impl_dep_tracking_hash_via_hash!(RelroLevel); impl_dep_tracking_hash_via_hash!(Passes); @@ -2528,7 +2544,7 @@ mod tests { use std::iter::FromIterator; use std::path::PathBuf; use super::{Externs, OutputType, OutputTypes}; - use rustc_target::spec::{PanicStrategy, RelroLevel}; + use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; use syntax::edition::{Edition, DEFAULT_EDITION}; use syntax; @@ -3183,6 +3199,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index ca5d1f6bd3203..c20846aebb877 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -109,6 +109,33 @@ impl<'tcx> QueryDescription<'tcx> for queries::check_mod_item_types<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_privacy<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking privacy in {}", key.describe_as_module(tcx)).into() + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_intrinsics<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking intrinsics in {}", key.describe_as_module(tcx)).into() + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_liveness<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking liveness of variables in {}", key.describe_as_module(tcx)).into() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> { fn describe( tcx: TyCtxt<'_, '_, '_>, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 39d76ceed9507..88c20547a2108 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -264,6 +264,12 @@ define_queries! { <'tcx> [] fn check_mod_item_types: CheckModItemTypes(DefId) -> (), + [] fn check_mod_privacy: CheckModPrivacy(DefId) -> (), + + [] fn check_mod_intrinsics: CheckModIntrinsics(DefId) -> (), + + [] fn check_mod_liveness: CheckModLiveness(DefId) -> (), + [] fn collect_mod_item_types: CollectModItemTypes(DefId) -> (), /// Caches CoerceUnsized kinds for impls on custom types. diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 562cd75a75ff4..5b7cb55b7bc3a 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,7 +2,7 @@ //! that generate the actual methods on tcx which find and execute the //! provider, manage the caches, and so forth. -use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor}; +use dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; use errors::DiagnosticBuilder; use errors::Level; use errors::Diagnostic; @@ -335,40 +335,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { eprintln!("end of query stack"); } - /// Try to read a node index for the node dep_node. - /// A node will have an index, when it's already been marked green, or when we can mark it - /// green. This function will mark the current task as a reader of the specified node, when - /// a node index can be found for that node. - pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option { - match self.dep_graph.node_color(dep_node) { - Some(DepNodeColor::Green(dep_node_index)) => { - self.dep_graph.read_index(dep_node_index); - Some(dep_node_index) - } - Some(DepNodeColor::Red) => { - None - } - None => { - // try_mark_green (called below) will panic when full incremental - // compilation is disabled. If that's the case, we can't try to mark nodes - // as green anyway, so we can safely return None here. - if !self.dep_graph.is_fully_enabled() { - return None; - } - match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) { - Some(dep_node_index) => { - debug_assert!(self.dep_graph.is_green(&dep_node)); - self.dep_graph.read_index(dep_node_index); - Some(dep_node_index) - } - None => { - None - } - } - } - } - } - #[inline(never)] fn try_get_with>( self, @@ -435,10 +401,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } if !dep_node.kind.is_input() { - if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) { + if let Some((prev_dep_node_index, + dep_node_index)) = self.dep_graph.try_mark_green_and_read(self, + &dep_node) { return Ok(self.load_from_disk_and_cache_in_memory::( key, job, + prev_dep_node_index, dep_node_index, &dep_node )) @@ -454,6 +423,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, key: Q::Key, job: JobOwner<'a, 'gcx, Q>, + prev_dep_node_index: SerializedDepNodeIndex, dep_node_index: DepNodeIndex, dep_node: &DepNode ) -> Q::Value @@ -466,10 +436,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // First we try to load the result from the on-disk cache let result = if Q::cache_on_disk(key.clone()) && self.sess.opts.debugging_opts.incremental_queries { - let prev_dep_node_index = - self.dep_graph.prev_dep_node_index_of(dep_node); - let result = Q::try_load_from_disk(self.global_tcx(), - prev_dep_node_index); + let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); // We always expect to find a cached result for things that // can be forced from DepNode. @@ -624,7 +591,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Ensuring an "input" or anonymous query makes no sense assert!(!dep_node.kind.is_anon()); assert!(!dep_node.kind.is_input()); - if self.try_mark_green_and_read(&dep_node).is_none() { + if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. // Either way, we can't call `dep_graph.read()` as we don't have the @@ -1281,6 +1248,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); } DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); } DepKind::CheckModItemTypes => { force!(check_mod_item_types, def_id!()); } + DepKind::CheckModPrivacy => { force!(check_mod_privacy, def_id!()); } + DepKind::CheckModIntrinsics => { force!(check_mod_intrinsics, def_id!()); } + DepKind::CheckModLiveness => { force!(check_mod_liveness, def_id!()); } DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); } DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index ad9ebbcde8ab9..dc70ebcf943a5 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -3,6 +3,7 @@ use back::write::create_target_machine; use llvm; use rustc::session::Session; use rustc::session::config::PrintRequest; +use rustc_target::spec::MergeFunctions; use libc::c_int; use std::ffi::CString; use syntax::feature_gate::UnstableFeatures; @@ -61,7 +62,14 @@ unsafe fn configure_llvm(sess: &Session) { add("-disable-preinline"); } if llvm::LLVMRustIsRustLLVM() { - add("-mergefunc-use-aliases"); + match sess.opts.debugging_opts.merge_functions + .unwrap_or(sess.target.target.options.merge_functions) { + MergeFunctions::Disabled | + MergeFunctions::Trampolines => {} + MergeFunctions::Aliases => { + add("-mergefunc-use-aliases"); + } + } } // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index fb3e7ea696363..39bdc70f8322e 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -24,6 +24,7 @@ use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; use rustc_errors::emitter::{Emitter}; +use rustc_target::spec::MergeFunctions; use syntax::attr; use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; @@ -152,8 +153,24 @@ impl ModuleConfig { sess.opts.optimize == config::OptLevel::Aggressive && !sess.target.target.options.is_like_emscripten; - self.merge_functions = sess.opts.optimize == config::OptLevel::Default || - sess.opts.optimize == config::OptLevel::Aggressive; + // Some targets (namely, NVPTX) interact badly with the MergeFunctions + // pass. This is because MergeFunctions can generate new function calls + // which may interfere with the target calling convention; e.g. for the + // NVPTX target, PTX kernels should not call other PTX kernels. + // MergeFunctions can also be configured to generate aliases instead, + // but aliases are not supported by some backends (again, NVPTX). + // Therefore, allow targets to opt out of the MergeFunctions pass, + // but otherwise keep the pass enabled (at O2 and O3) since it can be + // useful for reducing code size. + self.merge_functions = match sess.opts.debugging_opts.merge_functions + .unwrap_or(sess.target.target.options.merge_functions) { + MergeFunctions::Disabled => false, + MergeFunctions::Trampolines | + MergeFunctions::Aliases => { + sess.opts.optimize == config::OptLevel::Default || + sess.opts.optimize == config::OptLevel::Aggressive + } + }; } pub fn bitcode_needed(&self) -> bool { diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f9f94f0be7b9a..0253eef4dfa3a 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -70,6 +70,7 @@ cfg_if! { pub struct Atomic(Cell); impl Atomic { + #[inline] pub fn new(v: T) -> Self { Atomic(Cell::new(v)) } @@ -80,10 +81,12 @@ cfg_if! { self.0.into_inner() } + #[inline] pub fn load(&self, _: Ordering) -> T { self.0.get() } + #[inline] pub fn store(&self, val: T, _: Ordering) { self.0.set(val) } @@ -118,6 +121,7 @@ cfg_if! { pub type AtomicUsize = Atomic; pub type AtomicBool = Atomic; + pub type AtomicU32 = Atomic; pub type AtomicU64 = Atomic; pub use self::serial_join as join; @@ -223,7 +227,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64}; + pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ecb8ef112c9e..15cb5b032ade4 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1159,6 +1159,8 @@ pub fn default_provide(providers: &mut ty::query::Providers) { ty::provide(providers); traits::provide(providers); stability::provide(providers); + middle::intrinsicck::provide(providers); + middle::liveness::provide(providers); reachable::provide(providers); rustc_passes::provide(providers); rustc_traits::provide(providers); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2d764d11c66aa..71c859d8dbea7 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -341,6 +341,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #57571 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS), + reference: "issue #57644 ", + edition: None, + }, ]); // Register renamed and removed lints. diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 77c8a896b04ed..2a858bdd601ae 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -505,7 +505,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) { let mut diag = infcx.tcx.sess.struct_span_err( span, - "unsatisfied lifetime constraints", // FIXME + "lifetime may not live long enough" ); let counter = &mut 1; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4890369e13f20..698037e237101 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -22,12 +22,12 @@ use rustc::lint; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt, Ty, TraitRef, TypeFoldable, GenericParamDefKind}; use rustc::ty::fold::TypeVisitor; -use rustc::ty::query::Providers; +use rustc::ty::query::{Providers, queries}; use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeSet; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use syntax::ast::{self, CRATE_NODE_ID, Ident}; +use syntax::ast::{self, DUMMY_NODE_ID, Ident}; use syntax::attr; use syntax::symbol::keywords; use syntax_pos::Span; @@ -782,6 +782,11 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { NestedVisitorMap::All(&self.tcx.hir()) } + fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { + // Don't visit nested modules, since we run a separate visitor walk + // for each module in `privacy_access_levels` + } + fn visit_nested_body(&mut self, body: hir::BodyId) { let orig_tables = mem::replace(&mut self.tables, self.tcx.body_tables(body)); let body = self.tcx.hir().body(body); @@ -917,6 +922,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { NestedVisitorMap::All(&self.tcx.hir()) } + fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { + // Don't visit nested modules, since we run a separate visitor walk + // for each module in `privacy_access_levels` + } + fn visit_nested_body(&mut self, body: hir::BodyId) { let orig_tables = mem::replace(&mut self.tables, self.tcx.body_tables(body)); let orig_in_body = mem::replace(&mut self.in_body, true); @@ -1659,6 +1669,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> pub fn provide(providers: &mut Providers) { *providers = Providers { privacy_access_levels, + check_mod_privacy, ..*providers }; } @@ -1667,34 +1678,43 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { tcx.privacy_access_levels(LOCAL_CRATE) } -fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - krate: CrateNum) - -> Lrc { - assert_eq!(krate, LOCAL_CRATE); - - let krate = tcx.hir().krate(); +fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, tables: &empty_tables, - current_item: CRATE_NODE_ID, + current_item: DUMMY_NODE_ID, empty_tables: &empty_tables, }; - intravisit::walk_crate(&mut visitor, krate); + let (module, span, node_id) = tcx.hir().get_module(module_def_id); + intravisit::walk_mod(&mut visitor, module, node_id); // Check privacy of explicitly written types and traits as well as // inferred types of expressions and patterns. let mut visitor = TypePrivacyVisitor { tcx, tables: &empty_tables, - current_item: DefId::local(CRATE_DEF_INDEX), + current_item: module_def_id, in_body: false, - span: krate.span, + span, empty_tables: &empty_tables, }; - intravisit::walk_crate(&mut visitor, krate); + intravisit::walk_mod(&mut visitor, module, node_id); +} + +fn privacy_access_levels<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + krate: CrateNum, +) -> Lrc { + assert_eq!(krate, LOCAL_CRATE); + + let krate = tcx.hir().krate(); + + for &module in krate.modules.keys() { + queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); + } // Build up a set of all exported items in the AST. This is a set of all // items which are reachable from external crates based on visibility. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b41193723069c..c11a2cd01c167 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3318,7 +3318,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(_)) => { @@ -3330,13 +3335,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/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f42b0a1c3c958..3a21ca19b176b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -217,6 +217,46 @@ impl ToJson for RelroLevel { } } +#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] +pub enum MergeFunctions { + Disabled, + Trampolines, + Aliases +} + +impl MergeFunctions { + pub fn desc(&self) -> &str { + match *self { + MergeFunctions::Disabled => "disabled", + MergeFunctions::Trampolines => "trampolines", + MergeFunctions::Aliases => "aliases", + } + } +} + +impl FromStr for MergeFunctions { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "disabled" => Ok(MergeFunctions::Disabled), + "trampolines" => Ok(MergeFunctions::Trampolines), + "aliases" => Ok(MergeFunctions::Aliases), + _ => Err(()), + } + } +} + +impl ToJson for MergeFunctions { + fn to_json(&self) -> Json { + match *self { + MergeFunctions::Disabled => "disabled".to_json(), + MergeFunctions::Trampolines => "trampolines".to_json(), + MergeFunctions::Aliases => "aliases".to_json(), + } + } +} + pub type LinkArgs = BTreeMap>; pub type TargetResult = Result; @@ -690,7 +730,15 @@ pub struct TargetOptions { /// If set, have the linker export exactly these symbols, instead of using /// the usual logic to figure this out from the crate itself. - pub override_export_symbols: Option> + pub override_export_symbols: Option>, + + /// Determines how or whether the MergeFunctions LLVM pass should run for + /// this target. Either "disabled", "trampolines", or "aliases". + /// The MergeFunctions pass is generally useful, but some targets may need + /// to opt out. The default is "aliases". + /// + /// Workaround for: https://github.com/rust-lang/rust/issues/57356 + pub merge_functions: MergeFunctions } impl Default for TargetOptions { @@ -773,6 +821,7 @@ impl Default for TargetOptions { requires_uwtable: false, simd_types_indirect: true, override_export_symbols: None, + merge_functions: MergeFunctions::Aliases, } } } @@ -875,6 +924,19 @@ impl Target { .map(|o| o.as_u64() .map(|s| base.options.$key_name = Some(s))); } ); + ($key_name:ident, MergeFunctions) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { + match s.parse::() { + Ok(mergefunc) => base.options.$key_name = mergefunc, + _ => return Some(Err(format!("'{}' is not a valid value for \ + merge-functions. Use 'disabled', \ + 'trampolines', or 'aliases'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); ($key_name:ident, PanicStrategy) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { @@ -1064,6 +1126,7 @@ impl Target { key!(requires_uwtable, bool); key!(simd_types_indirect, bool); key!(override_export_symbols, opt_list); + key!(merge_functions, MergeFunctions)?; if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1275,6 +1338,7 @@ impl ToJson for Target { target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); target_option_val!(override_export_symbols); + target_option_val!(merge_functions); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8e5eaa18b9de0..534279e981d62 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -10,6 +10,7 @@ use hir::HirVec; use lint; use middle::resolve_lifetime as rl; use namespace::Namespace; +use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; @@ -1278,29 +1279,50 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } // Create a type from a path to an associated type. - // For a path `A::B::C::D`, `ty` and `ty_path_def` are the type and def for `A::B::C` + // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C` // and item_segment is the path segment for `D`. We return a type and a def for // the whole path. - // Will fail except for `T::A` and `Self::A`; i.e., if `ty`/`ty_path_def` are not a type + // Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type // parameter or `Self`. - pub fn associated_path_def_to_ty(&self, - ref_id: ast::NodeId, - span: Span, - ty: Ty<'tcx>, - ty_path_def: Def, - item_segment: &hir::PathSegment) - -> (Ty<'tcx>, Def) - { + pub fn associated_path_to_ty( + &self, + ref_id: ast::NodeId, + span: Span, + qself_ty: Ty<'tcx>, + qself_def: Def, + assoc_segment: &hir::PathSegment, + permit_variants: bool, + ) -> (Ty<'tcx>, Def) { let tcx = self.tcx(); - let assoc_name = item_segment.ident; + let assoc_ident = assoc_segment.ident; - debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name); + debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident); - self.prohibit_generics(slice::from_ref(item_segment)); + self.prohibit_generics(slice::from_ref(assoc_segment)); + + // Check if we have an enum variant. + let mut variant_resolution = None; + if let ty::Adt(adt_def, _) = qself_ty.sty { + if adt_def.is_enum() { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + let def = Def::Variant(variant_def.did); + if permit_variants { + check_type_alias_enum_variants_enabled(tcx, span); + tcx.check_stability(variant_def.did, Some(ref_id), span); + return (qself_ty, def); + } else { + variant_resolution = Some(def); + } + } + } + } // Find the type of the associated item, and the trait where the associated // item is declared. - let bound = match (&ty.sty, ty_path_def) { + let bound = match (&qself_ty.sty, qself_def) { (_, Def::SelfTy(Some(_), Some(impl_def_id))) => { // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. @@ -1313,77 +1335,61 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }; let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref)) - .filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name)); + .filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident)); - match self.one_bound_for_assoc_type(candidates, "Self", assoc_name, span) { + match self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span) { Ok(bound) => bound, Err(ErrorReported) => return (tcx.types.err, Def::Err), } } (&ty::Param(_), Def::SelfTy(Some(param_did), None)) | (&ty::Param(_), Def::TyParam(param_did)) => { - match self.find_bound_for_assoc_item(param_did, assoc_name, span) { + match self.find_bound_for_assoc_item(param_did, assoc_ident, span) { Ok(bound) => bound, Err(ErrorReported) => return (tcx.types.err, Def::Err), } } - (&ty::Adt(adt_def, _substs), Def::Enum(_did)) => { - let ty_str = ty.to_string(); - // Incorrect enum variant. - let mut err = tcx.sess.struct_span_err( - span, - &format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str), - ); - // Check if it was a typo. - let input = adt_def.variants.iter().map(|variant| &variant.ident.name); - if let Some(suggested_name) = find_best_match_for_name( - input, - &assoc_name.as_str(), - None, - ) { - err.span_suggestion_with_applicability( + _ => { + if variant_resolution.is_some() { + // Variant in type position + let msg = format!("expected type, found variant `{}`", assoc_ident); + tcx.sess.span_err(span, &msg); + } else if qself_ty.is_enum() { + // Report as incorrect enum variant rather than ambiguous type. + let mut err = tcx.sess.struct_span_err( span, - "did you mean", - format!("{}::{}", ty_str, suggested_name.to_string()), - Applicability::MaybeIncorrect, + &format!("no variant `{}` on enum `{}`", &assoc_ident.as_str(), qself_ty), ); - } else { - err.span_label(span, "unknown variant"); - } - err.emit(); - return (tcx.types.err, Def::Err); - } - _ => { - // Check if we have an enum variant. - match ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::Variant(variant_def.did); - tcx.check_stability(def.def_id(), Some(ref_id), span); - return (ty, def); - } - }, - _ => (), - } - - // Don't print `TyErr` to the user. - if !ty.references_error() { + // Check if it was a typo. + let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT"); + if let Some(suggested_name) = find_best_match_for_name( + adt_def.variants.iter().map(|variant| &variant.ident.name), + &assoc_ident.as_str(), + None, + ) { + err.span_suggestion_with_applicability( + span, + "did you mean", + format!("{}::{}", qself_ty, suggested_name), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(span, "unknown variant"); + } + err.emit(); + } else if !qself_ty.references_error() { + // Don't print `TyErr` to the user. self.report_ambiguous_associated_type(span, - &ty.to_string(), + &qself_ty.to_string(), "Trait", - &assoc_name.as_str()); + &assoc_ident.as_str()); } return (tcx.types.err, Def::Err); } }; let trait_did = bound.def_id(); - let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_name, trait_did, ref_id); + let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, ref_id); let item = tcx.associated_items(trait_did).find(|i| { Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident @@ -1394,11 +1400,35 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let def = Def::AssociatedTy(item.def_id); if !item.vis.is_accessible_from(def_scope, tcx) { - let msg = format!("{} `{}` is private", def.kind_name(), assoc_name); + let msg = format!("{} `{}` is private", def.kind_name(), assoc_ident); tcx.sess.span_err(span, &msg); } tcx.check_stability(item.def_id, Some(ref_id), span); + if let Some(variant_def) = variant_resolution { + let mut err = tcx.struct_span_lint_node( + AMBIGUOUS_ASSOCIATED_ITEMS, + ref_id, + span, + "ambiguous associated item", + ); + + let mut could_refer_to = |def: Def, also| { + let note_msg = format!("`{}` could{} refer to {} defined here", + assoc_ident, also, def.kind_name()); + err.span_note(tcx.def_span(def.def_id()), ¬e_msg); + }; + could_refer_to(variant_def, ""); + could_refer_to(def, " also"); + + err.span_suggestion_with_applicability( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, "Trait", assoc_ident), + Applicability::HasPlaceholders, + ).emit(); + } + (ty, def) } @@ -1773,7 +1803,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { Def::Err }; - self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 + self.associated_path_to_ty(ast_ty.id, ast_ty.span, ty, def, segment, false).0 } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.id); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 02687df6a94fc..e71dc019471bd 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -408,45 +408,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; - let mode = probe::Mode::Path; - match self.probe_for_name(span, mode, method_name, IsSuggestion(false), - self_ty, expr_id, ProbeScope::TraitsInScope) { - Ok(pick) => { - debug!("resolve_ufcs: pick={:?}", pick); - if let Some(import_id) = pick.import_id { - let import_def_id = tcx.hir().local_def_id(import_id); - debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); - Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) - .unwrap().insert(import_def_id); + // Check if we have an enum variant. + if let ty::Adt(adt_def, _) = self_ty.sty { + if adt_def.is_enum() { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(method_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); + tcx.check_stability(def.def_id(), Some(expr_id), span); + return Ok(def); } - - let def = pick.item.def(); - debug!("resolve_ufcs: def={:?}", def); - tcx.check_stability(def.def_id(), Some(expr_id), span); - - Ok(def) } - Err(err) => { - // Check if we have an enum variant. - match self_ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(method_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); - tcx.check_stability(def.def_id(), Some(expr_id), span); - return Ok(def); - } - }, - _ => (), - } + } - Err(err) - } + let pick = self.probe_for_name(span, probe::Mode::Path, method_name, IsSuggestion(false), + self_ty, expr_id, ProbeScope::TraitsInScope)?; + debug!("resolve_ufcs: pick={:?}", pick); + if let Some(import_id) = pick.import_id { + let import_def_id = tcx.hir().local_def_id(import_id); + debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); + Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) + .unwrap().insert(import_def_id); } + + let def = pick.item.def(); + debug!("resolve_ufcs: def={:?}", def); + tcx.check_stability(def.def_id(), Some(expr_id), span); + Ok(def) } /// Find item with name `item_name` defined in impl/trait `def_id` diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..22300f2ae11ed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4724,8 +4724,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { Def::Err }; - let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span, - ty, def, segment); + let (ty, def) = AstConv::associated_path_to_ty(self, node_id, path_span, + ty, def, segment, true); // Write back the new resolution. let hir_id = self.tcx.hir().node_to_hir_id(node_id); 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(); 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; } 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; 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 /// diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 41f1ac867ed15..83db3f347a761 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -286,6 +286,7 @@ #![feature(staged_api)] #![feature(stmt_expr_attributes)] #![feature(str_internals)] +#![feature(renamed_spin_loop)] #![feature(rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 24202ca8fbdc0..9a129e7e8fcd8 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -435,7 +435,8 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { match *seq_tt { TokenTree::MetaVarDecl(_, _, id) => id.name == "vis", TokenTree::Sequence(_, ref sub_seq) => - sub_seq.op == quoted::KleeneOp::ZeroOrMore, + sub_seq.op == quoted::KleeneOp::ZeroOrMore + || sub_seq.op == quoted::KleeneOp::ZeroOrOne, _ => false, } }) { @@ -543,7 +544,10 @@ impl FirstSets { } // Reverse scan: Sequence comes before `first`. - if subfirst.maybe_empty || seq_rep.op == quoted::KleeneOp::ZeroOrMore { + if subfirst.maybe_empty + || seq_rep.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.op == quoted::KleeneOp::ZeroOrOne + { // If sequence is potentially empty, then // union them (preserving first emptiness). first.add_all(&TokenSet { maybe_empty: true, ..subfirst }); @@ -591,8 +595,10 @@ impl FirstSets { assert!(first.maybe_empty); first.add_all(subfirst); - if subfirst.maybe_empty || - seq_rep.op == quoted::KleeneOp::ZeroOrMore { + if subfirst.maybe_empty + || seq_rep.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.op == quoted::KleeneOp::ZeroOrOne + { // continue scanning for more first // tokens, but also make sure we // restore empty-tracking state 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`. diff --git a/src/test/ui/issues/issue-5067.rs b/src/test/ui/issues/issue-5067.rs index 526a68311462e..616fd09907a2b 100644 --- a/src/test/ui/issues/issue-5067.rs +++ b/src/test/ui/issues/issue-5067.rs @@ -1,37 +1,59 @@ #![allow(unused_macros)] +// Tests that repetition matchers cannot match the empty token tree (since that would be +// ambiguous). + +// edition:2018 + macro_rules! foo { ( $()* ) => {}; //~^ ERROR repetition matches empty token tree ( $()+ ) => {}; //~^ ERROR repetition matches empty token tree - + ( $()? ) => {}; + //~^ ERROR repetition matches empty token tree ( $(),* ) => {}; // PASS ( $(),+ ) => {}; // PASS - + // `?` cannot have a separator... ( [$()*] ) => {}; //~^ ERROR repetition matches empty token tree ( [$()+] ) => {}; //~^ ERROR repetition matches empty token tree - + ( [$()?] ) => {}; + //~^ ERROR repetition matches empty token tree ( [$(),*] ) => {}; // PASS ( [$(),+] ) => {}; // PASS - + // `?` cannot have a separator... ( $($()* $(),* $(a)* $(a),* )* ) => {}; //~^ ERROR repetition matches empty token tree ( $($()* $(),* $(a)* $(a),* )+ ) => {}; //~^ ERROR repetition matches empty token tree - + ( $($()* $(),* $(a)* $(a),* )? ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )* ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )+ ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )? ) => {}; + //~^ ERROR repetition matches empty token tree ( $(a $(),* $(a)* $(a),* )* ) => {}; // PASS ( $($(a)+ $(),* $(a)* $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)* $(a),* )? ) => {}; // PASS + + ( $(a $(),* $(a)? $(a),* )* ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )? ) => {}; // PASS ( $(a $()+)* ) => {}; //~^ ERROR repetition matches empty token tree ( $(a $()*)+ ) => {}; //~^ ERROR repetition matches empty token tree + ( $(a $()+)? ) => {}; + //~^ ERROR repetition matches empty token tree + ( $(a $()?)+ ) => {}; + //~^ ERROR repetition matches empty token tree } - // --- Original Issue --- // macro_rules! make_vec { @@ -43,11 +65,10 @@ fn main() { let _ = make_vec![a 1, a 2, a 3]; } - // --- Minified Issue --- // macro_rules! m { - ( $()* ) => {} + ( $()* ) => {}; //~^ ERROR repetition matches empty token tree } diff --git a/src/test/ui/issues/issue-5067.stderr b/src/test/ui/issues/issue-5067.stderr index 433b7c8c04907..7ffc6071407c5 100644 --- a/src/test/ui/issues/issue-5067.stderr +++ b/src/test/ui/issues/issue-5067.stderr @@ -1,62 +1,110 @@ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:4:8 + --> $DIR/issue-5067.rs:9:8 | LL | ( $()* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:6:8 + --> $DIR/issue-5067.rs:11:8 | LL | ( $()+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:12:9 + --> $DIR/issue-5067.rs:13:8 + | +LL | ( $()? ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:18:9 | LL | ( [$()*] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:14:9 + --> $DIR/issue-5067.rs:20:9 | LL | ( [$()+] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:20:8 + --> $DIR/issue-5067.rs:22:9 + | +LL | ( [$()?] ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:27:8 | LL | ( $($()* $(),* $(a)* $(a),* )* ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:22:8 + --> $DIR/issue-5067.rs:29:8 | LL | ( $($()* $(),* $(a)* $(a),* )+ ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:28:12 + --> $DIR/issue-5067.rs:31:8 + | +LL | ( $($()* $(),* $(a)* $(a),* )? ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:33:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )* ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:35:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )+ ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:37:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )? ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:47:12 | LL | ( $(a $()+)* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:30:12 + --> $DIR/issue-5067.rs:49:12 | LL | ( $(a $()*)+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:38:18 + --> $DIR/issue-5067.rs:51:12 + | +LL | ( $(a $()+)? ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:53:12 + | +LL | ( $(a $()?)+ ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:60:18 | LL | (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); | ^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:50:8 + --> $DIR/issue-5067.rs:71:8 | -LL | ( $()* ) => {} +LL | ( $()* ) => {}; | ^^ -error: aborting due to 10 previous errors +error: aborting due to 18 previous errors diff --git a/src/test/ui/issues/issue-57597.rs b/src/test/ui/issues/issue-57597.rs new file mode 100644 index 0000000000000..ebeb3fe07adb4 --- /dev/null +++ b/src/test/ui/issues/issue-57597.rs @@ -0,0 +1,80 @@ +// Regression test for #57597. +// +// Make sure that nested matchers work correctly rather than causing an infinite loop or crash. + +// edition:2018 + +macro_rules! foo1 { + ($($($i:ident)?)+) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo2 { + ($($($i:ident)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo3 { + ($($($i:ident)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo4 { + ($($($($i:ident)?)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo5 { + ($($($($i:ident)*)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo6 { + ($($($($i:ident)?)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo7 { + ($($($($i:ident)?)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo8 { + ($($($($i:ident)*)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo9 { + ($($($($i:ident)?)*)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo10 { + ($($($($i:ident)?)*)+) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo11 { + ($($($($i:ident)+)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo12 { + ($($($($i:ident)+)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +fn main() { + foo1!(); + foo2!(); + foo3!(); + foo4!(); + foo5!(); + foo6!(); + foo7!(); + foo8!(); + foo9!(); + foo10!(); + foo11!(); + foo12!(); +} diff --git a/src/test/ui/issues/issue-57597.stderr b/src/test/ui/issues/issue-57597.stderr new file mode 100644 index 0000000000000..0a02ac8c499b6 --- /dev/null +++ b/src/test/ui/issues/issue-57597.stderr @@ -0,0 +1,74 @@ +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:8:7 + | +LL | ($($($i:ident)?)+) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:13:7 + | +LL | ($($($i:ident)?)*) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:18:7 + | +LL | ($($($i:ident)?)?) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:23:7 + | +LL | ($($($($i:ident)?)?)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:28:7 + | +LL | ($($($($i:ident)*)?)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:33:7 + | +LL | ($($($($i:ident)?)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:38:7 + | +LL | ($($($($i:ident)?)?)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:43:7 + | +LL | ($($($($i:ident)*)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:48:7 + | +LL | ($($($($i:ident)?)*)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:53:7 + | +LL | ($($($($i:ident)?)*)+) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:58:7 + | +LL | ($($($($i:ident)+)?)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:63:7 + | +LL | ($($($($i:ident)+)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 66f8791bfcb65..8e407070342cf 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -9,7 +9,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) i32)) ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/escape-argument-callee.rs:26:45 | LL | let mut closure = expect_sig(|p, y| *p = y); diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 5594271a21d60..55e4573e60bbb 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -16,7 +16,7 @@ LL | | }, = note: late-bound region is '_#5r = note: late-bound region is '_#6r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs index 7296bbad5189f..1c409a14b7280 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs @@ -41,10 +41,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3 #[rustc_regions] fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - // Only works if 'x: 'y: demand_y(x, y, x.get()) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index a827b85318792..5863b9bc84094 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -3,10 +3,9 @@ note: External requirements | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { | _______________________________________________^ -LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | }); | |_____^ | @@ -24,17 +23,17 @@ note: No external requirements | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | LL | | // Only works if 'x: 'y: -... | +LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR lifetime may not live long enough LL | | }); LL | | } | |_^ | = note: defining type: DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]) with substs [] -error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-ref.rs:46:9 +error: lifetime may not live long enough + --> $DIR/propagate-approximated-ref.rs:45:9 | LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs index eb6159c14e1e2..233a5dcab08ab 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs @@ -34,10 +34,9 @@ fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: #[rustc_regions] fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - // Only works if 'x: 'y: demand_y(outlives1, outlives2, x.get()) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index 1f9d1d7fb5038..b6d9d8529cf5c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -3,10 +3,9 @@ note: External requirements | LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { | _____________________________________________^ -LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(outlives1, outlives2, x.get()) -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | }); | |_____^ | @@ -24,17 +23,17 @@ note: No external requirements | LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { -LL | | LL | | // Only works if 'x: 'y: -... | +LL | | demand_y(outlives1, outlives2, x.get()) +LL | | //~^ ERROR lifetime may not live long enough LL | | }); LL | | } | |_^ | = note: defining type: DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]) with substs [] -error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-val.rs:39:9 +error: lifetime may not live long enough + --> $DIR/propagate-approximated-val.rs:38:9 | LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 1a8988f365d0c..93eb93bdc0638 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -16,7 +16,7 @@ LL | | }); = note: late-bound region is '_#2r = note: late-bound region is '_#3r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index d0492bdc573c3..c7809de88b922 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -16,7 +16,7 @@ LL | | }); = note: late-bound region is '_#3r = note: late-bound region is '_#4r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr index 0bc05922235cf..d0a24a267fd4f 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/region-lbr-named-does-not-outlive-static.rs:9:5 | LL | fn foo<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs index 1be27aebb3f0d..4d864c6e58868 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs +++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs @@ -7,7 +7,7 @@ fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { &*x - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr index 2332332f5b8c0..6dc98a944086f 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/region-lbr1-does-not-outlive-ebr2.rs:9:5 | LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 26243f9b821d3..4a035d0c9cd83 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -9,7 +9,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32 ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/return-wrong-bound-region.rs:11:23 | LL | expect_sig(|a, b| b); // ought to return `a` diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr index 913effa1c93c0..7cb5eb736c0e3 100644 --- a/src/test/ui/nll/issue-48238.stderr +++ b/src/test/ui/nll/issue-48238.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-48238.rs:11:13 | LL | move || use_val(&orig); //~ ERROR diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index fa893df3e15ad..229bb1777cc5e 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-50716.rs:16:14 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) diff --git a/src/test/ui/nll/issue-52113.rs b/src/test/ui/nll/issue-52113.rs index 8428e55eeb65b..795f4f426ffff 100644 --- a/src/test/ui/nll/issue-52113.rs +++ b/src/test/ui/nll/issue-52113.rs @@ -3,8 +3,8 @@ #![allow(warnings)] #![feature(nll)] -trait Bazinga { } -impl Bazinga for F { } +trait Bazinga {} +impl Bazinga for F {} fn produce1<'a>(data: &'a u32) -> impl Bazinga + 'a { let x = move || { @@ -21,7 +21,6 @@ fn produce2<'a>(data: &'a mut Vec<&'a u32>, value: &'a u32) -> impl Bazinga + 'a x } - fn produce3<'a, 'b: 'a>(data: &'a mut Vec<&'a u32>, value: &'b u32) -> impl Bazinga + 'a { let x = move || { let value: &'a u32 = value; @@ -35,7 +34,7 @@ fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl B let value: &'a u32 = value; data.push(value); }; - x //~ ERROR unsatisfied lifetime constraints + x //~ ERROR lifetime may not live long enough } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/issue-52113.stderr b/src/test/ui/nll/issue-52113.stderr index 873612d7657d6..ceae16185bbb1 100644 --- a/src/test/ui/nll/issue-52113.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -1,12 +1,12 @@ -error: unsatisfied lifetime constraints - --> $DIR/issue-52113.rs:38:5 +error: lifetime may not live long enough + --> $DIR/issue-52113.rs:37:5 | LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here ... -LL | x //~ ERROR unsatisfied lifetime constraints +LL | x //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'a` must outlive `'b` error: aborting due to previous error diff --git a/src/test/ui/nll/issue-52742.rs b/src/test/ui/nll/issue-52742.rs index d8251cb20640a..150e67fe09481 100644 --- a/src/test/ui/nll/issue-52742.rs +++ b/src/test/ui/nll/issue-52742.rs @@ -7,14 +7,14 @@ struct Foo<'a, 'b> { } struct Bar<'b> { - z: &'b u32 + z: &'b u32, } impl Foo<'_, '_> { fn take_bar(&mut self, b: Bar<'_>) { self.y = b.z - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr index f733702cd8b4b..6b25296c4bda1 100644 --- a/src/test/ui/nll/issue-52742.stderr +++ b/src/test/ui/nll/issue-52742.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-52742.rs:15:9 | LL | fn take_bar(&mut self, b: Bar<'_>) { diff --git a/src/test/ui/nll/issue-55394.rs b/src/test/ui/nll/issue-55394.rs index 4a83c33239c19..deb1034525edb 100644 --- a/src/test/ui/nll/issue-55394.rs +++ b/src/test/ui/nll/issue-55394.rs @@ -8,7 +8,7 @@ struct Foo<'s> { impl Foo<'_> { fn new(bar: &mut Bar) -> Self { - Foo { bar } //~ ERROR unsatisfied lifetime constraints + Foo { bar } //~ERROR lifetime may not live long enough } } diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index a4c5160c7b326..bcdd78248eb4b 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -1,11 +1,11 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-55394.rs:11:9 | LL | fn new(bar: &mut Bar) -> Self { | - ---- return type is Foo<'2> | | | let's call the lifetime of this reference `'1` -LL | Foo { bar } //~ ERROR unsatisfied lifetime constraints +LL | Foo { bar } //~ERROR lifetime may not live long enough | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` error: aborting due to previous error diff --git a/src/test/ui/nll/mir_check_cast_closure.rs b/src/test/ui/nll/mir_check_cast_closure.rs index 5298e840defd5..0619ff37d972b 100644 --- a/src/test/ui/nll/mir_check_cast_closure.rs +++ b/src/test/ui/nll/mir_check_cast_closure.rs @@ -5,7 +5,7 @@ fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { let g: fn(_, _) -> _ = |_x, y| y; g - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_closure.stderr b/src/test/ui/nll/mir_check_cast_closure.stderr index b88353371dfbc..e14cb074c81f8 100644 --- a/src/test/ui/nll/mir_check_cast_closure.stderr +++ b/src/test/ui/nll/mir_check_cast_closure.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_closure.rs:7:5 | LL | fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { diff --git a/src/test/ui/nll/mir_check_cast_reify.rs b/src/test/ui/nll/mir_check_cast_reify.rs index b0ad8e34b17b5..be12e313b42e6 100644 --- a/src/test/ui/nll/mir_check_cast_reify.rs +++ b/src/test/ui/nll/mir_check_cast_reify.rs @@ -35,7 +35,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 { // as part of checking the `ReifyFnPointer`. let f: fn(_) -> _ = foo; f(x) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_reify.stderr b/src/test/ui/nll/mir_check_cast_reify.stderr index 2585486f12702..4e8eec330a579 100644 --- a/src/test/ui/nll/mir_check_cast_reify.stderr +++ b/src/test/ui/nll/mir_check_cast_reify.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_reify.rs:37:5 | LL | fn bar<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs index 29fbf462b30a9..9df9c05748924 100644 --- a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs +++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs @@ -7,7 +7,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { // in `g`. These are related via the `UnsafeFnPointer` cast. let g: unsafe fn(_) -> _ = f; unsafe { g(input) } - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr index e7b945a51caaf..52959850a3332 100644 --- a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr +++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_unsafe_fn.rs:9:14 | LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/mir_check_cast_unsize.rs b/src/test/ui/nll/mir_check_cast_unsize.rs index e98d5e14fca62..d15c4e4f46722 100644 --- a/src/test/ui/nll/mir_check_cast_unsize.rs +++ b/src/test/ui/nll/mir_check_cast_unsize.rs @@ -6,7 +6,7 @@ use std::fmt::Debug; fn bar<'a>(x: &'a u32) -> &'static dyn Debug { x - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_unsize.stderr b/src/test/ui/nll/mir_check_cast_unsize.stderr index 189bb2dff5275..364d6c17ea7f6 100644 --- a/src/test/ui/nll/mir_check_cast_unsize.stderr +++ b/src/test/ui/nll/mir_check_cast_unsize.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_unsize.rs:8:5 | LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug { diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index f2bfdaecdaf27..e8283d1ab5da2 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -40,7 +40,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`... -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:45:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -94,7 +94,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:56:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index fc59100d1873a..78a8c803dd972 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -31,7 +31,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:37:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -76,7 +76,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:47:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs index 25877e6665c40..20edfb33931af 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -85,7 +85,7 @@ where T: Anything<'b, 'b>, { with_signature(cell, t, |cell, t| require(cell, t)); - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } #[rustc_regions] diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index c2b54b610fffa..d8725dc4284f3 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -217,7 +217,7 @@ LL | | where LL | | T: Anything<'b, 'b>, LL | | { LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | } | |_^ | @@ -226,7 +226,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 | LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 6b3bb60d51d3b..bcd141bb406b1 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/type-alias-free-regions.rs:19:9 | LL | impl<'a> FromBox<'a> for C<'a> { @@ -8,7 +8,7 @@ LL | fn from_box(b: Box) -> Self { LL | C { f: b } //~ ERROR | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/type-alias-free-regions.rs:29:9 | LL | impl<'a> FromTuple<'a> for C<'a> { diff --git a/src/test/ui/nll/user-annotations/closure-substs.rs b/src/test/ui/nll/user-annotations/closure-substs.rs index 9dc84aa0ba7b5..cafdd9257fdc0 100644 --- a/src/test/ui/nll/user-annotations/closure-substs.rs +++ b/src/test/ui/nll/user-annotations/closure-substs.rs @@ -5,21 +5,21 @@ fn foo<'a>() { // Here `x` is free in the closure sig: |x: &'a i32| -> &'static i32 { - return x; //~ ERROR unsatisfied lifetime constraints + return x; //~ ERROR lifetime may not live long enough }; } fn foo1() { // Here `x` is bound in the closure sig: |x: &i32| -> &'static i32 { - return x; //~ ERROR unsatisfied lifetime constraints + return x; //~ ERROR lifetime may not live long enough }; } fn bar<'a>() { // Here `x` is free in the closure sig: |x: &'a i32, b: fn(&'static i32)| { - b(x); //~ ERROR unsatisfied lifetime constraints + b(x); //~ ERROR lifetime may not live long enough }; } @@ -30,4 +30,4 @@ fn bar1() { }; } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/user-annotations/closure-substs.stderr b/src/test/ui/nll/user-annotations/closure-substs.stderr index ffc6e5a275705..a46ab61418efb 100644 --- a/src/test/ui/nll/user-annotations/closure-substs.stderr +++ b/src/test/ui/nll/user-annotations/closure-substs.stderr @@ -1,27 +1,27 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:8:16 | LL | fn foo<'a>() { | -- lifetime `'a` defined here ... -LL | return x; //~ ERROR unsatisfied lifetime constraints +LL | return x; //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:15:16 | LL | |x: &i32| -> &'static i32 { | - let's call the lifetime of this reference `'1` -LL | return x; //~ ERROR unsatisfied lifetime constraints +LL | return x; //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'1` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:22:9 | LL | fn bar<'a>() { | -- lifetime `'a` defined here ... -LL | b(x); //~ ERROR unsatisfied lifetime constraints +LL | b(x); //~ ERROR lifetime may not live long enough | ^^^^ argument requires that `'a` must outlive `'static` error[E0521]: borrowed data escapes outside of closure diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 94fbe01772412..541a7113ec740 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-inherent-1.rs:10:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr index 7aeb276eeb929..5b97c12b626b3 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-normalize.rs:20:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr index fee9abc1ed83a..10e48b5bc348b 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-1.rs:12:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr index 047aad9831923..5bfa32ec64492 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-2.rs:12:5 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index b373cebacb063..a1e60db05d08f 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-3.rs:12:5 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/issue-54124.rs b/src/test/ui/nll/user-annotations/issue-54124.rs index 042ad028575bb..e1de67aa93869 100644 --- a/src/test/ui/nll/user-annotations/issue-54124.rs +++ b/src/test/ui/nll/user-annotations/issue-54124.rs @@ -1,8 +1,8 @@ #![feature(nll)] fn test<'a>() { - let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints - //~^ ERROR unsatisfied lifetime constraints + let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/nll/user-annotations/issue-54124.stderr b/src/test/ui/nll/user-annotations/issue-54124.stderr index 5b5afaee8df71..b1c2411e46c01 100644 --- a/src/test/ui/nll/user-annotations/issue-54124.stderr +++ b/src/test/ui/nll/user-annotations/issue-54124.stderr @@ -1,19 +1,19 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-54124.rs:4:22 | LL | fn test<'a>() { | -- lifetime `'a` defined here -LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints +LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough | ^ - let's call the lifetime of this reference `'1` | | | requires that `'1` must outlive `'a` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-54124.rs:4:22 | LL | fn test<'a>() { | -- lifetime `'a` defined here -LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints +LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough | ^ requires that `'a` must outlive `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr index b0c554e6ca1d4..476578e074dac 100644 --- a/src/test/ui/nll/user-annotations/patterns.stderr +++ b/src/test/ui/nll/user-annotations/patterns.stderr @@ -148,7 +148,7 @@ LL | value1: &x, //~ ERROR LL | } | - `x` dropped here while still borrowed -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:113:5 | LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { @@ -157,7 +157,7 @@ LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:125:5 | LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { @@ -166,7 +166,7 @@ LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:130:5 | LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { @@ -175,7 +175,7 @@ LL | let Single { value: y }: Single<&'a u32> = Single { value: &22 }; LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:134:18 | LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/wf-self-type.rs b/src/test/ui/nll/user-annotations/wf-self-type.rs index da9ef8c89a169..d8caf4693b504 100644 --- a/src/test/ui/nll/user-annotations/wf-self-type.rs +++ b/src/test/ui/nll/user-annotations/wf-self-type.rs @@ -9,7 +9,7 @@ impl<'a, 'b> Foo<'a, 'b> { } pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { - Foo::xmute(u) //~ ERROR unsatisfied lifetime constraints + Foo::xmute(u) //~ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/user-annotations/wf-self-type.stderr b/src/test/ui/nll/user-annotations/wf-self-type.stderr index 401fe2a058a60..00500c8d6541f 100644 --- a/src/test/ui/nll/user-annotations/wf-self-type.stderr +++ b/src/test/ui/nll/user-annotations/wf-self-type.stderr @@ -1,11 +1,11 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/wf-self-type.rs:12:5 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here -LL | Foo::xmute(u) //~ ERROR unsatisfied lifetime constraints +LL | Foo::xmute(u) //~ ERROR lifetime may not live long enough | ^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` error: aborting due to previous error diff --git a/src/test/ui/nll/where_clauses_in_functions.rs b/src/test/ui/nll/where_clauses_in_functions.rs index 256ec6000faa7..0d35c09b8ef07 100644 --- a/src/test/ui/nll/where_clauses_in_functions.rs +++ b/src/test/ui/nll/where_clauses_in_functions.rs @@ -11,7 +11,7 @@ where fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { foo(x, y) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/where_clauses_in_functions.stderr b/src/test/ui/nll/where_clauses_in_functions.stderr index 4419a19010c9e..f3b65ec31ac7d 100644 --- a/src/test/ui/nll/where_clauses_in_functions.stderr +++ b/src/test/ui/nll/where_clauses_in_functions.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/where_clauses_in_functions.rs:13:5 | LL | fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { diff --git a/src/test/ui/nll/where_clauses_in_structs.rs b/src/test/ui/nll/where_clauses_in_structs.rs index 1b02f26a67837..8bc6b2e4a4fbb 100644 --- a/src/test/ui/nll/where_clauses_in_structs.rs +++ b/src/test/ui/nll/where_clauses_in_structs.rs @@ -11,7 +11,7 @@ struct Foo<'a: 'b, 'b> { fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { Foo { x, y }; - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/where_clauses_in_structs.stderr b/src/test/ui/nll/where_clauses_in_structs.stderr index 8704b0dc85c21..e0feb40273f6b 100644 --- a/src/test/ui/nll/where_clauses_in_structs.stderr +++ b/src/test/ui/nll/where_clauses_in_structs.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/where_clauses_in_structs.rs:13:11 | LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr index f667afdef7fa7..d6cec03e0ff2e 100644 --- a/src/test/ui/regions/regions-static-bound.nll.stderr +++ b/src/test/ui/regions/regions-static-bound.nll.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/regions-static-bound.rs:9:5 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs index 3ee518702e064..c1a15e50a4d06 100644 --- a/src/test/ui/regions/regions-static-bound.rs +++ b/src/test/ui/regions/regions-static-bound.rs @@ -7,7 +7,7 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { t //[ll]~ ERROR E0312 - //[nll]~^ ERROR unsatisfied lifetime constraints + //[nll]~^ ERROR lifetime may not live long enough } fn error(u: &(), v: &()) { 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/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`. 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 diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs new file mode 100644 index 0000000000000..295f8acf62f85 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +fn main() { + ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied +} diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr new file mode 100644 index 0000000000000..c6ec96ebb7d3b --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.stderr @@ -0,0 +1,12 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/type-alias-enum-variants-priority-2.rs:12:5 + | +LL | V(u8) + | ----- defined here +... +LL | ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied + | ^^^^^^^^ expected 1 parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants-priority-3.rs b/src/test/ui/type-alias-enum-variants-priority-3.rs new file mode 100644 index 0000000000000..33f96553b57f0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-3.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V +} + +fn check() -> ::V {} +//~^ ERROR expected type, found variant `V` + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority-3.stderr b/src/test/ui/type-alias-enum-variants-priority-3.stderr new file mode 100644 index 0000000000000..b3451542a2570 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-3.stderr @@ -0,0 +1,8 @@ +error: expected type, found variant `V` + --> $DIR/type-alias-enum-variants-priority-3.rs:7:15 + | +LL | fn check() -> ::V {} + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-enum-variants-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs new file mode 100644 index 0000000000000..db1da2b12e256 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_enum_variants)] +#![deny(ambiguous_associated_items)] + +enum E { + V +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { 0 } + //~^ ERROR ambiguous associated item + //~| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants-priority.stderr new file mode 100644 index 0000000000000..dcf7dc77ed5ea --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.stderr @@ -0,0 +1,26 @@ +error: ambiguous associated item + --> $DIR/type-alias-enum-variants-priority.rs:15:15 + | +LL | fn f() -> Self::V { 0 } + | ^^^^^^^ help: use fully-qualified syntax: `::V` + | +note: lint level defined here + --> $DIR/type-alias-enum-variants-priority.rs:2:9 + | +LL | #![deny(ambiguous_associated_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57644 +note: `V` could refer to variant defined here + --> $DIR/type-alias-enum-variants-priority.rs:5:5 + | +LL | V + | ^ +note: `V` could also refer to associated type defined here + --> $DIR/type-alias-enum-variants-priority.rs:9:5 + | +LL | type V; + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8c1baa55bcdca..4ca285b9b1db1 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -95,6 +95,7 @@ static TARGETS: &'static [&'static str] = &[ "wasm32-unknown-unknown", "x86_64-apple-darwin", "x86_64-apple-ios", + "x86_64-fortanix-unknown-sgx", "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-gnu",