From c64a2ed191f2a9137227b71d7005d0d93c376976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Thu, 15 Apr 2021 16:58:17 +0200 Subject: [PATCH 01/16] elision of generic argument in E0599 if the methode has not been found anywhere and sugetion of type with method when found. --- .../rustc_typeck/src/check/method/suggest.rs | 120 +++++++++++++++++- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +- .../no-method-suggested-traits.stderr | 24 ++-- src/test/ui/issues/issue-30123.stderr | 2 + src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 90 +++++++++++++ ...ethod-not-found-generic-arg-elision.stderr | 75 +++++++++++ src/test/ui/object-pointer-types.stderr | 2 +- 11 files changed, 310 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.rs create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.stderr diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 02fe8312c4c..54a1078383f 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,6 +13,7 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; +use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -383,6 +384,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } else { span = item_name.span; + + // issue #81576, elision of generic argument when no methode can be found in any implementation + let mut ty_str_reported = ty_str.clone(); + if let ty::Adt(_, ref generics) = actual.kind() { + if generics.len() > 0 { + let candidate_numbers: usize = self + .autoderef(span, actual) + .map(|(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() + } else { + 0 + } + }) + .sum(); + if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { + if let Some((path_string, _)) = ty_str.split_once('<') { + ty_str_reported = format!("{}<", path_string); + for (index, arg) in generics.iter().enumerate() { + let arg_replace = match arg.unpack() { + GenericArgKind::Lifetime(_) => "'_", + GenericArgKind::Type(_) + | GenericArgKind::Const(_) => "_", + }; + ty_str_reported = + format!("{}{}", ty_str_reported, arg_replace); + if index < generics.len() - 1 { + ty_str_reported = format!("{}, ", ty_str_reported); + } + } + ty_str_reported = format!("{}>", ty_str_reported); + } + } + } + } + let mut err = struct_span_err!( tcx.sess, span, @@ -391,7 +438,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 +496,77 @@ 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 + // incorect associated item. + match (mode, assoc.fn_has_self_parameter) { + (Mode::MethodCall, true) => { + if let SelfSource::MethodCall(_) = source { + // 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 + } else { + false + } + } + (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. + const LIMIT: usize = 3; + let mut note = format!("The {item_kind} was found for"); + if inherent_impls_candidate.len() > 1 { + for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) + { + let impl_ty = self.tcx.at(span).type_of(*impl_item); + note = format!("{} {},", note, impl_ty); + } + let impl_ty = self.tcx.at(span).type_of( + inherent_impls_candidate + [inherent_impls_candidate.len() - 1], + ); + if inherent_impls_candidate.len() > LIMIT { + note = format!("{} {},", note, impl_ty); + } else { + note = format!("{} {} and", note, impl_ty); + } + } + let impl_ty = self + .tcx + .at(span) + .type_of(*inherent_impls_candidate.last().unwrap()); + note = format!("{} {}", note, impl_ty); + if inherent_impls_candidate.len() > LIMIT { + note = format!( + "{} and {} more", + note, + inherent_impls_candidate.len() - LIMIT + ); + } + err.note(&format!("{}.", note)); + } + } } else { err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds")); } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index eb8447ff0f3..be1b79e936d 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope +error[E0599]: no method named `test` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index 56d10d88d8b..c01af6d7e25 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box` in the current scope +error[E0599]: no method named `eat` found for struct `Box<_, _>` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); 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..2bf32975a6f 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..f17a56eba2f 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/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 64ddcb81c0a..5c0f945140a 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index bc6731601f0..27b128372c0 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -3,6 +3,8 @@ 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..f9d11c47687 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..85ccb0bd0de --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -0,0 +1,90 @@ +// Test for issue 81576 +// Remove generic arguments if no method is found for all possible generic argument + + +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) {} +} + +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<_, _> +} 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..80e111390c6 --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -0,0 +1,75 @@ +error[E0599]: no method named `distance` found for struct `Point` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:69: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:71: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:74: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:74:18: 74:27]>` + +error[E0599]: no method named `method` found for struct `Wrapper` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:77: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 and 3 more. + +error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:79: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:83: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, i32, C> and 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:85: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<_, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:88:7 + | +LL | a.not_found(); + | ^^^^^^^^^ method not found in `Vec<{integer}>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index a477425edc8..fb3462b2cab 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope +error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); From 6efa14b3add08188c5322db8694a8cbbea7851e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Fri, 21 May 2021 14:01:38 +0200 Subject: [PATCH 02/16] remove generic argument insead of displaying "_" --- .../rustc_typeck/src/check/method/suggest.rs | 16 +------------ src/test/ui/auto-ref-slice-plus-ref.stderr | 4 ++-- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +++++----- .../no-method-suggested-traits.stderr | 24 +++++++++---------- src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 10 ++++---- ...ethod-not-found-generic-arg-elision.stderr | 10 ++++---- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 11 files changed, 36 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 54a1078383f..f46d4205a6b 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,7 +13,6 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -411,20 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sum(); if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { if let Some((path_string, _)) = ty_str.split_once('<') { - ty_str_reported = format!("{}<", path_string); - for (index, arg) in generics.iter().enumerate() { - let arg_replace = match arg.unpack() { - GenericArgKind::Lifetime(_) => "'_", - GenericArgKind::Type(_) - | GenericArgKind::Const(_) => "_", - }; - ty_str_reported = - format!("{}{}", ty_str_reported, arg_replace); - if index < generics.len() - 1 { - ty_str_reported = format!("{}, ", ty_str_reported); - } - } - ty_str_reported = format!("{}>", ty_str_reported); + ty_str_reported = path_string.to_string(); } } } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index be1b79e936d..7203d3ed30e 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `test` found for struct `Vec` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index c01af6d7e25..a1a3ead5812 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box<_, _>` in the current scope +error[E0599]: no method named `eat` found for struct `Box` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); 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 2bf32975a6f..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<_>` 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 f17a56eba2f..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<_>` 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<_>` 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<_>` 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<_>` 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<_>` 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<_>` 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/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5c0f945140a..5507406b0f5 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index f9d11c47687..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<_, _>` 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 index 85ccb0bd0de..23f01fb861f 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -69,22 +69,22 @@ fn main() { 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<_> + //~^ 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<_, _> + //~^ 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<_> + //~^ 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<'_, _, _> + //~^ 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<_, _> + //~^ ERROR no method named `not_found` found for struct `Vec } 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 index 80e111390c6..65dbabbc143 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -9,7 +9,7 @@ LL | let d = point_i32.distance(); | = note: The method was found for Point. -error[E0599]: no method named `other` found for struct `Point<_>` in the current scope +error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:71:23 | LL | struct Point { @@ -18,7 +18,7 @@ LL | struct Point { 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 +error[E0599]: no method named `extend` found for struct `Map` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:74:29 | LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); @@ -35,7 +35,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. -error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:79:13 | LL | struct Wrapper(T); @@ -55,7 +55,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. -error[E0599]: no method named `other` found for struct `Wrapper2<'_, _, _>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:85:13 | LL | struct Wrapper2<'a, T, const C: usize> { @@ -64,7 +64,7 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `not_found` found for struct `Vec` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:88:7 | LL | a.not_found(); diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index fb3462b2cab..021899b3082 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope +error[E0599]: no method named `managed` found for struct `Box` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 027d7a0e0e4..6b8ec47d98d 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From 1f130fbff8d32da093da8eca723323792a3a8554 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 21 May 2021 14:55:09 -0400 Subject: [PATCH 03/16] Revert portion of PR #83521 that injected issue #85435 (and thus exposed underlying issue #85561). --- .../src/build/expr/as_rvalue.rs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) 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 92a2a7bc17a..1345531f3c6 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, + ); + } } } From 4742bbb48b25df49a8b88db29c0259ba08b54ca5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 21 May 2021 15:05:53 -0400 Subject: [PATCH 04/16] Regression test for issue 85435. --- ...fe-op-in-let-under-unsafe-under-closure.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs 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..9315edf882b --- /dev/null +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -0,0 +1,28 @@ +// check-pass + +// 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 { + // Fails compilation with: + // error[E0133]: dereference of raw pointer is unsafe and + // requires unsafe function or block + let tmp = *u8_ptr; + tmp + + // Just dereferencing and returning directly compiles fine: + // *u8_ptr + } + }; +} From 0d073c9174aa02c04a321c65f384958b67d43f46 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Fri, 21 May 2021 15:10:56 -0400 Subject: [PATCH 05/16] Apply suggestions from code review (removing confusing comment from my test, since the comment reflects the bad undesirable behavior that is being fixed here.) --- .../issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs | 3 --- 1 file changed, 3 deletions(-) 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 index 9315edf882b..b0d738855d7 100644 --- 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 @@ -15,9 +15,6 @@ fn main() { let u8_ptr: *const u8 = &val; let _closure = || { unsafe { - // Fails compilation with: - // error[E0133]: dereference of raw pointer is unsafe and - // requires unsafe function or block let tmp = *u8_ptr; tmp From 5b802ed6c9fd23214f9201b8e05193c8a2240e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= <77335613+ABouttefeux@users.noreply.github.com> Date: Sat, 22 May 2021 08:59:04 +0200 Subject: [PATCH 06/16] Apply suggestions from code review Co-authored-by: Esteban Kuber --- .../rustc_typeck/src/check/method/suggest.rs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index f46d4205a6b..a36e0553c7a 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { span = item_name.span; - // issue #81576, elision of generic argument when no methode can be found in any implementation + // 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 { @@ -493,22 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.associated_item(*def_id, item_name, Namespace::ValueNS) { // Check for both mode is the same so we avoid suggesting - // incorect associated item. - match (mode, assoc.fn_has_self_parameter) { - (Mode::MethodCall, true) => { - if let SelfSource::MethodCall(_) = source { - // 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 - } else { - false - } + // 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, + (Mode::Path, false, _) => true, _ => false, } } else { @@ -521,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inherent_impls_candidate.dedup(); // number of type to shows at most. const LIMIT: usize = 3; - let mut note = format!("The {item_kind} was found for"); + let mut note = format!("the {item_kind} was found for"); if inherent_impls_candidate.len() > 1 { for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) { From 120691c590c4309fda31994931b9a561b4249c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Sat, 22 May 2021 12:03:37 +0200 Subject: [PATCH 07/16] change from review and show full type if it can be deref --- .../rustc_typeck/src/check/method/suggest.rs | 89 ++++++++----------- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../no-method-suggested-traits.stderr | 24 ++--- src/test/ui/issues/issue-30123.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 20 ++++- ...ethod-not-found-generic-arg-elision.stderr | 46 +++++++--- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 9 files changed, 105 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index a36e0553c7a..109cd3e4bc8 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -388,27 +388,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut ty_str_reported = ty_str.clone(); if let ty::Adt(_, ref generics) = actual.kind() { if generics.len() > 0 { - let candidate_numbers: usize = self - .autoderef(span, actual) - .map(|(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() - } else { - 0 - } - }) - .sum(); - if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { + 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(); } @@ -501,8 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 + && self.tcx.at(span).type_of(*def_id) != rcvr_ty } (Mode::Path, false, _) => true, _ => false, @@ -515,38 +517,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if inherent_impls_candidate.len() > 0 { inherent_impls_candidate.sort(); inherent_impls_candidate.dedup(); + let type_candidates = inherent_impls_candidate + .iter() + .map(|impl_item| self.tcx.at(span).type_of(*impl_item)) + .collect::>(); // number of type to shows at most. - const LIMIT: usize = 3; - let mut note = format!("the {item_kind} was found for"); - if inherent_impls_candidate.len() > 1 { - for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) - { - let impl_ty = self.tcx.at(span).type_of(*impl_item); - note = format!("{} {},", note, impl_ty); - } - let impl_ty = self.tcx.at(span).type_of( - inherent_impls_candidate - [inherent_impls_candidate.len() - 1], - ); - if inherent_impls_candidate.len() > LIMIT { - note = format!("{} {},", note, impl_ty); - } else { - note = format!("{} {} and", note, impl_ty); - } + let limit = if type_candidates.len() == 4 { 4 } else { 3 }; + for ty in type_candidates.iter().take(limit) { + err.note(&format!("the {item_kind} was found for {}", ty)); } - let impl_ty = self - .tcx - .at(span) - .type_of(*inherent_impls_candidate.last().unwrap()); - note = format!("{} {}", note, impl_ty); - if inherent_impls_candidate.len() > LIMIT { - note = format!( - "{} and {} more", - note, - inherent_impls_candidate.len() - LIMIT - ); + if type_candidates.len() > limit { + err.note(&format!( + "the {item_kind} was found for {} more types", + type_candidates.len() - limit + )); } - err.note(&format!("{}.", note)); } } } else { diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index 7203d3ed30e..eb8447ff0f3 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec` in the current scope +error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index a1a3ead5812..56d10d88d8b 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box` in the current scope +error[E0599]: no method named `eat` found for struct `Box` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5507406b0f5..64ddcb81c0a 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 27b128372c0..76a6b447ac1 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,7 @@ 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. + = 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/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 23f01fb861f..3df928b5d80 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -1,6 +1,7 @@ // 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, @@ -19,8 +20,6 @@ impl<'a, const C: usize> Wrapper2<'a, i32, C> { } struct Wrapper(T); - - impl Wrapper { fn method(&self) {} } @@ -62,6 +61,20 @@ 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(); @@ -87,4 +100,7 @@ fn main() { 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 index 65dbabbc143..4a9cfb4fc80 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `distance` found for struct `Point` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:69:23 + --> $DIR/method-not-found-generic-arg-elision.rs:82:23 | LL | struct Point { | --------------- method `distance` not found for this @@ -7,10 +7,10 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: The method was found for 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:71:23 + --> $DIR/method-not-found-generic-arg-elision.rs:84:23 | LL | struct Point { | --------------- method `other` not found for this @@ -19,13 +19,13 @@ 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:74:29 + --> $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:74:18: 74:27]>` + | ^^^^^^ 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:77:13 + --> $DIR/method-not-found-generic-arg-elision.rs:90:13 | LL | struct Wrapper(T); | --------------------- method `method` not found for this @@ -33,10 +33,13 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for 3 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:79:13 + --> $DIR/method-not-found-generic-arg-elision.rs:92:13 | LL | struct Wrapper(T); | --------------------- method `other` not found for this @@ -45,7 +48,7 @@ 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:83:13 + --> $DIR/method-not-found-generic-arg-elision.rs:96:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `method` not found for this @@ -53,10 +56,12 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. + = note: the method was found for Wrapper2<'a, i8, C> + = note: the method was found for Wrapper2<'a, i16, C> + = note: the method was found for 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:85:13 + --> $DIR/method-not-found-generic-arg-elision.rs:98:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `other` not found for this @@ -64,12 +69,25 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:88:7 +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: aborting due to 8 previous errors +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/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index 021899b3082..a477425edc8 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box` in the current scope +error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 6b8ec47d98d..027d7a0e0e4 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From a50f1e949b4f7b3b35ee0be041cbf490d6e21314 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 22 May 2021 11:46:54 +0200 Subject: [PATCH 08/16] Get rid of PreviousDepGraph. --- .../rustc_incremental/src/persist/load.rs | 10 ++-- .../rustc_incremental/src/persist/save.rs | 4 +- compiler/rustc_middle/src/dep_graph/mod.rs | 1 - .../rustc_query_system/src/dep_graph/graph.rs | 15 +++-- .../rustc_query_system/src/dep_graph/mod.rs | 2 - .../rustc_query_system/src/dep_graph/prev.rs | 56 ------------------- .../src/dep_graph/serialized.rs | 40 +++++++++++-- 7 files changed, 49 insertions(+), 79 deletions(-) delete mode 100644 compiler/rustc_query_system/src/dep_graph/prev.rs 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_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_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 }) } } From 1c1d4f907d1aa903a5fecae3fa75298042f5d8d9 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Mon, 24 May 2021 16:50:01 -0400 Subject: [PATCH 09/16] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test THIR unsafeck too Co-authored-by: Léo Lanteri Thauvin --- .../issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs | 2 ++ 1 file changed, 2 insertions(+) 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 index b0d738855d7..72f7b674777 100644 --- 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 @@ -1,4 +1,6 @@ // 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 From e238ee31d4d613da9458a84ad200195518b1bd39 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 24 May 2021 23:34:12 +0100 Subject: [PATCH 10/16] Update cc Recent commits to cc have helped to address #83043 and #43468 --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 4 ++-- compiler/rustc_llvm/Cargo.toml | 2 +- library/profiler_builtins/Cargo.toml | 2 +- library/unwind/Cargo.toml | 2 +- src/bootstrap/Cargo.toml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62734bfaf62..d0607fe4cf1 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_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/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/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" From 5d8e6ea7b9e668578917940d2ab1ba1a51b291b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Tue, 25 May 2021 16:55:30 +0200 Subject: [PATCH 11/16] show list of candidates --- .../rustc_typeck/src/check/method/suggest.rs | 34 ++++++++++++------- src/test/ui/issues/issue-30123.stderr | 3 +- ...ethod-not-found-generic-arg-elision.stderr | 20 ++++++----- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 109cd3e4bc8..569e8719227 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -517,21 +517,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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() - .map(|impl_item| self.tcx.at(span).type_of(*impl_item)) - .collect::>(); - // number of type to shows at most. - let limit = if type_candidates.len() == 4 { 4 } else { 3 }; - for ty in type_candidates.iter().take(limit) { - err.note(&format!("the {item_kind} was found for {}", ty)); - } - if type_candidates.len() > limit { - err.note(&format!( - "the {item_kind} was found for {} more types", - type_candidates.len() - limit - )); - } + .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 { diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 76a6b447ac1..e9d934332f1 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,8 @@ 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 + = 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/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 4a9cfb4fc80..1671e5e5e64 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -7,7 +7,8 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: the method was found for 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 @@ -33,10 +34,12 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for 3 more types + = 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 @@ -56,9 +59,10 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: the method was found for Wrapper2<'a, i8, C> - = note: the method was found for Wrapper2<'a, i16, C> - = note: the method was found for Wrapper2<'a, i32, C> + = 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 From caf6faf95107ab52d1f58b90d6bec764b428fdaa Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 25 May 2021 20:20:05 +0200 Subject: [PATCH 12/16] Remove Iterator #[rustc_on_unimplemented]s that no longer apply. --- library/core/src/iter/traits/iterator.rs | 34 ------------------------ 1 file changed, 34 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e6ed34d3f05..a696c88f663 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", From 128d385e5659f44c0d2a09414adc12cee41119b8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 29 Apr 2021 10:31:44 -0400 Subject: [PATCH 13/16] stabilize member constraints --- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/active.rs | 3 - .../rustc_trait_selection/src/opaque_types.rs | 66 ------------------- .../language-features/member-constraints.md | 29 -------- .../multiple-lifetimes/ret-impl-trait-fg.rs | 7 +- .../ret-impl-trait-no-fg.rs | 20 ------ .../ret-impl-trait-no-fg.stderr | 43 ------------ .../multiple-lifetimes/ret-impl-trait-one.rs | 2 - .../ret-impl-trait-one.stderr | 2 +- .../feature-gate-member-constraints.rs | 10 --- .../feature-gate-member-constraints.stderr | 18 ----- .../error-handling.full_tait.stderr | 4 +- .../error-handling.min_tait.stderr | 2 +- .../multiple-lifetimes/error-handling.rs | 1 - .../multiple-lifetimes/inverse-bounds.rs | 2 - .../ordinary-bounds-pick-original-elided.rs | 8 +-- ...nds-pick-original-type-alias-impl-trait.rs | 7 +- .../ordinary-bounds-pick-original.rs | 8 +-- .../ordinary-bounds-pick-other.rs | 2 - .../ordinary-bounds-unrelated.rs | 2 - .../ordinary-bounds-unrelated.stderr | 4 +- .../ordinary-bounds-unsuited.rs | 4 +- .../ordinary-bounds-unsuited.stderr | 4 +- .../impl-trait/needs_least_region_or_bound.rs | 2 - .../issue-74761.full_tait.stderr | 6 +- .../issue-74761.min_tait.stderr | 4 +- .../ui/type-alias-impl-trait/issue-74761.rs | 1 - 27 files changed, 28 insertions(+), 235 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/member-constraints.md delete mode 100644 src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs delete mode 100644 src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-member-constraints.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-member-constraints.stderr 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_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/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.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/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.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.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/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))] From 45099e6cf6d44bb9cefdda42823794fab2df2703 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 26 May 2021 13:12:54 +0300 Subject: [PATCH 14/16] Add inline attr to private CString::into_inner --- library/std/src/ffi/c_str.rs | 1 + 1 file changed, 1 insertion(+) 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. From b3054d2c2180631f9574ee3c6c3d138ce5e25798 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 26 May 2021 12:05:34 -0400 Subject: [PATCH 15/16] bless compare-mode=nll output --- .../multiple-lifetimes/ret-impl-trait-one.nll.stderr | 2 +- .../multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr | 2 +- .../multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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/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-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> | ^^^^^^^^^^^^^^^^^^ From ff8a3874901303c22bf8d65e5fad870a91ad6121 Mon Sep 17 00:00:00 2001 From: Smitty Date: Wed, 26 May 2021 13:16:26 -0400 Subject: [PATCH 16/16] Remove unneeded workaround This removes a workaround for #24159, which has been fixed. --- compiler/rustc_mir/src/interpret/place.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) 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()`.