diff --git a/Cargo.lock b/Cargo.lock index d5453c5fd6c..4d2a2e96458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,9 +441,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" dependencies = [ "jobserver", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 68f40d5f863..3a677a2437c 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -9,7 +9,7 @@ test = false [dependencies] bitflags = "1.2.1" -cc = "1.0.67" +cc = "1.0.68" itertools = "0.9" tracing = "0.1" libc = "0.2.50" @@ -24,7 +24,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_apfloat = { path = "../rustc_apfloat" } rustc_attr = { path = "../rustc_attr" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } -rustc_data_structures = { path = "../rustc_data_structures"} +rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 945406aed4b..95504723e7b 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -285,6 +285,8 @@ declare_features! ( (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), /// Allows unsizing coercions in `const fn`. (accepted, const_fn_unsize, "1.54.0", Some(64992), None), + /// Allows `impl Trait` with multiple unrelated lifetimes. + (accepted, member_constraints, "1.54.0", Some(61997), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ac1974eb4c6..a84737e80a0 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -472,9 +472,6 @@ declare_features! ( /// Allows explicit discriminants on non-unit enum variants. (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), - /// Allows `impl Trait` with multiple unrelated lifetimes. - (active, member_constraints, "1.37.0", Some(61997), None), - /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index bd3b5239f7b..303c39a39a9 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::definitions::DefPathTable; -use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::query::OnDiskCache; use rustc_serialize::opaque::Decoder; use rustc_serialize::Decodable; @@ -22,8 +22,8 @@ pub enum LoadResult { Error { message: String }, } -impl LoadResult<(PreviousDepGraph, WorkProductMap)> { - pub fn open(self, sess: &Session) -> (PreviousDepGraph, WorkProductMap) { +impl LoadResult<(SerializedDepGraph, WorkProductMap)> { + pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) { match self { LoadResult::Error { message } => { sess.warn(&message); @@ -84,7 +84,7 @@ impl MaybeAsync { } } -pub type DepGraphFuture = MaybeAsync>; +pub type DepGraphFuture = MaybeAsync>; /// Launch a thread and load the dependency graph in the background. pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { @@ -185,7 +185,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { let dep_graph = SerializedDepGraph::decode(&mut decoder) .expect("Error reading cached dep-graph"); - LoadResult::Ok { data: (PreviousDepGraph::new(dep_graph), prev_work_products) } + LoadResult::Ok { data: (dep_graph, prev_work_products) } } } })) diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 1484088837a..9603b102cbc 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::join; -use rustc_middle::dep_graph::{DepGraph, PreviousDepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_serialize::Encodable as RustcEncodable; @@ -186,7 +186,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: &mut FileEncoder) -> FileEncodeR pub fn build_dep_graph( sess: &Session, - prev_graph: PreviousDepGraph, + prev_graph: SerializedDepGraph, prev_work_products: FxHashMap, ) -> Option { if sess.opts.incremental.is_none() { diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 7a34788de91..3fca2e1ccb9 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -13,4 +13,4 @@ libc = "0.2.73" [build-dependencies] build_helper = { path = "../../src/build_helper" } -cc = "1.0.67" +cc = "1.0.68" diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 31bea832958..aa61219ad78 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -18,7 +18,6 @@ crate use dep_node::{make_compile_codegen_unit, make_compile_mono_item}; pub type DepGraph = rustc_query_system::dep_graph::DepGraph; pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps; pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery; -pub type PreviousDepGraph = rustc_query_system::dep_graph::PreviousDepGraph; pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph; pub type EdgeFilter = rustc_query_system::dep_graph::debug::EdgeFilter; diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 79aaff1c5eb..4c53510ed00 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -15,9 +15,9 @@ use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ - alloc_range, mir_assign_valid_types, AllocId, AllocMap, AllocRef, AllocRefMut, Allocation, - ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, - Operand, Pointer, PointerArithmetic, Scalar, ScalarMaybeUninit, + alloc_range, mir_assign_valid_types, AllocRef, AllocRefMut, ConstAlloc, ImmTy, Immediate, + InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, + PointerArithmetic, Scalar, ScalarMaybeUninit, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -292,8 +292,6 @@ where // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 Tag: Debug + Copy + Eq + Hash + 'static, M: Machine<'mir, 'tcx, PointerTag = Tag>, - // FIXME: Working around https://github.com/rust-lang/rust/issues/24159 - M::MemoryMap: AllocMap, Allocation)>, { /// Take a value, which represents a (thin or wide) reference, and make it a place. /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`. diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index a19ee802438..2185bd3a5c6 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -185,21 +185,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match x { _ => () } // fake read of `x` // }; // ``` - for (thir_place, cause, hir_id) in fake_reads.into_iter() { - let place_builder = - unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); + // + // FIXME(RFC2229, rust#85435): Remove feature gate once diagnostics are + // improved and unsafe checking works properly in closure bodies again. + if this.tcx.features().capture_disjoint_fields { + for (thir_place, cause, hir_id) in fake_reads.into_iter() { + let place_builder = + unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); - if let Ok(place_builder_resolved) = - place_builder.try_upvars_resolved(this.tcx, this.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); - this.cfg.push_fake_read( - block, - this.source_info(this.tcx.hir().span(*hir_id)), - *cause, - mir_place, - ); + if let Ok(place_builder_resolved) = + place_builder.try_upvars_resolved(this.tcx, this.typeck_results) + { + let mir_place = + place_builder_resolved.into_place(this.tcx, this.typeck_results); + this.cfg.push_fake_read( + block, + this.source_info(this.tcx.hir().span(*hir_id)), + *cause, + mir_place, + ); + } } } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 7a0fc320663..38010b77868 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -19,9 +19,8 @@ use std::marker::PhantomData; use std::mem; use std::sync::atomic::Ordering::Relaxed; -use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; -use super::serialized::{GraphEncoder, SerializedDepNodeIndex}; +use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex}; use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId}; use crate::query::QueryContext; @@ -78,7 +77,7 @@ struct DepGraphData { /// The dep-graph from the previous compilation session. It contains all /// nodes and edges as well as all fingerprints of nodes that have them. - previous: PreviousDepGraph, + previous: SerializedDepGraph, colors: DepNodeColorMap, @@ -109,7 +108,7 @@ where impl DepGraph { pub fn new( - prev_graph: PreviousDepGraph, + prev_graph: SerializedDepGraph, prev_work_products: FxHashMap, encoder: FileEncoder, record_graph: bool, @@ -857,7 +856,7 @@ rustc_index::newtype_index! { /// For this reason, we avoid storing `DepNode`s more than once as map /// keys. The `new_node_to_index` map only contains nodes not in the previous /// graph, and we map nodes in the previous graph to indices via a two-step -/// mapping. `PreviousDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, +/// mapping. `SerializedDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, /// and the `prev_index_to_index` vector (which is more compact and faster than /// using a map) maps from `SerializedDepNodeIndex` to `DepNodeIndex`. /// @@ -982,7 +981,7 @@ impl CurrentDepGraph { fn intern_node( &self, profiler: &SelfProfilerRef, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, key: DepNode, edges: EdgesVec, fingerprint: Option, @@ -1080,7 +1079,7 @@ impl CurrentDepGraph { fn promote_node_and_deps_to_current( &self, profiler: &SelfProfilerRef, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, ) -> DepNodeIndex { self.debug_assert_not_in_new_nodes(prev_graph, prev_index); @@ -1112,7 +1111,7 @@ impl CurrentDepGraph { #[inline] fn debug_assert_not_in_new_nodes( &self, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, ) { let node = &prev_graph.index_to_node(prev_index); diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 1b6ecf3e637..15e2633c4f1 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -1,13 +1,11 @@ pub mod debug; mod dep_node; mod graph; -mod prev; mod query; mod serialized; pub use dep_node::{DepNode, DepNodeParams, WorkProductId}; pub use graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct}; -pub use prev::PreviousDepGraph; pub use query::DepGraphQuery; pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; diff --git a/compiler/rustc_query_system/src/dep_graph/prev.rs b/compiler/rustc_query_system/src/dep_graph/prev.rs deleted file mode 100644 index 6303bbf53b9..00000000000 --- a/compiler/rustc_query_system/src/dep_graph/prev.rs +++ /dev/null @@ -1,56 +0,0 @@ -use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; -use super::{DepKind, DepNode}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxHashMap; - -#[derive(Debug)] -pub struct PreviousDepGraph { - data: SerializedDepGraph, - index: FxHashMap, SerializedDepNodeIndex>, -} - -impl Default for PreviousDepGraph { - fn default() -> Self { - PreviousDepGraph { data: Default::default(), index: Default::default() } - } -} - -impl PreviousDepGraph { - pub fn new(data: SerializedDepGraph) -> PreviousDepGraph { - let index: FxHashMap<_, _> = - data.nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect(); - PreviousDepGraph { data, index } - } - - #[inline] - pub fn edge_targets_from( - &self, - dep_node_index: SerializedDepNodeIndex, - ) -> &[SerializedDepNodeIndex] { - self.data.edge_targets_from(dep_node_index) - } - - #[inline] - pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { - self.data.nodes[dep_node_index] - } - - #[inline] - pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node).cloned() - } - - #[inline] - pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node).map(|&node_index| self.data.fingerprints[node_index]) - } - - #[inline] - pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { - self.data.fingerprints[dep_node_index] - } - - pub fn node_count(&self) -> usize { - self.index.len() - } -} diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 6f3d1fb7199..6a84a28be66 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -37,17 +37,19 @@ rustc_index::newtype_index! { #[derive(Debug)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph - pub nodes: IndexVec>, + nodes: IndexVec>, /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to /// the DepNode at the same index in the nodes vector. - pub fingerprints: IndexVec, + fingerprints: IndexVec, /// For each DepNode, stores the list of edges originating from that /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data, /// which holds the actual DepNodeIndices of the target nodes. - pub edge_list_indices: IndexVec, + edge_list_indices: IndexVec, /// A flattened list of all edge targets in the graph. Edge sources are /// implicit in edge_list_indices. - pub edge_list_data: Vec, + edge_list_data: Vec, + /// Reciprocal map to `nodes`. + index: FxHashMap, SerializedDepNodeIndex>, } impl Default for SerializedDepGraph { @@ -57,6 +59,7 @@ impl Default for SerializedDepGraph { fingerprints: Default::default(), edge_list_indices: Default::default(), edge_list_data: Default::default(), + index: Default::default(), } } } @@ -67,6 +70,30 @@ impl SerializedDepGraph { let targets = self.edge_list_indices[source]; &self.edge_list_data[targets.0 as usize..targets.1 as usize] } + + #[inline] + pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { + self.nodes[dep_node_index] + } + + #[inline] + pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { + self.index.get(dep_node).cloned() + } + + #[inline] + pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { + self.index.get(dep_node).map(|&node_index| self.fingerprints[node_index]) + } + + #[inline] + pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { + self.fingerprints[dep_node_index] + } + + pub fn node_count(&self) -> usize { + self.index.len() + } } impl<'a, K: DepKind + Decodable>> Decodable> @@ -121,7 +148,10 @@ impl<'a, K: DepKind + Decodable>> Decodable = + nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect(); + + Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }) } } diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 7e67bc118ec..163df26e9ff 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -140,15 +140,6 @@ pub trait InferCtxtExt<'tcx> { first_own_region_index: usize, ); - /*private*/ - fn member_constraint_feature_gate( - &self, - opaque_defn: &OpaqueTypeDecl<'tcx>, - opaque_type_def_id: DefId, - conflict1: ty::Region<'tcx>, - conflict2: ty::Region<'tcx>, - ) -> bool; - fn infer_opaque_definition_from_instantiation( &self, def_id: DefId, @@ -490,9 +481,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // ['a, 'b, 'c]`, where `'a..'c` are the // regions that appear in the impl trait. - // For now, enforce a feature gate outside of async functions. - self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_region); - return self.generate_member_constraint( concrete_ty, opaque_defn, @@ -559,60 +547,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); } - /// Member constraints are presently feature-gated except for - /// async-await. We expect to lift this once we've had a bit more - /// time. - fn member_constraint_feature_gate( - &self, - opaque_defn: &OpaqueTypeDecl<'tcx>, - opaque_type_def_id: DefId, - conflict1: ty::Region<'tcx>, - conflict2: ty::Region<'tcx>, - ) -> bool { - // If we have `#![feature(member_constraints)]`, no problems. - if self.tcx.features().member_constraints { - return false; - } - - let span = self.tcx.def_span(opaque_type_def_id); - - // Without a feature-gate, we only generate member-constraints for async-await. - let context_name = match opaque_defn.origin { - // No feature-gate required for `async fn`. - hir::OpaqueTyOrigin::AsyncFn => return false, - - // Otherwise, generate the label we'll use in the error message. - hir::OpaqueTyOrigin::Binding - | hir::OpaqueTyOrigin::FnReturn - | hir::OpaqueTyOrigin::TyAlias - | hir::OpaqueTyOrigin::Misc => "impl Trait", - }; - let msg = format!("ambiguous lifetime bound in `{}`", context_name); - let mut err = self.tcx.sess.struct_span_err(span, &msg); - - let conflict1_name = conflict1.to_string(); - let conflict2_name = conflict2.to_string(); - let label_owned; - let label = match (&*conflict1_name, &*conflict2_name) { - ("'_", "'_") => "the elided lifetimes here do not outlive one another", - _ => { - label_owned = format!( - "neither `{}` nor `{}` outlives the other", - conflict1_name, conflict2_name, - ); - &label_owned - } - }; - err.span_label(span, label); - - if self.tcx.sess.is_nightly_build() { - err.help("add #![feature(member_constraints)] to the crate attributes to enable"); - } - - err.emit(); - true - } - /// Given the fully resolved, instantiated type for an opaque /// type, i.e., the value of an inference variable like C1 or C2 /// (*), computes the "definition type" for an opaque type diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 2320a29e6d8..16382c7e7a4 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -383,6 +383,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } else { span = item_name.span; + + // Don't show generic arguments when the method can't be found in any implementation (#81576). + let mut ty_str_reported = ty_str.clone(); + if let ty::Adt(_, ref generics) = actual.kind() { + if generics.len() > 0 { + let mut autoderef = self.autoderef(span, actual); + let candidate_found = autoderef.any(|(ty, _)| { + if let ty::Adt(ref adt_deref, _) = ty.kind() { + self.tcx + .inherent_impls(adt_deref.did) + .iter() + .filter_map(|def_id| { + self.associated_item( + *def_id, + item_name, + Namespace::ValueNS, + ) + }) + .count() + >= 1 + } else { + false + } + }); + let has_deref = autoderef.step_count() > 0; + if !candidate_found + && !has_deref + && unsatisfied_predicates.is_empty() + { + if let Some((path_string, _)) = ty_str.split_once('<') { + ty_str_reported = path_string.to_string(); + } + } + } + } + let mut err = struct_span_err!( tcx.sess, span, @@ -391,7 +427,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, actual.prefix_string(self.tcx), - ty_str, + ty_str_reported, ); if let Mode::MethodCall = mode { if let SelfSource::MethodCall(call) = source { @@ -449,6 +485,63 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut label_span_not_found = || { if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); + if let ty::Adt(ref adt, _) = rcvr_ty.kind() { + let mut inherent_impls_candidate = self + .tcx + .inherent_impls(adt.did) + .iter() + .copied() + .filter(|def_id| { + if let Some(assoc) = + self.associated_item(*def_id, item_name, Namespace::ValueNS) + { + // Check for both mode is the same so we avoid suggesting + // incorrect associated item. + match (mode, assoc.fn_has_self_parameter, source) { + (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != actual + && self.tcx.at(span).type_of(*def_id) != rcvr_ty + } + (Mode::Path, false, _) => true, + _ => false, + } + } else { + false + } + }) + .collect::>(); + if inherent_impls_candidate.len() > 0 { + inherent_impls_candidate.sort(); + inherent_impls_candidate.dedup(); + + // number of type to shows at most. + let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; + let type_candidates = inherent_impls_candidate + .iter() + .take(limit) + .map(|impl_item| { + format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) + }) + .collect::>() + .join("\n"); + let additional_types = if inherent_impls_candidate.len() > limit { + format!( + "\nand {} more types", + inherent_impls_candidate.len() - limit + ) + } else { + "".to_string() + }; + err.note(&format!( + "the {item_kind} was found for\n{}{}", + type_candidates, additional_types + )); + } + } } else { err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds")); } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 1eef0f9064c..ad77e76c94f 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -25,40 +25,6 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} /// [impl]: crate::iter#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - on( - _Self = "[std::ops::Range; 1]", - label = "if you meant to iterate between two values, remove the square brackets", - note = "`[start..end]` is an array of one `Range`; you might have meant to have a `Range` \ - without the brackets: `start..end`" - ), - on( - _Self = "[std::ops::RangeFrom; 1]", - label = "if you meant to iterate from a value onwards, remove the square brackets", - note = "`[start..]` is an array of one `RangeFrom`; you might have meant to have a \ - `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an \ - unbounded iterator will run forever unless you `break` or `return` from within the \ - loop" - ), - on( - _Self = "[std::ops::RangeTo; 1]", - label = "if you meant to iterate until a value, remove the square brackets and add a \ - starting value", - note = "`[..end]` is an array of one `RangeTo`; you might have meant to have a bounded \ - `Range` without the brackets: `0..end`" - ), - on( - _Self = "[std::ops::RangeInclusive; 1]", - label = "if you meant to iterate between two values, remove the square brackets", - note = "`[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a \ - `RangeInclusive` without the brackets: `start..=end`" - ), - on( - _Self = "[std::ops::RangeToInclusive; 1]", - label = "if you meant to iterate until a value (including it), remove the square brackets \ - and add a starting value", - note = "`[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a \ - bounded `RangeInclusive` without the brackets: `0..=end`" - ), on( _Self = "std::ops::RangeTo", label = "if you meant to iterate until a value, add a starting value", diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index 474058a547f..7b7ca8029b4 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -14,4 +14,4 @@ core = { path = "../core" } compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -cc = "1.0.67" +cc = "1.0.68" diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 2a4ef553be3..be7e099b73a 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -672,6 +672,7 @@ impl CString { } /// Bypass "move out of struct which implements [`Drop`] trait" restriction. + #[inline] fn into_inner(self) -> Box<[u8]> { // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)` // so we use `ManuallyDrop` to ensure `self` is not dropped. diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index f42ded62585..9dac1f35657 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -21,7 +21,7 @@ compiler_builtins = "0.1.0" cfg-if = "0.1.8" [build-dependencies] -cc = "1.0.67" +cc = "1.0.68" [features] llvm-libunwind = [] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index a74df97a5c7..8445d811e0f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -40,7 +40,7 @@ cmake = "0.1.38" filetime = "0.2" num_cpus = "1.0" getopts = "0.2.19" -cc = "1.0.67" +cc = "1.0.68" libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md deleted file mode 100644 index 3ba4a3e6b1f..00000000000 --- a/src/doc/unstable-book/src/language-features/member-constraints.md +++ /dev/null @@ -1,29 +0,0 @@ -# `member_constraints` - -The tracking issue for this feature is: [#61997] - -[#61997]: https://github.com/rust-lang/rust/issues/61997 - ------------------------- - -The `member_constraints` feature gate lets you use `impl Trait` syntax with -multiple unrelated lifetime parameters. - -A simple example is: - -```rust -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T {} - -fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - (x, y) -} - -fn main() { } -``` - -Without the `member_constraints` feature gate, the above example is an -error because both `'a` and `'b` appear in the impl Trait bounds, but -neither outlives the other. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs index b901b61aa18..f1002947fb9 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs @@ -1,10 +1,9 @@ // edition:2018 // run-pass -// Test that a feature gate is needed to use `impl Trait` as the -// return type of an async. - -#![feature(member_constraints)] +// Test member constraints that appear in the `impl Trait` +// return type of an async function. +// (This used to require a feature gate.) trait Trait<'a, 'b> { } impl Trait<'_, '_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs deleted file mode 100644 index 05960c0c7f6..00000000000 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs +++ /dev/null @@ -1,20 +0,0 @@ -// edition:2018 - -// Test that a feature gate is needed to use `impl Trait` as the -// return type of an async. - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } - -async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - //~^ ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds - //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds - (a, b) -} - -fn main() { - let _ = async_ret_impl_trait(&22, &44); -} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr deleted file mode 100644 index f65bbeaa31a..00000000000 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-no-fg.rs:9:1 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: hidden type `(&u8, &u8)` captures lifetime '_#5r - -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-no-fg.rs:9:1 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: hidden type `(&u8, &u8)` captures lifetime '_#6r - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr index 53b0dd691b8..eed90772d29 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/ret-impl-trait-one.rs:12:80 + --> $DIR/ret-impl-trait-one.rs:10:80 | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { | ________________________________--__--__________________________________________^ diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs index babc90a5e96..7e084217c26 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -3,8 +3,6 @@ // Test that a feature gate is needed to use `impl Trait` as the // return type of an async. -#![feature(member_constraints)] - trait Trait<'a> { } impl Trait<'_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 5041b39a9e9..8e28605721c 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ret-impl-trait-one.rs:12:65 + --> $DIR/ret-impl-trait-one.rs:10:65 | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { | ------ ^^^^^^^^^^^^^^ diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index d6b399acb73..fe6b12968c1 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-18343.rs:6:28: 6:33]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 051940bbe96..0480958e99c 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.rs b/src/test/ui/feature-gates/feature-gate-member-constraints.rs deleted file mode 100644 index f6a92b0d0bf..00000000000 --- a/src/test/ui/feature-gates/feature-gate-member-constraints.rs +++ /dev/null @@ -1,10 +0,0 @@ -trait Trait<'a, 'b> {} -impl Trait<'_, '_> for T {} - -fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - //~^ ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - (x, y) -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr b/src/test/ui/feature-gates/feature-gate-member-constraints.stderr deleted file mode 100644 index c2ec7ae16a3..00000000000 --- a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/feature-gate-member-constraints.rs:4:43 - | -LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/feature-gate-member-constraints.rs:4:43 - | -LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr index d7a9e5463b3..ff99d037d19 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/error-handling.rs:6:32 + --> $DIR/error-handling.rs:5:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: lifetime may not live long enough - --> $DIR/error-handling.rs:26:16 + --> $DIR/error-handling.rs:25:16 | LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr index e2d745cdec8..4b23ba81604 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/error-handling.rs:26:16 + --> $DIR/error-handling.rs:25:16 | LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs index b5adabb7abd..1ead78e02ed 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -1,6 +1,5 @@ // compile-flags:-Zborrowck=mir -#![feature(member_constraints)] // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs index 3911769b0c6..41b6a9eb055 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs @@ -3,8 +3,6 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs index 553dea7aa6e..d0277336b25 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs @@ -3,10 +3,8 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Test case where we have elision in the impl trait and we have to // pick the right region. @@ -26,4 +24,4 @@ fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> { (a, a) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs index 9d345502aab..b9857b7aa2f 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs @@ -3,10 +3,9 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] #![feature(min_type_alias_impl_trait)] -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Here we wind up selecting `'a` and `'b` in the hidden type because // those are the types that appear in the original values. @@ -28,4 +27,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { (a, b) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs index c0930ec5944..be455f53350 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs @@ -3,10 +3,8 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Here we wind up selecting `'a` and `'b` in the hidden type because // those are the types that appear in the original values. @@ -26,4 +24,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { (a, b) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs index ed36bda7db7..7235d89019f 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs @@ -3,8 +3,6 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr index 129af80ce4a..8cf89f164b1 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs index db1641b0140..3a97624647e 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index b42ff1486f0..a6bc8fec283 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ | note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr index de6d5edcae5..1bcb28120ed 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs index 7f9c92f15a2..d4c60a4e892 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} @@ -18,7 +16,7 @@ struct Ordinary<'a>(&'a u8); // consider the loans for both `'a` and `'b` alive. fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds +//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds { // We return a value: // diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 254643c406c..a219e747415 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ | note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.rs b/src/test/ui/impl-trait/needs_least_region_or_bound.rs index 3c8682bb62a..c4bcfe5b281 100644 --- a/src/test/ui/impl-trait/needs_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/needs_least_region_or_bound.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(member_constraints)] - trait MultiRegionTrait<'a, 'b> {} impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {} diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index bc6731601f0..e9d934332f1 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -3,6 +3,9 @@ error[E0599]: no function or associated item named `new_undirected` found for st | LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` + | + = note: the function or associated item was found for + - `issue_30123_aux::Graph` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index 09d5594f73f..017dd831f71 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs new file mode 100644 index 00000000000..3df928b5d80 --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -0,0 +1,106 @@ +// Test for issue 81576 +// Remove generic arguments if no method is found for all possible generic argument + +use std::marker::PhantomData; + +struct Wrapper2<'a, T, const C: usize> { + x: &'a T, +} + +impl<'a, const C: usize> Wrapper2<'a, i8, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i16, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i32, C> { + fn method(&self) {} +} +struct Wrapper(T); + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +struct Point { + x: T, + y: T, +} + +impl Point { + fn distance(&self) -> f64 { + self.x.hypot(self.y) + } +} + +struct Other; + +impl Other { + fn other(&self) {} +} + +struct Struct{ + _phatom: PhantomData +} + +impl Default for Struct { + fn default() -> Self { + Self{ _phatom: PhantomData } + } +} + +impl Struct { + fn method(&self) {} +} + +fn main() { + let point_f64 = Point{ x: 1_f64, y: 1_f64}; + let d = point_f64.distance(); + let point_i32 = Point{ x: 1_i32, y: 1_i32}; + let d = point_i32.distance(); + //~^ ERROR no method named `distance` found for struct `Point + let d = point_i32.other(); + //~^ ERROR no method named `other` found for struct `Point + let v = vec![1_i32, 2, 3]; + v.iter().map(|x| x * x).extend(std::iter::once(100)); + //~^ ERROR no method named `extend` found for struct `Map + let wrapper = Wrapper(true); + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper + let boolean = true; + let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper2 + let a = vec![1, 2, 3]; + a.not_found(); + //~^ ERROR no method named `not_found` found for struct `Vec + let s = Struct::::default(); + s.method(); + //~^ ERROR the method `method` exists for struct `Struct`, but its trait bounds were not satisfied +} diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr new file mode 100644 index 00000000000..1671e5e5e64 --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -0,0 +1,97 @@ +error[E0599]: no method named `distance` found for struct `Point` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:82:23 + | +LL | struct Point { + | --------------- method `distance` not found for this +... +LL | let d = point_i32.distance(); + | ^^^^^^^^ method not found in `Point` + | + = note: the method was found for + - `Point` + +error[E0599]: no method named `other` found for struct `Point` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:84:23 + | +LL | struct Point { + | --------------- method `other` not found for this +... +LL | let d = point_i32.other(); + | ^^^^^ method not found in `Point` + +error[E0599]: no method named `extend` found for struct `Map` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:87:29 + | +LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); + | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:87:18: 87:27]>` + +error[E0599]: no method named `method` found for struct `Wrapper` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:90:13 + | +LL | struct Wrapper(T); + | --------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper` + | + = note: the method was found for + - `Wrapper` + - `Wrapper` + - `Wrapper` + - `Wrapper` + and 2 more types + +error[E0599]: no method named `other` found for struct `Wrapper` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:92:13 + | +LL | struct Wrapper(T); + | --------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper` + +error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:96:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | + = note: the method was found for + - `Wrapper2<'a, i8, C>` + - `Wrapper2<'a, i16, C>` + - `Wrapper2<'a, i32, C>` + +error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:98:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + +error[E0599]: no method named `not_found` found for struct `Vec<{integer}>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:101:7 + | +LL | a.not_found(); + | ^^^^^^^^^ method not found in `Vec<{integer}>` + +error[E0599]: the method `method` exists for struct `Struct`, but its trait bounds were not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:104:7 + | +LL | struct Struct{ + | ---------------- method `method` not found for this +... +LL | s.method(); + | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `f64: Eq` + `f64: Ord` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr index 0880136d71b..05b63a00dfb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-74761.rs:4:32 + --> $DIR/issue-74761.rs:3:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:6 + --> $DIR/issue-74761.rs:10:6 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:10 + --> $DIR/issue-74761.rs:10:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr index 20ebdd9cb50..ad111e23b15 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr @@ -1,11 +1,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:6 + --> $DIR/issue-74761.rs:10:6 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:10 + --> $DIR/issue-74761.rs:10:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.rs b/src/test/ui/type-alias-impl-trait/issue-74761.rs index 66bb079b25a..bbc67ecc97a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.rs +++ b/src/test/ui/type-alias-impl-trait/issue-74761.rs @@ -1,4 +1,3 @@ -#![feature(member_constraints)] // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] diff --git a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs new file mode 100644 index 00000000000..72f7b674777 --- /dev/null +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -0,0 +1,27 @@ +// check-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +// This is issue #85435. But the real story is reflected in issue #85561, where +// a bug in the implementation of feature(capture_disjoint_fields) () was +// exposed to non-feature-gated code by a diagnostic changing PR that removed +// the gating in one case. + +// This test is double-checking that the case of interest continues to work as +// expected in the *absence* of that feature gate. At the time of this writing, +// enabling the feature gate will cause this test to fail. We obviously cannot +// stabilize that feature until it can correctly handle this test. + +fn main() { + let val: u8 = 5; + let u8_ptr: *const u8 = &val; + let _closure = || { + unsafe { + let tmp = *u8_ptr; + tmp + + // Just dereferencing and returning directly compiles fine: + // *u8_ptr + } + }; +}