about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs31
-rw-r--r--tests/ui/async-await/issue-74047.stderr2
-rw-r--r--tests/ui/issues/issue-3344.stderr2
-rw-r--r--tests/ui/suggestions/missing-assoc-fn.stderr2
5 files changed, 27 insertions, 12 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 0c54fd70c9b..51ec5dd7a28 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>(
         if !missing_items.is_empty() {
             let full_impl_span =
                 tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
-            missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
+            missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
         }
 
         if let Some(missing_items) = must_implement_one_of {
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 8fe4c44fca4..f147b4657cc 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
 
 fn missing_items_err(
     tcx: TyCtxt<'_>,
-    impl_span: Span,
+    impl_def_id: LocalDefId,
     missing_items: &[ty::AssocItem],
     full_impl_span: Span,
 ) {
@@ -211,6 +211,7 @@ fn missing_items_err(
         .collect::<Vec<_>>()
         .join("`, `");
 
+    let impl_span = tcx.def_span(impl_def_id);
     let mut err = struct_span_err!(
         tcx.sess,
         impl_span,
@@ -229,7 +230,11 @@ fn missing_items_err(
         tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
 
     for &trait_item in missing_items {
-        let snippet = suggestion_signature(trait_item, tcx);
+        let snippet = suggestion_signature(
+            tcx,
+            trait_item,
+            tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
+        );
         let code = format!("{}{}\n{}", padding, snippet, padding);
         let msg = format!("implement the missing item: `{snippet}`");
         let appl = Applicability::HasPlaceholders;
@@ -301,11 +306,11 @@ fn default_body_is_unstable(
 /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
 fn bounds_from_generic_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
 ) -> (String, String) {
     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
     let mut projections = vec![];
-    for (predicate, _) in predicates.predicates {
+    for (predicate, _) in predicates {
         debug!("predicate {:?}", predicate);
         let bound_predicate = predicate.kind();
         match bound_predicate.skip_binder() {
@@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>(
     tcx: TyCtxt<'tcx>,
     sig: ty::FnSig<'tcx>,
     ident: Ident,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
     assoc: ty::AssocItem,
 ) -> String {
     let args = sig
@@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
 /// Return placeholder code for the given associated item.
 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
 /// structured suggestion.
-fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
+fn suggestion_signature<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    assoc: ty::AssocItem,
+    impl_trait_ref: ty::TraitRef<'tcx>,
+) -> String {
+    let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
+        tcx,
+        assoc.container_id(tcx),
+        impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
+    );
+
     match assoc.kind {
         ty::AssocKind::Fn => {
             // We skip the binder here because the binder would deanonymize all
@@ -445,9 +460,9 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
             // regions just fine, showing `fn(&MyType)`.
             fn_sig_suggestion(
                 tcx,
-                tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(),
+                tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
                 assoc.ident(tcx),
-                tcx.predicates_of(assoc.def_id),
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
                 assoc,
             )
         }
diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr
index 28174825d8b..9ba73f76923 100644
--- a/tests/ui/async-await/issue-74047.stderr
+++ b/tests/ui/async-await/issue-74047.stderr
@@ -5,7 +5,7 @@ LL | impl TryFrom<OtherStream> for MyStream {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation
    |
    = help: implement the missing item: `type Error = Type;`
-   = help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }`
+   = help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-3344.stderr b/tests/ui/issues/issue-3344.stderr
index 11d5999672e..e849f5d0490 100644
--- a/tests/ui/issues/issue-3344.stderr
+++ b/tests/ui/issues/issue-3344.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
 LL | impl PartialOrd for Thing {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
    |
-   = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }`
+   = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr
index 136ec2152e0..77fa9562878 100644
--- a/tests/ui/suggestions/missing-assoc-fn.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn.stderr
@@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
 LL | impl FromIterator<()> for X {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
    |
-   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }`
+   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
 
 error: aborting due to 3 previous errors