about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_errors/src/emitter.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs41
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl15
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs15
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs7
-rw-r--r--src/bootstrap/compile.rs1
-rw-r--r--src/bootstrap/tool.rs33
-rw-r--r--tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs24
-rw-r--r--tests/ui/async-await/issue-74047.stderr4
-rw-r--r--tests/ui/extenv/issue-110547.rs7
-rw-r--r--tests/ui/extenv/issue-110547.stderr29
-rw-r--r--tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs5
-rw-r--r--tests/ui/generic-associated-types/missing-item-sugg.rs11
-rw-r--r--tests/ui/generic-associated-types/missing-item-sugg.stderr11
-rw-r--r--tests/ui/issues/issue-3344.stderr2
-rw-r--r--tests/ui/missing/missing-items/m2.stderr2
-rw-r--r--tests/ui/span/issue-23729.stderr2
-rw-r--r--tests/ui/span/issue-23827.stderr2
-rw-r--r--tests/ui/span/issue-24356.stderr2
-rw-r--r--tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs16
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed21
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs21
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr18
-rw-r--r--tests/ui/suggestions/missing-assoc-fn.stderr2
25 files changed, 210 insertions, 84 deletions
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 8c76d5e010f..2498ae2b7bc 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1336,6 +1336,7 @@ impl EmitterWriter {
         //                see?
         for (text, style) in msg.iter() {
             let text = self.translate_message(text, args).map_err(Report::new).unwrap();
+            let text = &normalize_whitespace(&text);
             let lines = text.split('\n').collect::<Vec<_>>();
             if lines.len() > 1 {
                 for (i, line) in lines.iter().enumerate() {
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..4b3f3cf169d 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,16 +460,22 @@ 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,
             )
         }
-        ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
+        ty::AssocKind::Type => {
+            let (generics, where_clauses) = bounds_from_generic_predicates(
+                tcx,
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
+            );
+            format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
+        }
         ty::AssocKind::Const => {
             let ty = tcx.type_of(assoc.def_id).subst_identity();
-            let val = ty_kind_suggestion(ty).unwrap_or("value");
+            let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
             format!("const {}: {} = {};", assoc.name, ty, val)
         }
     }
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 2c537bf4064..6d40df7d0cc 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -3,21 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer =
     .label = used more than once
     .previous_use_label = first use of `{$ident}`
 
-hir_typeck_copy_impl_on_type_with_dtor =
-    the trait `Copy` cannot be implemented for this type; the type has a destructor
-    .label = `Copy` not allowed on types with destructors
-
-hir_typeck_multiple_relaxed_default_bounds =
-    type parameter has more than one relaxed default bound, only one is supported
-
-hir_typeck_copy_impl_on_non_adt =
-    the trait `Copy` cannot be implemented for this type
-    .label = type is not a structure or enumeration
-
-hir_typeck_trait_object_declared_with_no_traits =
-    at least one trait is required for an object type
-    .alias_span = this alias does not contain a trait
-
 hir_typeck_functional_record_update_on_non_struct =
     functional record update syntax requires a struct
 
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index bb574954587..bd52957d162 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> {
     pub(super) search_graph: &'a mut SearchGraph<'tcx>,
 
     pub(super) nested_goals: NestedGoals<'tcx>,
+
+    // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
+    //
+    // If so, then it can no longer be used to make a canonical query response,
+    // since subsequent calls to `try_evaluate_added_goals` have possibly dropped
+    // ambiguous goals. Instead, a probe needs to be introduced somewhere in the
+    // evaluation code.
+    tainted: Result<(), NoSolution>,
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
             max_input_universe: ty::UniverseIndex::ROOT,
             var_values: CanonicalVarValues::dummy(),
             nested_goals: NestedGoals::new(),
+            tainted: Ok(()),
         };
         let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
 
@@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 max_input_universe: canonical_goal.max_universe,
                 search_graph,
                 nested_goals: NestedGoals::new(),
+                tainted: Ok(()),
             };
             ecx.compute_goal(goal)
         })
@@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             },
         );
 
+        if response.is_err() {
+            self.tainted = Err(NoSolution);
+        }
+
         self.nested_goals = goals;
         response
     }
@@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             max_input_universe: self.max_input_universe,
             search_graph: self.search_graph,
             nested_goals: self.nested_goals.clone(),
+            tainted: self.tainted,
         };
         self.infcx.probe(|_| f(&mut ecx))
     }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 23cf0f0c724..2dea36811d8 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -51,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         certainty: Certainty,
     ) -> QueryResult<'tcx> {
         let goals_certainty = self.try_evaluate_added_goals()?;
+        assert_eq!(
+            self.tainted,
+            Ok(()),
+            "EvalCtxt is tainted -- nested goals may have been dropped in a \
+            previous call to `try_evaluate_added_goals!`"
+        );
+
         let certainty = certainty.unify_with(goals_certainty);
 
         let external_constraints = self.compute_external_query_constraints()?;
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8af5927e27f..ab307d4d038 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1328,7 +1328,6 @@ impl Step for Sysroot {
                     true
                 }
             });
-            return INTERNER.intern_path(sysroot);
         }
 
         // Symlink the source root into the same location inside the sysroot,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 79eec6f848c..f8da6df0c7c 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -748,6 +748,7 @@ macro_rules! tool_extended {
        stable = $stable:expr
        $(,tool_std = $tool_std:literal)?
        $(,allow_features = $allow_features:expr)?
+       $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)?
        ;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -790,7 +791,7 @@ macro_rules! tool_extended {
 
             #[allow(unused_mut)]
             fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
-                $builder.ensure(ToolBuild {
+                let tool = $builder.ensure(ToolBuild {
                     compiler: $sel.compiler,
                     target: $sel.target,
                     tool: $tool_name,
@@ -800,7 +801,27 @@ macro_rules! tool_extended {
                     is_optional_tool: true,
                     source_type: SourceType::InTree,
                     allow_features: concat!($($allow_features)*),
-                })
+                })?;
+
+                if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 {
+                    let bindir = $builder.sysroot($sel.compiler).join("bin");
+                    t!(fs::create_dir_all(&bindir));
+
+                    #[allow(unused_variables)]
+                    let tools_out = $builder
+                        .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target);
+
+                    $(for add_bin in $add_bins_to_sysroot {
+                        let bin_source = tools_out.join(exe(add_bin, $sel.target));
+                        let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host));
+                        $builder.copy(&bin_source, &bin_destination);
+                    })?
+
+                    let tool = bindir.join(exe($tool_name, $sel.compiler.host));
+                    Some(tool)
+                } else {
+                    Some(tool)
+                }
             }
         }
         )+
@@ -814,15 +835,15 @@ macro_rules! tool_extended {
 tool_extended!((self, builder),
     Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
     CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
-    Clippy, "src/tools/clippy", "clippy-driver", stable=true;
-    Miri, "src/tools/miri", "miri", stable=false;
-    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true;
+    Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"];
+    Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"];
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"];
     // FIXME: tool_std is not quite right, we shouldn't allow nightly features.
     // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
     // and this is close enough for now.
     Rls, "src/tools/rls", "rls", stable=true, tool_std=true;
     RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true;
-    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true;
+    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
 );
 
 impl<'a> Builder<'a> {
diff --git a/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
new file mode 100644
index 00000000000..d8953eaf597
--- /dev/null
+++ b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
@@ -0,0 +1,24 @@
+// This is a regression test for <https://github.com/rust-lang/rust/issues/46506>.
+// This test ensures that if public re-exported is re-exported, it won't be inlined.
+
+#![crate_name = "foo"]
+
+// @has 'foo/associations/index.html'
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
+// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy'
+// @has 'foo/associations/trait.GroupedBy.html'
+pub mod associations {
+    mod belongs_to {
+        pub trait GroupedBy {}
+    }
+    pub use self::belongs_to::GroupedBy;
+}
+
+// @has 'foo/prelude/index.html'
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;'
+pub mod prelude {
+    pub use associations::GroupedBy;
+}
diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr
index 28174825d8b..6bdb9ded482 100644
--- a/tests/ui/async-await/issue-74047.stderr
+++ b/tests/ui/async-await/issue-74047.stderr
@@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from`
 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: `type Error = /* Type */;`
+   = 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/extenv/issue-110547.rs b/tests/ui/extenv/issue-110547.rs
new file mode 100644
index 00000000000..a6fb96ac066
--- /dev/null
+++ b/tests/ui/extenv/issue-110547.rs
@@ -0,0 +1,7 @@
+// compile-flags: -C debug-assertions
+
+fn main() {
+    env!{"\t"}; //~ ERROR not defined at compile time
+    env!("\t"); //~ ERROR not defined at compile time
+    env!("\u{2069}"); //~ ERROR not defined at compile time
+}
diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr
new file mode 100644
index 00000000000..1219630d346
--- /dev/null
+++ b/tests/ui/extenv/issue-110547.stderr
@@ -0,0 +1,29 @@
+error: environment variable `    ` not defined at compile time
+  --> $DIR/issue-110547.rs:4:5
+   |
+LL |     env!{"\t"};
+   |     ^^^^^^^^^^
+   |
+   = help: use `std::env::var("    ")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: environment variable `    ` not defined at compile time
+  --> $DIR/issue-110547.rs:5:5
+   |
+LL |     env!("\t");
+   |     ^^^^^^^^^^
+   |
+   = help: use `std::env::var("    ")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: environment variable `` not defined at compile time
+  --> $DIR/issue-110547.rs:6:5
+   |
+LL |     env!("\u{2069}");
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: use `std::env::var("")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs
new file mode 100644
index 00000000000..5b10aab4b3f
--- /dev/null
+++ b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs
@@ -0,0 +1,5 @@
+pub trait Foo {
+    type Gat<T>
+    where
+        T: std::fmt::Display;
+}
diff --git a/tests/ui/generic-associated-types/missing-item-sugg.rs b/tests/ui/generic-associated-types/missing-item-sugg.rs
new file mode 100644
index 00000000000..35d573d8188
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-item-sugg.rs
@@ -0,0 +1,11 @@
+// aux-build:missing-item-sugg.rs
+
+extern crate missing_item_sugg;
+
+struct Local;
+impl missing_item_sugg::Foo for Local {
+    //~^ ERROR not all trait items implemented, missing: `Gat`
+}
+//~^ HELP implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing-item-sugg.stderr b/tests/ui/generic-associated-types/missing-item-sugg.stderr
new file mode 100644
index 00000000000..378115f6d38
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-item-sugg.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `Gat`
+  --> $DIR/missing-item-sugg.rs:6:1
+   |
+LL | impl missing_item_sugg::Foo for Local {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation
+   |
+   = help: implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
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/missing/missing-items/m2.stderr b/tests/ui/missing/missing-items/m2.stderr
index d18fb443aa4..835c9b2aa48 100644
--- a/tests/ui/missing/missing-items/m2.stderr
+++ b/tests/ui/missing/missing-items/m2.stderr
@@ -5,7 +5,7 @@ LL | impl m1::X for X {
    | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation
    |
    = help: implement the missing item: `const CONSTANT: u32 = 42;`
-   = help: implement the missing item: `type Type = Type;`
+   = help: implement the missing item: `type Type = /* Type */;`
    = help: implement the missing item: `fn method(&self, _: String) -> <Self as m1::X>::Type { todo!() }`
    = help: implement the missing item: `fn method2(self: Box<Self>, _: String) -> <Self as m1::X>::Type { todo!() }`
    = help: implement the missing item: `fn method3(_: &Self, _: String) -> <Self as m1::X>::Type { todo!() }`
diff --git a/tests/ui/span/issue-23729.stderr b/tests/ui/span/issue-23729.stderr
index f88ce6c88db..cd854e61f2f 100644
--- a/tests/ui/span/issue-23729.stderr
+++ b/tests/ui/span/issue-23729.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
 LL |         impl Iterator for Recurrence {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
    |
-   = help: implement the missing item: `type Item = Type;`
+   = help: implement the missing item: `type Item = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr
index 46a820f1b76..83a9e8c9b98 100644
--- a/tests/ui/span/issue-23827.stderr
+++ b/tests/ui/span/issue-23827.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
 LL | impl<C: Component> FnOnce<(C,)> for Prototype {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
    |
-   = help: implement the missing item: `type Output = Type;`
+   = help: implement the missing item: `type Output = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue-24356.stderr b/tests/ui/span/issue-24356.stderr
index a1f9b255020..cf666e8b4a7 100644
--- a/tests/ui/span/issue-24356.stderr
+++ b/tests/ui/span/issue-24356.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
 LL |         impl Deref for Thing {
    |         ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
    |
-   = help: implement the missing item: `type Target = Type;`
+   = help: implement the missing item: `type Target = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs
new file mode 100644
index 00000000000..b026035a6a1
--- /dev/null
+++ b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs
@@ -0,0 +1,16 @@
+pub trait TraitB {
+    type Item;
+}
+
+pub trait TraitA<A> {
+    type Type;
+
+    fn bar<T>(_: T) -> Self;
+
+    fn baz<T>(_: T) -> Self
+    where
+        T: TraitB,
+        <T as TraitB>::Item: Copy;
+
+    const A: usize;
+}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed
deleted file mode 100644
index a0cb39a3f8a..00000000000
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-rustfix
-trait TraitB {
-    type Item;
-}
-
-trait TraitA<A> {
-    type Type;
-    fn bar<T>(_: T) -> Self;
-    fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-}
-
-struct S;
-struct Type;
-
-impl TraitA<()> for S { //~ ERROR not all trait items implemented
-fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }
-fn bar<T>(_: T) -> Self { todo!() }
-type Type = Type;
-}
-
-fn main() {}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
index c80ede1b2be..11e0c9a3a72 100644
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
+++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
@@ -1,18 +1,15 @@
-// run-rustfix
-trait TraitB {
-    type Item;
-}
+// aux-build:missing-assoc-fn-applicable-suggestions.rs
 
-trait TraitA<A> {
-    type Type;
-    fn bar<T>(_: T) -> Self;
-    fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-}
+extern crate missing_assoc_fn_applicable_suggestions;
+use missing_assoc_fn_applicable_suggestions::TraitA;
 
 struct S;
-struct Type;
-
-impl TraitA<()> for S { //~ ERROR not all trait items implemented
+impl TraitA<()> for S {
+    //~^ ERROR not all trait items implemented
 }
+//~^ HELP implement the missing item: `type Type = /* Type */;`
+//~| HELP implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
+//~| HELP implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
+//~| HELP implement the missing item: `const A: usize = 42;`
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
index 4c75fbe4c78..4c2d2776d3d 100644
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
@@ -1,15 +1,13 @@
-error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`
-  --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1
+error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A`
+  --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1
    |
-LL |     type Type;
-   |     --------- `Type` from trait
-LL |     fn bar<T>(_: T) -> Self;
-   |     ------------------------ `bar` from trait
-LL |     fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-   |     ------------------------------------------------------------------- `baz` from trait
-...
 LL | impl TraitA<()> for S {
-   | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation
+   | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation
+   |
+   = help: implement the missing item: `type Type = /* Type */;`
+   = help: implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
+   = help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
+   = help: implement the missing item: `const A: usize = 42;`
 
 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