]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/method/suggest.rs
Auto merge of #95662 - Dylan-DPC:rollup-fo7jsr6, r=Dylan-DPC
[rust.git] / compiler / rustc_typeck / src / check / method / suggest.rs
1 //! Give useful errors and suggestions to users when an item can't be
2 //! found or is otherwise invalid.
3
4 use crate::check::FnCtxt;
5 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6 use rustc_errors::{
7     pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
8 };
9 use rustc_hir as hir;
10 use rustc_hir::def_id::{DefId, LocalDefId};
11 use rustc_hir::lang_items::LangItem;
12 use rustc_hir::{ExprKind, Node, QPath};
13 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
14 use rustc_middle::traits::util::supertraits;
15 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
16 use rustc_middle::ty::print::with_crate_prefix;
17 use rustc_middle::ty::ToPolyTraitRef;
18 use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
19 use rustc_span::symbol::{kw, sym, Ident};
20 use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, MultiSpan, Span};
21 use rustc_trait_selection::traits::error_reporting::on_unimplemented::InferCtxtExt as _;
22 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
23 use rustc_trait_selection::traits::{
24     FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedNote,
25 };
26
27 use std::cmp::Ordering;
28 use std::iter;
29
30 use super::probe::Mode;
31 use super::{CandidateSource, MethodError, NoMatchData};
32
33 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34     fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
35         let tcx = self.tcx;
36         match ty.kind() {
37             // Not all of these (e.g., unsafe fns) implement `FnOnce`,
38             // so we look for these beforehand.
39             ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
40             // If it's not a simple function, look for things which implement `FnOnce`.
41             _ => {
42                 let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
43                     return false;
44                 };
45
46                 // This conditional prevents us from asking to call errors and unresolved types.
47                 // It might seem that we can use `predicate_must_hold_modulo_regions`,
48                 // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
49                 // type resolution always gives a "maybe" here.
50                 if self.autoderef(span, ty).any(|(ty, _)| {
51                     info!("check deref {:?} error", ty);
52                     matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
53                 }) {
54                     return false;
55                 }
56
57                 self.autoderef(span, ty).any(|(ty, _)| {
58                     info!("check deref {:?} impl FnOnce", ty);
59                     self.probe(|_| {
60                         let fn_once_substs = tcx.mk_substs_trait(
61                             ty,
62                             &[self
63                                 .next_ty_var(TypeVariableOrigin {
64                                     kind: TypeVariableOriginKind::MiscVariable,
65                                     span,
66                                 })
67                                 .into()],
68                         );
69                         let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
70                         let poly_trait_ref = ty::Binder::dummy(trait_ref);
71                         let obligation = Obligation::misc(
72                             span,
73                             self.body_id,
74                             self.param_env,
75                             poly_trait_ref.without_const().to_predicate(tcx),
76                         );
77                         self.predicate_may_hold(&obligation)
78                     })
79                 })
80             }
81         }
82     }
83
84     fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
85         self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
86     }
87
88     pub fn report_method_error(
89         &self,
90         mut span: Span,
91         rcvr_ty: Ty<'tcx>,
92         item_name: Ident,
93         source: SelfSource<'tcx>,
94         error: MethodError<'tcx>,
95         args: Option<&'tcx [hir::Expr<'tcx>]>,
96     ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
97         // Avoid suggestions when we don't know what's going on.
98         if rcvr_ty.references_error() {
99             return None;
100         }
101
102         let report_candidates = |span: Span,
103                                  err: &mut Diagnostic,
104                                  mut sources: Vec<CandidateSource>,
105                                  sugg_span: Span| {
106             sources.sort();
107             sources.dedup();
108             // Dynamic limit to avoid hiding just one candidate, which is silly.
109             let limit = if sources.len() == 5 { 5 } else { 4 };
110
111             for (idx, source) in sources.iter().take(limit).enumerate() {
112                 match *source {
113                     CandidateSource::Impl(impl_did) => {
114                         // Provide the best span we can. Use the item, if local to crate, else
115                         // the impl, if local to crate (item may be defaulted), else nothing.
116                         let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
117                             let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
118                             self.associated_value(impl_trait_ref.def_id, item_name)
119                         }) else {
120                             continue;
121                         };
122                         let note_span = self
123                             .tcx
124                             .hir()
125                             .span_if_local(item.def_id)
126                             .or_else(|| self.tcx.hir().span_if_local(impl_did));
127
128                         let impl_ty = self.tcx.at(span).type_of(impl_did);
129
130                         let insertion = match self.tcx.impl_trait_ref(impl_did) {
131                             None => String::new(),
132                             Some(trait_ref) => format!(
133                                 " of the trait `{}`",
134                                 self.tcx.def_path_str(trait_ref.def_id)
135                             ),
136                         };
137
138                         let (note_str, idx) = if sources.len() > 1 {
139                             (
140                                 format!(
141                                     "candidate #{} is defined in an impl{} for the type `{}`",
142                                     idx + 1,
143                                     insertion,
144                                     impl_ty,
145                                 ),
146                                 Some(idx + 1),
147                             )
148                         } else {
149                             (
150                                 format!(
151                                     "the candidate is defined in an impl{} for the type `{}`",
152                                     insertion, impl_ty,
153                                 ),
154                                 None,
155                             )
156                         };
157                         if let Some(note_span) = note_span {
158                             // We have a span pointing to the method. Show note with snippet.
159                             err.span_note(
160                                 self.tcx.sess.source_map().guess_head_span(note_span),
161                                 &note_str,
162                             );
163                         } else {
164                             err.note(&note_str);
165                         }
166                         if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
167                             let path = self.tcx.def_path_str(trait_ref.def_id);
168
169                             let ty = match item.kind {
170                                 ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
171                                 ty::AssocKind::Fn => self
172                                     .tcx
173                                     .fn_sig(item.def_id)
174                                     .inputs()
175                                     .skip_binder()
176                                     .get(0)
177                                     .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
178                                     .copied()
179                                     .unwrap_or(rcvr_ty),
180                             };
181                             print_disambiguation_help(
182                                 item_name,
183                                 args,
184                                 err,
185                                 path,
186                                 ty,
187                                 item.kind,
188                                 item.def_id,
189                                 sugg_span,
190                                 idx,
191                                 self.tcx.sess.source_map(),
192                                 item.fn_has_self_parameter,
193                             );
194                         }
195                     }
196                     CandidateSource::Trait(trait_did) => {
197                         let Some(item) = self.associated_value(trait_did, item_name) else { continue };
198                         let item_span = self
199                             .tcx
200                             .sess
201                             .source_map()
202                             .guess_head_span(self.tcx.def_span(item.def_id));
203                         let idx = if sources.len() > 1 {
204                             let msg = &format!(
205                                 "candidate #{} is defined in the trait `{}`",
206                                 idx + 1,
207                                 self.tcx.def_path_str(trait_did)
208                             );
209                             err.span_note(item_span, msg);
210                             Some(idx + 1)
211                         } else {
212                             let msg = &format!(
213                                 "the candidate is defined in the trait `{}`",
214                                 self.tcx.def_path_str(trait_did)
215                             );
216                             err.span_note(item_span, msg);
217                             None
218                         };
219                         let path = self.tcx.def_path_str(trait_did);
220                         print_disambiguation_help(
221                             item_name,
222                             args,
223                             err,
224                             path,
225                             rcvr_ty,
226                             item.kind,
227                             item.def_id,
228                             sugg_span,
229                             idx,
230                             self.tcx.sess.source_map(),
231                             item.fn_has_self_parameter,
232                         );
233                     }
234                 }
235             }
236             if sources.len() > limit {
237                 err.note(&format!("and {} others", sources.len() - limit));
238             }
239         };
240
241         let sugg_span = if let SelfSource::MethodCall(expr) = source {
242             // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
243             self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
244         } else {
245             span
246         };
247
248         match error {
249             MethodError::NoMatch(NoMatchData {
250                 static_candidates: static_sources,
251                 unsatisfied_predicates,
252                 out_of_scope_traits,
253                 lev_candidate,
254                 mode,
255             }) => {
256                 let tcx = self.tcx;
257
258                 let actual = self.resolve_vars_if_possible(rcvr_ty);
259                 let ty_str = self.ty_to_string(actual);
260                 let is_method = mode == Mode::MethodCall;
261                 let item_kind = if is_method {
262                     "method"
263                 } else if actual.is_enum() {
264                     "variant or associated item"
265                 } else {
266                     match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
267                         (Some(name), false) if name.is_lowercase() => "function or associated item",
268                         (Some(_), false) => "associated item",
269                         (Some(_), true) | (None, false) => "variant or associated item",
270                         (None, true) => "variant",
271                     }
272                 };
273                 // FIXME(eddyb) this indentation is probably unnecessary.
274                 let mut err = {
275                     // Suggest clamping down the type if the method that is being attempted to
276                     // be used exists at all, and the type is an ambiguous numeric type
277                     // ({integer}/{float}).
278                     let mut candidates = all_traits(self.tcx)
279                         .into_iter()
280                         .filter_map(|info| self.associated_value(info.def_id, item_name));
281                     // There are methods that are defined on the primitive types and won't be
282                     // found when exploring `all_traits`, but we also need them to be accurate on
283                     // our suggestions (#47759).
284                     let found_assoc = |ty: Ty<'tcx>| {
285                         simplify_type(tcx, ty, TreatParams::AsPlaceholders)
286                             .and_then(|simp| {
287                                 tcx.incoherent_impls(simp)
288                                     .iter()
289                                     .find_map(|&id| self.associated_value(id, item_name))
290                             })
291                             .is_some()
292                     };
293                     let found_candidate = candidates.next().is_some()
294                         || found_assoc(tcx.types.i8)
295                         || found_assoc(tcx.types.i16)
296                         || found_assoc(tcx.types.i32)
297                         || found_assoc(tcx.types.i64)
298                         || found_assoc(tcx.types.i128)
299                         || found_assoc(tcx.types.u8)
300                         || found_assoc(tcx.types.u16)
301                         || found_assoc(tcx.types.u32)
302                         || found_assoc(tcx.types.u64)
303                         || found_assoc(tcx.types.u128)
304                         || found_assoc(tcx.types.f32)
305                         || found_assoc(tcx.types.f32);
306                     if let (true, false, SelfSource::MethodCall(expr), true) = (
307                         actual.is_numeric(),
308                         actual.has_concrete_skeleton(),
309                         source,
310                         found_candidate,
311                     ) {
312                         let mut err = struct_span_err!(
313                             tcx.sess,
314                             span,
315                             E0689,
316                             "can't call {} `{}` on ambiguous numeric type `{}`",
317                             item_kind,
318                             item_name,
319                             ty_str
320                         );
321                         let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
322                         match expr.kind {
323                             ExprKind::Lit(ref lit) => {
324                                 // numeric literal
325                                 let snippet = tcx
326                                     .sess
327                                     .source_map()
328                                     .span_to_snippet(lit.span)
329                                     .unwrap_or_else(|_| "<numeric literal>".to_owned());
330
331                                 // If this is a floating point literal that ends with '.',
332                                 // get rid of it to stop this from becoming a member access.
333                                 let snippet = snippet.strip_suffix('.').unwrap_or(&snippet);
334
335                                 err.span_suggestion(
336                                     lit.span,
337                                     &format!(
338                                         "you must specify a concrete type for this numeric value, \
339                                          like `{}`",
340                                         concrete_type
341                                     ),
342                                     format!("{snippet}_{concrete_type}"),
343                                     Applicability::MaybeIncorrect,
344                                 );
345                             }
346                             ExprKind::Path(QPath::Resolved(_, path)) => {
347                                 // local binding
348                                 if let hir::def::Res::Local(hir_id) = path.res {
349                                     let span = tcx.hir().span(hir_id);
350                                     let snippet = tcx.sess.source_map().span_to_snippet(span);
351                                     let filename = tcx.sess.source_map().span_to_filename(span);
352
353                                     let parent_node =
354                                         self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
355                                     let msg = format!(
356                                         "you must specify a type for this binding, like `{}`",
357                                         concrete_type,
358                                     );
359
360                                     match (filename, parent_node, snippet) {
361                                         (
362                                             FileName::Real(_),
363                                             Node::Local(hir::Local {
364                                                 source: hir::LocalSource::Normal,
365                                                 ty,
366                                                 ..
367                                             }),
368                                             Ok(ref snippet),
369                                         ) => {
370                                             err.span_suggestion(
371                                                 // account for `let x: _ = 42;`
372                                                 //                  ^^^^
373                                                 span.to(ty
374                                                     .as_ref()
375                                                     .map(|ty| ty.span)
376                                                     .unwrap_or(span)),
377                                                 &msg,
378                                                 format!("{}: {}", snippet, concrete_type),
379                                                 Applicability::MaybeIncorrect,
380                                             );
381                                         }
382                                         _ => {
383                                             err.span_label(span, msg);
384                                         }
385                                     }
386                                 }
387                             }
388                             _ => {}
389                         }
390                         err.emit();
391                         return None;
392                     } else {
393                         span = item_name.span;
394
395                         // Don't show generic arguments when the method can't be found in any implementation (#81576).
396                         let mut ty_str_reported = ty_str.clone();
397                         if let ty::Adt(_, generics) = actual.kind() {
398                             if generics.len() > 0 {
399                                 let mut autoderef = self.autoderef(span, actual);
400                                 let candidate_found = autoderef.any(|(ty, _)| {
401                                     if let ty::Adt(adt_deref, _) = ty.kind() {
402                                         self.tcx
403                                             .inherent_impls(adt_deref.did())
404                                             .iter()
405                                             .filter_map(|def_id| {
406                                                 self.associated_value(*def_id, item_name)
407                                             })
408                                             .count()
409                                             >= 1
410                                     } else {
411                                         false
412                                     }
413                                 });
414                                 let has_deref = autoderef.step_count() > 0;
415                                 if !candidate_found
416                                     && !has_deref
417                                     && unsatisfied_predicates.is_empty()
418                                 {
419                                     if let Some((path_string, _)) = ty_str.split_once('<') {
420                                         ty_str_reported = path_string.to_string();
421                                     }
422                                 }
423                             }
424                         }
425
426                         let mut err = struct_span_err!(
427                             tcx.sess,
428                             span,
429                             E0599,
430                             "no {} named `{}` found for {} `{}` in the current scope",
431                             item_kind,
432                             item_name,
433                             actual.prefix_string(self.tcx),
434                             ty_str_reported,
435                         );
436                         if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source {
437                             self.suggest_await_before_method(
438                                 &mut err, item_name, actual, cal, span,
439                             );
440                         }
441                         if let Some(span) =
442                             tcx.resolutions(()).confused_type_with_std_module.get(&span)
443                         {
444                             if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
445                                 err.span_suggestion(
446                                     *span,
447                                     "you are looking for the module in `std`, \
448                                      not the primitive type",
449                                     format!("std::{}", snippet),
450                                     Applicability::MachineApplicable,
451                                 );
452                             }
453                         }
454                         if let ty::RawPtr(_) = &actual.kind() {
455                             err.note(
456                                 "try using `<*const T>::as_ref()` to get a reference to the \
457                                       type behind the pointer: https://doc.rust-lang.org/std/\
458                                       primitive.pointer.html#method.as_ref",
459                             );
460                             err.note(
461                                 "using `<*const T>::as_ref()` on a pointer \
462                                       which is unaligned or points to invalid \
463                                       or uninitialized memory is undefined behavior",
464                             );
465                         }
466                         err
467                     }
468                 };
469
470                 if actual.references_error() {
471                     err.downgrade_to_delayed_bug();
472                 }
473
474                 if let Some(def) = actual.ty_adt_def() {
475                     if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
476                         let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
477                         err.span_label(
478                             def_sp,
479                             format!(
480                                 "{} `{}` not found {}",
481                                 item_kind,
482                                 item_name,
483                                 if def.is_enum() && !is_method { "here" } else { "for this" }
484                             ),
485                         );
486                     }
487                 }
488
489                 if self.is_fn_ty(rcvr_ty, span) {
490                     fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
491                         err.note(
492                             &format!("`{}` is a function, perhaps you wish to call it", name,),
493                         );
494                     }
495
496                     if let SelfSource::MethodCall(expr) = source {
497                         if let Ok(expr_string) = tcx.sess.source_map().span_to_snippet(expr.span) {
498                             report_function(&mut err, expr_string);
499                         } else if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
500                             if let Some(segment) = path.segments.last() {
501                                 report_function(&mut err, segment.ident);
502                             }
503                         }
504                     }
505                 }
506
507                 let mut custom_span_label = false;
508
509                 if !static_sources.is_empty() {
510                     err.note(
511                         "found the following associated functions; to be used as methods, \
512                          functions must have a `self` parameter",
513                     );
514                     err.span_label(span, "this is an associated function, not a method");
515                     custom_span_label = true;
516                 }
517                 if static_sources.len() == 1 {
518                     let ty_str =
519                         if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) {
520                             // When the "method" is resolved through dereferencing, we really want the
521                             // original type that has the associated function for accurate suggestions.
522                             // (#61411)
523                             let ty = tcx.at(span).type_of(*impl_did);
524                             match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) {
525                                 (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
526                                     // Use `actual` as it will have more `substs` filled in.
527                                     self.ty_to_value_string(actual.peel_refs())
528                                 }
529                                 _ => self.ty_to_value_string(ty.peel_refs()),
530                             }
531                         } else {
532                             self.ty_to_value_string(actual.peel_refs())
533                         };
534                     if let SelfSource::MethodCall(expr) = source {
535                         err.span_suggestion(
536                             expr.span.to(span),
537                             "use associated function syntax instead",
538                             format!("{}::{}", ty_str, item_name),
539                             Applicability::MachineApplicable,
540                         );
541                     } else {
542                         err.help(&format!("try with `{}::{}`", ty_str, item_name,));
543                     }
544
545                     report_candidates(span, &mut err, static_sources, sugg_span);
546                 } else if static_sources.len() > 1 {
547                     report_candidates(span, &mut err, static_sources, sugg_span);
548                 }
549
550                 let mut bound_spans = vec![];
551                 let mut restrict_type_params = false;
552                 let mut unsatisfied_bounds = false;
553                 if item_name.name == sym::count && self.is_slice_ty(actual, span) {
554                     let msg = "consider using `len` instead";
555                     if let SelfSource::MethodCall(_expr) = source {
556                         err.span_suggestion_short(
557                             span,
558                             msg,
559                             String::from("len"),
560                             Applicability::MachineApplicable,
561                         );
562                     } else {
563                         err.span_label(span, msg);
564                     }
565                     if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
566                         let iterator_trait = self.tcx.def_path_str(iterator_trait);
567                         err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
568                     }
569                 } else if !unsatisfied_predicates.is_empty() {
570                     let def_span = |def_id| {
571                         self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
572                     };
573                     let mut type_params = FxHashMap::default();
574
575                     // Pick out the list of unimplemented traits on the receiver.
576                     // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
577                     let mut unimplemented_traits = FxHashMap::default();
578                     let mut unimplemented_traits_only = true;
579                     for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
580                         if let (ty::PredicateKind::Trait(p), Some(cause)) =
581                             (predicate.kind().skip_binder(), cause.as_ref())
582                         {
583                             if p.trait_ref.self_ty() != rcvr_ty {
584                                 // This is necessary, not just to keep the errors clean, but also
585                                 // because our derived obligations can wind up with a trait ref that
586                                 // requires a different param_env to be correctly compared.
587                                 continue;
588                             }
589                             unimplemented_traits.entry(p.trait_ref.def_id).or_insert((
590                                 predicate.kind().rebind(p.trait_ref),
591                                 Obligation {
592                                     cause: cause.clone(),
593                                     param_env: self.param_env,
594                                     predicate: predicate.clone(),
595                                     recursion_depth: 0,
596                                 },
597                             ));
598                         }
599                     }
600
601                     // Make sure that, if any traits other than the found ones were involved,
602                     // we don't don't report an unimplemented trait.
603                     // We don't want to say that `iter::Cloned` is not an iterator, just
604                     // because of some non-Clone item being iterated over.
605                     for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
606                         match predicate.kind().skip_binder() {
607                             ty::PredicateKind::Trait(p)
608                                 if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
609                             _ => {
610                                 unimplemented_traits_only = false;
611                                 break;
612                             }
613                         }
614                     }
615
616                     let mut collect_type_param_suggestions =
617                         |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
618                             // We don't care about regions here, so it's fine to skip the binder here.
619                             if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
620                                 (self_ty.kind(), parent_pred.kind().skip_binder())
621                             {
622                                 let node = match p.trait_ref.self_ty().kind() {
623                                     ty::Param(_) => {
624                                         // Account for `fn` items like in `issue-35677.rs` to
625                                         // suggest restricting its type params.
626                                         let did = self.tcx.hir().body_owner_def_id(hir::BodyId {
627                                             hir_id: self.body_id,
628                                         });
629                                         Some(
630                                             self.tcx
631                                                 .hir()
632                                                 .get(self.tcx.hir().local_def_id_to_hir_id(did)),
633                                         )
634                                     }
635                                     ty::Adt(def, _) => def.did().as_local().map(|def_id| {
636                                         self.tcx
637                                             .hir()
638                                             .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
639                                     }),
640                                     _ => None,
641                                 };
642                                 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
643                                     if let Some(g) = kind.generics() {
644                                         let key = match g.where_clause.predicates {
645                                             [.., pred] => (pred.span().shrink_to_hi(), false),
646                                             [] => (
647                                                 g.where_clause.span_for_predicates_or_empty_place(),
648                                                 true,
649                                             ),
650                                         };
651                                         type_params
652                                             .entry(key)
653                                             .or_insert_with(FxHashSet::default)
654                                             .insert(obligation.to_owned());
655                                     }
656                                 }
657                             }
658                         };
659                     let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
660                         let msg = format!(
661                             "doesn't satisfy `{}`",
662                             if obligation.len() > 50 { quiet } else { obligation }
663                         );
664                         match &self_ty.kind() {
665                             // Point at the type that couldn't satisfy the bound.
666                             ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
667                             // Point at the trait object that couldn't satisfy the bound.
668                             ty::Dynamic(preds, _) => {
669                                 for pred in preds.iter() {
670                                     match pred.skip_binder() {
671                                         ty::ExistentialPredicate::Trait(tr) => {
672                                             bound_spans.push((def_span(tr.def_id), msg.clone()))
673                                         }
674                                         ty::ExistentialPredicate::Projection(_)
675                                         | ty::ExistentialPredicate::AutoTrait(_) => {}
676                                     }
677                                 }
678                             }
679                             // Point at the closure that couldn't satisfy the bound.
680                             ty::Closure(def_id, _) => bound_spans
681                                 .push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
682                             _ => {}
683                         }
684                     };
685                     let mut format_pred = |pred: ty::Predicate<'tcx>| {
686                         let bound_predicate = pred.kind();
687                         match bound_predicate.skip_binder() {
688                             ty::PredicateKind::Projection(pred) => {
689                                 let pred = bound_predicate.rebind(pred);
690                                 // `<Foo as Iterator>::Item = String`.
691                                 let projection_ty = pred.skip_binder().projection_ty;
692
693                                 let substs_with_infer_self = tcx.mk_substs(
694                                     iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
695                                         .chain(projection_ty.substs.iter().skip(1)),
696                                 );
697
698                                 let quiet_projection_ty = ty::ProjectionTy {
699                                     substs: substs_with_infer_self,
700                                     item_def_id: projection_ty.item_def_id,
701                                 };
702
703                                 let term = pred.skip_binder().term;
704
705                                 let obligation = format!("{} = {}", projection_ty, term);
706                                 let quiet = format!("{} = {}", quiet_projection_ty, term);
707
708                                 bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
709                                 Some((obligation, projection_ty.self_ty()))
710                             }
711                             ty::PredicateKind::Trait(poly_trait_ref) => {
712                                 let p = poly_trait_ref.trait_ref;
713                                 let self_ty = p.self_ty();
714                                 let path = p.print_only_trait_path();
715                                 let obligation = format!("{}: {}", self_ty, path);
716                                 let quiet = format!("_: {}", path);
717                                 bound_span_label(self_ty, &obligation, &quiet);
718                                 Some((obligation, self_ty))
719                             }
720                             _ => None,
721                         }
722                     };
723
724                     // Find all the requirements that come from a local `impl` block.
725                     let mut skip_list: FxHashSet<_> = Default::default();
726                     let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
727                     for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
728                         .iter()
729                         .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
730                         .filter_map(|(p, parent, c)| match c.code() {
731                             ObligationCauseCode::ImplDerivedObligation(ref data) => {
732                                 Some((&data.derived, p, parent, data.impl_def_id, data.span))
733                             }
734                             _ => None,
735                         })
736                     {
737                         let parent_trait_ref = data.parent_trait_pred;
738                         let path = parent_trait_ref.print_modifiers_and_trait_path();
739                         let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
740                         let unsatisfied_msg = "unsatisfied trait bound introduced here".to_string();
741                         let derive_msg =
742                             "unsatisfied trait bound introduced in this `derive` macro";
743                         match self.tcx.hir().get_if_local(impl_def_id) {
744                             // Unmet obligation comes from a `derive` macro, point at it once to
745                             // avoid multiple span labels pointing at the same place.
746                             Some(Node::Item(hir::Item {
747                                 kind: hir::ItemKind::Trait(..),
748                                 ident,
749                                 ..
750                             })) if matches!(
751                                 ident.span.ctxt().outer_expn_data().kind,
752                                 ExpnKind::Macro(MacroKind::Derive, _)
753                             ) =>
754                             {
755                                 let span = ident.span.ctxt().outer_expn_data().call_site;
756                                 let mut spans: MultiSpan = span.into();
757                                 spans.push_span_label(span, derive_msg.to_string());
758                                 let entry = spanned_predicates.entry(spans);
759                                 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
760                             }
761
762                             Some(Node::Item(hir::Item {
763                                 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
764                                 ..
765                             })) if matches!(
766                                 self_ty.span.ctxt().outer_expn_data().kind,
767                                 ExpnKind::Macro(MacroKind::Derive, _)
768                             ) || matches!(
769                                 of_trait.as_ref().map(|t| t
770                                     .path
771                                     .span
772                                     .ctxt()
773                                     .outer_expn_data()
774                                     .kind),
775                                 Some(ExpnKind::Macro(MacroKind::Derive, _))
776                             ) =>
777                             {
778                                 let span = self_ty.span.ctxt().outer_expn_data().call_site;
779                                 let mut spans: MultiSpan = span.into();
780                                 spans.push_span_label(span, derive_msg.to_string());
781                                 let entry = spanned_predicates.entry(spans.into());
782                                 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
783                             }
784
785                             // Unmet obligation coming from a `trait`.
786                             Some(Node::Item(hir::Item {
787                                 kind: hir::ItemKind::Trait(..),
788                                 ident,
789                                 span: item_span,
790                                 ..
791                             })) if !matches!(
792                                 ident.span.ctxt().outer_expn_data().kind,
793                                 ExpnKind::Macro(MacroKind::Derive, _)
794                             ) =>
795                             {
796                                 if let Some(pred) = parent_p {
797                                     // Done to add the "doesn't satisfy" `span_label`.
798                                     let _ = format_pred(*pred);
799                                 }
800                                 skip_list.insert(p);
801                                 let mut spans = if cause_span != *item_span {
802                                     let mut spans: MultiSpan = cause_span.into();
803                                     spans.push_span_label(cause_span, unsatisfied_msg);
804                                     spans
805                                 } else {
806                                     ident.span.into()
807                                 };
808                                 spans.push_span_label(ident.span, "in this trait".to_string());
809                                 let entry = spanned_predicates.entry(spans.into());
810                                 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
811                             }
812
813                             // Unmet obligation coming from an `impl`.
814                             Some(Node::Item(hir::Item {
815                                 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
816                                 span: item_span,
817                                 ..
818                             })) if !matches!(
819                                 self_ty.span.ctxt().outer_expn_data().kind,
820                                 ExpnKind::Macro(MacroKind::Derive, _)
821                             ) && !matches!(
822                                 of_trait.as_ref().map(|t| t
823                                     .path
824                                     .span
825                                     .ctxt()
826                                     .outer_expn_data()
827                                     .kind),
828                                 Some(ExpnKind::Macro(MacroKind::Derive, _))
829                             ) =>
830                             {
831                                 if let Some(pred) = parent_p {
832                                     // Done to add the "doesn't satisfy" `span_label`.
833                                     let _ = format_pred(*pred);
834                                 }
835                                 skip_list.insert(p);
836                                 let mut spans = if cause_span != *item_span {
837                                     let mut spans: MultiSpan = cause_span.into();
838                                     spans.push_span_label(cause_span, unsatisfied_msg);
839                                     spans
840                                 } else {
841                                     let mut spans = Vec::with_capacity(2);
842                                     if let Some(trait_ref) = of_trait {
843                                         spans.push(trait_ref.path.span);
844                                     }
845                                     spans.push(self_ty.span);
846                                     spans.into()
847                                 };
848                                 if let Some(trait_ref) = of_trait {
849                                     spans.push_span_label(trait_ref.path.span, String::new());
850                                 }
851                                 spans.push_span_label(self_ty.span, String::new());
852
853                                 let entry = spanned_predicates.entry(spans.into());
854                                 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
855                             }
856                             _ => {}
857                         }
858                     }
859                     let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
860                     spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
861                     for (span, (_path, _self_ty, preds)) in spanned_predicates {
862                         let mut preds: Vec<_> = preds
863                             .into_iter()
864                             .filter_map(|pred| format_pred(*pred))
865                             .map(|(p, _)| format!("`{}`", p))
866                             .collect();
867                         preds.sort();
868                         preds.dedup();
869                         let msg = if let [pred] = &preds[..] {
870                             format!("trait bound {} was not satisfied", pred)
871                         } else {
872                             format!(
873                                 "the following trait bounds were not satisfied:\n{}",
874                                 preds.join("\n"),
875                             )
876                         };
877                         err.span_note(span, &msg);
878                         unsatisfied_bounds = true;
879                     }
880
881                     // The requirements that didn't have an `impl` span to show.
882                     let mut bound_list = unsatisfied_predicates
883                         .iter()
884                         .filter_map(|(pred, parent_pred, _cause)| {
885                             format_pred(*pred).map(|(p, self_ty)| {
886                                 collect_type_param_suggestions(self_ty, *pred, &p);
887                                 (
888                                     match parent_pred {
889                                         None => format!("`{}`", &p),
890                                         Some(parent_pred) => match format_pred(*parent_pred) {
891                                             None => format!("`{}`", &p),
892                                             Some((parent_p, _)) => {
893                                                 collect_type_param_suggestions(
894                                                     self_ty,
895                                                     *parent_pred,
896                                                     &p,
897                                                 );
898                                                 format!(
899                                                     "`{}`\nwhich is required by `{}`",
900                                                     p, parent_p
901                                                 )
902                                             }
903                                         },
904                                     },
905                                     *pred,
906                                 )
907                             })
908                         })
909                         .filter(|(_, pred)| !skip_list.contains(&pred))
910                         .map(|(t, _)| t)
911                         .enumerate()
912                         .collect::<Vec<(usize, String)>>();
913
914                     for ((span, empty_where), obligations) in type_params.into_iter() {
915                         restrict_type_params = true;
916                         // #74886: Sort here so that the output is always the same.
917                         let mut obligations = obligations.into_iter().collect::<Vec<_>>();
918                         obligations.sort();
919                         err.span_suggestion_verbose(
920                             span,
921                             &format!(
922                                 "consider restricting the type parameter{s} to satisfy the \
923                                  trait bound{s}",
924                                 s = pluralize!(obligations.len())
925                             ),
926                             format!(
927                                 "{} {}",
928                                 if empty_where { " where" } else { "," },
929                                 obligations.join(", ")
930                             ),
931                             Applicability::MaybeIncorrect,
932                         );
933                     }
934
935                     bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
936                     bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677
937                     bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order.
938
939                     if !bound_list.is_empty() || !skip_list.is_empty() {
940                         let bound_list = bound_list
941                             .into_iter()
942                             .map(|(_, path)| path)
943                             .collect::<Vec<_>>()
944                             .join("\n");
945                         let actual_prefix = actual.prefix_string(self.tcx);
946                         info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
947                         let (primary_message, label) = if unimplemented_traits.len() == 1
948                             && unimplemented_traits_only
949                         {
950                             unimplemented_traits
951                                 .into_iter()
952                                 .next()
953                                 .map(|(_, (trait_ref, obligation))| {
954                                     if trait_ref.self_ty().references_error()
955                                         || actual.references_error()
956                                     {
957                                         // Avoid crashing.
958                                         return (None, None);
959                                     }
960                                     let OnUnimplementedNote { message, label, .. } =
961                                         self.infcx.on_unimplemented_note(trait_ref, &obligation);
962                                     (message, label)
963                                 })
964                                 .unwrap_or((None, None))
965                         } else {
966                             (None, None)
967                         };
968                         let primary_message = primary_message.unwrap_or_else(|| format!(
969                             "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
970                         ));
971                         err.set_primary_message(&primary_message);
972                         if let Some(label) = label {
973                             custom_span_label = true;
974                             err.span_label(span, label);
975                         }
976                         if !bound_list.is_empty() {
977                             err.note(&format!(
978                                 "the following trait bounds were not satisfied:\n{bound_list}"
979                             ));
980                         }
981                         self.suggest_derive(&mut err, &unsatisfied_predicates);
982
983                         unsatisfied_bounds = true;
984                     }
985                 }
986
987                 let mut label_span_not_found = || {
988                     if unsatisfied_predicates.is_empty() {
989                         err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
990                         let is_string_or_ref_str = match actual.kind() {
991                             ty::Ref(_, ty, _) => {
992                                 ty.is_str()
993                                     || matches!(
994                                         ty.kind(),
995                                         ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
996                                     )
997                             }
998                             ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
999                             _ => false,
1000                         };
1001                         if is_string_or_ref_str && item_name.name == sym::iter {
1002                             err.span_suggestion_verbose(
1003                                 item_name.span,
1004                                 "because of the in-memory representation of `&str`, to obtain \
1005                                  an `Iterator` over each of its codepoint use method `chars`",
1006                                 String::from("chars"),
1007                                 Applicability::MachineApplicable,
1008                             );
1009                         }
1010                         if let ty::Adt(adt, _) = rcvr_ty.kind() {
1011                             let mut inherent_impls_candidate = self
1012                                 .tcx
1013                                 .inherent_impls(adt.did())
1014                                 .iter()
1015                                 .copied()
1016                                 .filter(|def_id| {
1017                                     if let Some(assoc) = self.associated_value(*def_id, item_name) {
1018                                         // Check for both mode is the same so we avoid suggesting
1019                                         // incorrect associated item.
1020                                         match (mode, assoc.fn_has_self_parameter, source) {
1021                                             (Mode::MethodCall, true, SelfSource::MethodCall(_)) => {
1022                                                 // We check that the suggest type is actually
1023                                                 // different from the received one
1024                                                 // So we avoid suggestion method with Box<Self>
1025                                                 // for instance
1026                                                 self.tcx.at(span).type_of(*def_id) != actual
1027                                                     && self.tcx.at(span).type_of(*def_id) != rcvr_ty
1028                                             }
1029                                             (Mode::Path, false, _) => true,
1030                                             _ => false,
1031                                         }
1032                                     } else {
1033                                         false
1034                                     }
1035                                 })
1036                                 .collect::<Vec<_>>();
1037                             if !inherent_impls_candidate.is_empty() {
1038                                 inherent_impls_candidate.sort();
1039                                 inherent_impls_candidate.dedup();
1040
1041                                 // number of type to shows at most.
1042                                 let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
1043                                 let type_candidates = inherent_impls_candidate
1044                                     .iter()
1045                                     .take(limit)
1046                                     .map(|impl_item| {
1047                                         format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
1048                                     })
1049                                     .collect::<Vec<_>>()
1050                                     .join("\n");
1051                                 let additional_types = if inherent_impls_candidate.len() > limit {
1052                                     format!(
1053                                         "\nand {} more types",
1054                                         inherent_impls_candidate.len() - limit
1055                                     )
1056                                 } else {
1057                                     "".to_string()
1058                                 };
1059                                 err.note(&format!(
1060                                     "the {item_kind} was found for\n{}{}",
1061                                     type_candidates, additional_types
1062                                 ));
1063                             }
1064                         }
1065                     } else {
1066                         err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
1067                     }
1068                 };
1069
1070                 // If the method name is the name of a field with a function or closure type,
1071                 // give a helping note that it has to be called as `(x.f)(...)`.
1072                 if let SelfSource::MethodCall(expr) = source {
1073                     let field_receiver =
1074                         self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
1075                             ty::Adt(def, substs) if !def.is_enum() => {
1076                                 let variant = &def.non_enum_variant();
1077                                 self.tcx.find_field_index(item_name, variant).map(|index| {
1078                                     let field = &variant.fields[index];
1079                                     let field_ty = field.ty(tcx, substs);
1080                                     (field, field_ty)
1081                                 })
1082                             }
1083                             _ => None,
1084                         });
1085
1086                     if let Some((field, field_ty)) = field_receiver {
1087                         let scope = self.tcx.parent_module(self.body_id).to_def_id();
1088                         let is_accessible = field.vis.is_accessible_from(scope, self.tcx);
1089
1090                         if is_accessible {
1091                             if self.is_fn_ty(field_ty, span) {
1092                                 let expr_span = expr.span.to(item_name.span);
1093                                 err.multipart_suggestion(
1094                                     &format!(
1095                                         "to call the function stored in `{}`, \
1096                                          surround the field access with parentheses",
1097                                         item_name,
1098                                     ),
1099                                     vec![
1100                                         (expr_span.shrink_to_lo(), '('.to_string()),
1101                                         (expr_span.shrink_to_hi(), ')'.to_string()),
1102                                     ],
1103                                     Applicability::MachineApplicable,
1104                                 );
1105                             } else {
1106                                 let call_expr = self
1107                                     .tcx
1108                                     .hir()
1109                                     .expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1110
1111                                 if let Some(span) = call_expr.span.trim_start(item_name.span) {
1112                                     err.span_suggestion(
1113                                         span,
1114                                         "remove the arguments",
1115                                         String::new(),
1116                                         Applicability::MaybeIncorrect,
1117                                     );
1118                                 }
1119                             }
1120                         }
1121
1122                         let field_kind = if is_accessible { "field" } else { "private field" };
1123                         err.span_label(item_name.span, format!("{}, not a method", field_kind));
1124                     } else if lev_candidate.is_none() && !custom_span_label {
1125                         label_span_not_found();
1126                     }
1127                 } else if !custom_span_label {
1128                     label_span_not_found();
1129                 }
1130
1131                 bound_spans.sort();
1132                 bound_spans.dedup();
1133                 for (span, msg) in bound_spans.into_iter() {
1134                     err.span_label(span, &msg);
1135                 }
1136
1137                 if actual.is_numeric() && actual.is_fresh() || restrict_type_params {
1138                 } else {
1139                     self.suggest_traits_to_import(
1140                         &mut err,
1141                         span,
1142                         rcvr_ty,
1143                         item_name,
1144                         source,
1145                         out_of_scope_traits,
1146                         &unsatisfied_predicates,
1147                         unsatisfied_bounds,
1148                     );
1149                 }
1150
1151                 // Don't emit a suggestion if we found an actual method
1152                 // that had unsatisfied trait bounds
1153                 if unsatisfied_predicates.is_empty() && actual.is_enum() {
1154                     let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
1155                     if let Some(suggestion) = lev_distance::find_best_match_for_name(
1156                         &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
1157                         item_name.name,
1158                         None,
1159                     ) {
1160                         err.span_suggestion(
1161                             span,
1162                             "there is a variant with a similar name",
1163                             suggestion.to_string(),
1164                             Applicability::MaybeIncorrect,
1165                         );
1166                     }
1167                 }
1168
1169                 if item_name.name == sym::as_str && actual.peel_refs().is_str() {
1170                     let msg = "remove this method call";
1171                     let mut fallback_span = true;
1172                     if let SelfSource::MethodCall(expr) = source {
1173                         let call_expr =
1174                             self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1175                         if let Some(span) = call_expr.span.trim_start(expr.span) {
1176                             err.span_suggestion(
1177                                 span,
1178                                 msg,
1179                                 String::new(),
1180                                 Applicability::MachineApplicable,
1181                             );
1182                             fallback_span = false;
1183                         }
1184                     }
1185                     if fallback_span {
1186                         err.span_label(span, msg);
1187                     }
1188                 } else if let Some(lev_candidate) = lev_candidate {
1189                     // Don't emit a suggestion if we found an actual method
1190                     // that had unsatisfied trait bounds
1191                     if unsatisfied_predicates.is_empty() {
1192                         let def_kind = lev_candidate.kind.as_def_kind();
1193                         err.span_suggestion(
1194                             span,
1195                             &format!(
1196                                 "there is {} {} with a similar name",
1197                                 def_kind.article(),
1198                                 def_kind.descr(lev_candidate.def_id),
1199                             ),
1200                             lev_candidate.name.to_string(),
1201                             Applicability::MaybeIncorrect,
1202                         );
1203                     }
1204                 }
1205
1206                 return Some(err);
1207             }
1208
1209             MethodError::Ambiguity(sources) => {
1210                 let mut err = struct_span_err!(
1211                     self.sess(),
1212                     item_name.span,
1213                     E0034,
1214                     "multiple applicable items in scope"
1215                 );
1216                 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
1217
1218                 report_candidates(span, &mut err, sources, sugg_span);
1219                 err.emit();
1220             }
1221
1222             MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
1223                 let kind = kind.descr(def_id);
1224                 let mut err = struct_span_err!(
1225                     self.tcx.sess,
1226                     item_name.span,
1227                     E0624,
1228                     "{} `{}` is private",
1229                     kind,
1230                     item_name
1231                 );
1232                 err.span_label(item_name.span, &format!("private {}", kind));
1233                 let sp = self
1234                     .tcx
1235                     .hir()
1236                     .span_if_local(def_id)
1237                     .unwrap_or_else(|| self.tcx.def_span(def_id));
1238                 err.span_label(sp, &format!("private {} defined here", kind));
1239                 self.suggest_valid_traits(&mut err, out_of_scope_traits);
1240                 err.emit();
1241             }
1242
1243             MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
1244                 let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
1245                 let mut err = self.sess().struct_span_err(span, &msg);
1246                 err.span_label(bound_span, "this has a `Sized` requirement");
1247                 if !candidates.is_empty() {
1248                     let help = format!(
1249                         "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
1250                          add a `use` for {one_of_them}:",
1251                         an = if candidates.len() == 1 { "an" } else { "" },
1252                         s = pluralize!(candidates.len()),
1253                         were = if candidates.len() == 1 { "was" } else { "were" },
1254                         one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
1255                     );
1256                     self.suggest_use_candidates(&mut err, help, candidates);
1257                 }
1258                 if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
1259                     if needs_mut {
1260                         let trait_type = self.tcx.mk_ref(
1261                             *region,
1262                             ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
1263                         );
1264                         err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
1265                     }
1266                 }
1267                 err.emit();
1268             }
1269
1270             MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
1271         }
1272         None
1273     }
1274
1275     crate fn note_unmet_impls_on_type(
1276         &self,
1277         err: &mut Diagnostic,
1278         errors: Vec<FulfillmentError<'tcx>>,
1279     ) {
1280         let all_local_types_needing_impls =
1281             errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
1282                 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
1283                     ty::Adt(def, _) => def.did().is_local(),
1284                     _ => false,
1285                 },
1286                 _ => false,
1287             });
1288         let mut preds: Vec<_> = errors
1289             .iter()
1290             .filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
1291                 ty::PredicateKind::Trait(pred) => Some(pred),
1292                 _ => None,
1293             })
1294             .collect();
1295         preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty()));
1296         let def_ids = preds
1297             .iter()
1298             .filter_map(|pred| match pred.self_ty().kind() {
1299                 ty::Adt(def, _) => Some(def.did()),
1300                 _ => None,
1301             })
1302             .collect::<FxHashSet<_>>();
1303         let sm = self.tcx.sess.source_map();
1304         let mut spans: MultiSpan = def_ids
1305             .iter()
1306             .filter_map(|def_id| {
1307                 let span = self.tcx.def_span(*def_id);
1308                 if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
1309             })
1310             .collect::<Vec<_>>()
1311             .into();
1312
1313         for pred in &preds {
1314             match pred.self_ty().kind() {
1315                 ty::Adt(def, _) => {
1316                     spans.push_span_label(
1317                         sm.guess_head_span(self.tcx.def_span(def.did())),
1318                         format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
1319                     );
1320                 }
1321                 _ => {}
1322             }
1323         }
1324
1325         if all_local_types_needing_impls && spans.primary_span().is_some() {
1326             let msg = if preds.len() == 1 {
1327                 format!(
1328                     "an implementation of `{}` might be missing for `{}`",
1329                     preds[0].trait_ref.print_only_trait_path(),
1330                     preds[0].self_ty()
1331                 )
1332             } else {
1333                 format!(
1334                     "the following type{} would have to `impl` {} required trait{} for this \
1335                      operation to be valid",
1336                     pluralize!(def_ids.len()),
1337                     if def_ids.len() == 1 { "its" } else { "their" },
1338                     pluralize!(preds.len()),
1339                 )
1340             };
1341             err.span_note(spans, &msg);
1342         }
1343
1344         let preds: Vec<_> = errors
1345             .iter()
1346             .map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
1347             .collect();
1348         self.suggest_derive(err, &preds);
1349     }
1350
1351     fn suggest_derive(
1352         &self,
1353         err: &mut Diagnostic,
1354         unsatisfied_predicates: &[(
1355             ty::Predicate<'tcx>,
1356             Option<ty::Predicate<'tcx>>,
1357             Option<ObligationCause<'tcx>>,
1358         )],
1359     ) {
1360         let mut derives = Vec::<(String, Span, String)>::new();
1361         let mut traits = Vec::<Span>::new();
1362         for (pred, _, _) in unsatisfied_predicates {
1363             let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
1364             let adt = match trait_pred.self_ty().ty_adt_def() {
1365                 Some(adt) if adt.did().is_local() => adt,
1366                 _ => continue,
1367             };
1368             if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1369                 let can_derive = match diagnostic_name {
1370                     sym::Default => !adt.is_enum(),
1371                     sym::Eq
1372                     | sym::PartialEq
1373                     | sym::Ord
1374                     | sym::PartialOrd
1375                     | sym::Clone
1376                     | sym::Copy
1377                     | sym::Hash
1378                     | sym::Debug => true,
1379                     _ => false,
1380                 };
1381                 if can_derive {
1382                     let self_name = trait_pred.self_ty().to_string();
1383                     let self_span = self.tcx.def_span(adt.did());
1384                     if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
1385                         for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
1386                         {
1387                             if let Some(parent_diagnostic_name) =
1388                                 self.tcx.get_diagnostic_name(super_trait.def_id())
1389                             {
1390                                 derives.push((
1391                                     self_name.clone(),
1392                                     self_span.clone(),
1393                                     parent_diagnostic_name.to_string(),
1394                                 ));
1395                             }
1396                         }
1397                     }
1398                     derives.push((self_name, self_span, diagnostic_name.to_string()));
1399                 } else {
1400                     traits.push(self.tcx.def_span(trait_pred.def_id()));
1401                 }
1402             } else {
1403                 traits.push(self.tcx.def_span(trait_pred.def_id()));
1404             }
1405         }
1406         traits.sort();
1407         traits.dedup();
1408
1409         derives.sort();
1410         derives.dedup();
1411
1412         let mut derives_grouped = Vec::<(String, Span, String)>::new();
1413         for (self_name, self_span, trait_name) in derives.into_iter() {
1414             if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
1415             {
1416                 if last_self_name == &self_name {
1417                     last_trait_names.push_str(format!(", {}", trait_name).as_str());
1418                     continue;
1419                 }
1420             }
1421             derives_grouped.push((self_name, self_span, trait_name));
1422         }
1423
1424         let len = traits.len();
1425         if len > 0 {
1426             let span: MultiSpan = traits.into();
1427             err.span_note(
1428                 span,
1429                 &format!("the following trait{} must be implemented", pluralize!(len),),
1430             );
1431         }
1432
1433         for (self_name, self_span, traits) in &derives_grouped {
1434             err.span_suggestion_verbose(
1435                 self_span.shrink_to_lo(),
1436                 &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits),
1437                 format!("#[derive({})]\n", traits),
1438                 Applicability::MaybeIncorrect,
1439             );
1440         }
1441     }
1442
1443     /// Print out the type for use in value namespace.
1444     fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
1445         match ty.kind() {
1446             ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)),
1447             _ => self.ty_to_string(ty),
1448         }
1449     }
1450
1451     fn suggest_await_before_method(
1452         &self,
1453         err: &mut Diagnostic,
1454         item_name: Ident,
1455         ty: Ty<'tcx>,
1456         call: &hir::Expr<'_>,
1457         span: Span,
1458     ) {
1459         let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1460             Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
1461             _ => return,
1462         };
1463         let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);
1464         debug!("suggest_await_before_method: is_method_exist={}", method_exists);
1465         if method_exists {
1466             err.span_suggestion_verbose(
1467                 span.shrink_to_lo(),
1468                 "consider `await`ing on the `Future` and calling the method on its `Output`",
1469                 "await.".to_string(),
1470                 Applicability::MaybeIncorrect,
1471             );
1472         }
1473     }
1474
1475     fn suggest_use_candidates(
1476         &self,
1477         err: &mut Diagnostic,
1478         mut msg: String,
1479         candidates: Vec<DefId>,
1480     ) {
1481         let parent_map = self.tcx.visible_parent_map(());
1482
1483         // Separate out candidates that must be imported with a glob, because they are named `_`
1484         // and cannot be referred with their identifier.
1485         let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
1486             if let Some(parent_did) = parent_map.get(trait_did) {
1487                 // If the item is re-exported as `_`, we should suggest a glob-import instead.
1488                 if Some(*parent_did) != self.tcx.parent(*trait_did)
1489                     && self
1490                         .tcx
1491                         .module_children(*parent_did)
1492                         .iter()
1493                         .filter(|child| child.res.opt_def_id() == Some(*trait_did))
1494                         .all(|child| child.ident.name == kw::Underscore)
1495                 {
1496                     return false;
1497                 }
1498             }
1499
1500             true
1501         });
1502
1503         let module_did = self.tcx.parent_module(self.body_id);
1504         let (span, found_use) = find_use_placement(self.tcx, module_did);
1505         if let Some(span) = span {
1506             let path_strings = candidates.iter().map(|trait_did| {
1507                 // Produce an additional newline to separate the new use statement
1508                 // from the directly following item.
1509                 let additional_newline = if found_use { "" } else { "\n" };
1510                 format!(
1511                     "use {};\n{}",
1512                     with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
1513                     additional_newline
1514                 )
1515             });
1516
1517             let glob_path_strings = globs.iter().map(|trait_did| {
1518                 let parent_did = parent_map.get(trait_did).unwrap();
1519
1520                 // Produce an additional newline to separate the new use statement
1521                 // from the directly following item.
1522                 let additional_newline = if found_use { "" } else { "\n" };
1523                 format!(
1524                     "use {}::*; // trait {}\n{}",
1525                     with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1526                     self.tcx.item_name(*trait_did),
1527                     additional_newline
1528                 )
1529             });
1530
1531             err.span_suggestions(
1532                 span,
1533                 &msg,
1534                 path_strings.chain(glob_path_strings),
1535                 Applicability::MaybeIncorrect,
1536             );
1537         } else {
1538             let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 };
1539             for (i, trait_did) in candidates.iter().take(limit).enumerate() {
1540                 if candidates.len() + globs.len() > 1 {
1541                     msg.push_str(&format!(
1542                         "\ncandidate #{}: `use {};`",
1543                         i + 1,
1544                         with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1545                     ));
1546                 } else {
1547                     msg.push_str(&format!(
1548                         "\n`use {};`",
1549                         with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1550                     ));
1551                 }
1552             }
1553             for (i, trait_did) in
1554                 globs.iter().take(limit.saturating_sub(candidates.len())).enumerate()
1555             {
1556                 let parent_did = parent_map.get(trait_did).unwrap();
1557
1558                 if candidates.len() + globs.len() > 1 {
1559                     msg.push_str(&format!(
1560                         "\ncandidate #{}: `use {}::*; // trait {}`",
1561                         candidates.len() + i + 1,
1562                         with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1563                         self.tcx.item_name(*trait_did),
1564                     ));
1565                 } else {
1566                     msg.push_str(&format!(
1567                         "\n`use {}::*; // trait {}`",
1568                         with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1569                         self.tcx.item_name(*trait_did),
1570                     ));
1571                 }
1572             }
1573             if candidates.len() > limit {
1574                 msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit));
1575             }
1576             err.note(&msg);
1577         }
1578     }
1579
1580     fn suggest_valid_traits(
1581         &self,
1582         err: &mut Diagnostic,
1583         valid_out_of_scope_traits: Vec<DefId>,
1584     ) -> bool {
1585         if !valid_out_of_scope_traits.is_empty() {
1586             let mut candidates = valid_out_of_scope_traits;
1587             candidates.sort();
1588             candidates.dedup();
1589
1590             // `TryFrom` and `FromIterator` have no methods
1591             let edition_fix = candidates
1592                 .iter()
1593                 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
1594                 .copied();
1595
1596             err.help("items from traits can only be used if the trait is in scope");
1597             let msg = format!(
1598                 "the following {traits_are} implemented but not in scope; \
1599                  perhaps add a `use` for {one_of_them}:",
1600                 traits_are = if candidates.len() == 1 { "trait is" } else { "traits are" },
1601                 one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
1602             );
1603
1604             self.suggest_use_candidates(err, msg, candidates);
1605             if let Some(did) = edition_fix {
1606                 err.note(&format!(
1607                     "'{}' is included in the prelude starting in Edition 2021",
1608                     with_crate_prefix!(self.tcx.def_path_str(did))
1609                 ));
1610             }
1611
1612             true
1613         } else {
1614             false
1615         }
1616     }
1617
1618     fn suggest_traits_to_import(
1619         &self,
1620         err: &mut Diagnostic,
1621         span: Span,
1622         rcvr_ty: Ty<'tcx>,
1623         item_name: Ident,
1624         source: SelfSource<'tcx>,
1625         valid_out_of_scope_traits: Vec<DefId>,
1626         unsatisfied_predicates: &[(
1627             ty::Predicate<'tcx>,
1628             Option<ty::Predicate<'tcx>>,
1629             Option<ObligationCause<'tcx>>,
1630         )],
1631         unsatisfied_bounds: bool,
1632     ) {
1633         let mut alt_rcvr_sugg = false;
1634         if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
1635             debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
1636             let skippable = [
1637                 self.tcx.lang_items().clone_trait(),
1638                 self.tcx.lang_items().deref_trait(),
1639                 self.tcx.lang_items().deref_mut_trait(),
1640                 self.tcx.lang_items().drop_trait(),
1641                 self.tcx.get_diagnostic_item(sym::AsRef),
1642             ];
1643             // Try alternative arbitrary self types that could fulfill this call.
1644             // FIXME: probe for all types that *could* be arbitrary self-types, not
1645             // just this list.
1646             for (rcvr_ty, post) in &[
1647                 (rcvr_ty, ""),
1648                 (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
1649                 (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
1650             ] {
1651                 match self.lookup_probe(
1652                     span,
1653                     item_name,
1654                     *rcvr_ty,
1655                     rcvr,
1656                     crate::check::method::probe::ProbeScope::AllTraits,
1657                 ) {
1658                     Ok(pick) => {
1659                         // If the method is defined for the receiver we have, it likely wasn't `use`d.
1660                         // We point at the method, but we just skip the rest of the check for arbitrary
1661                         // self types and rely on the suggestion to `use` the trait from
1662                         // `suggest_valid_traits`.
1663                         let did = Some(pick.item.container.id());
1664                         let skip = skippable.contains(&did);
1665                         if pick.autoderefs == 0 && !skip {
1666                             err.span_label(
1667                                 pick.item.ident(self.tcx).span,
1668                                 &format!("the method is available for `{}` here", rcvr_ty),
1669                             );
1670                         }
1671                         break;
1672                     }
1673                     Err(MethodError::Ambiguity(_)) => {
1674                         // If the method is defined (but ambiguous) for the receiver we have, it is also
1675                         // likely we haven't `use`d it. It may be possible that if we `Box`/`Pin`/etc.
1676                         // the receiver, then it might disambiguate this method, but I think these
1677                         // suggestions are generally misleading (see #94218).
1678                         break;
1679                     }
1680                     _ => {}
1681                 }
1682
1683                 for (rcvr_ty, pre) in &[
1684                     (self.tcx.mk_lang_item(*rcvr_ty, LangItem::OwnedBox), "Box::new"),
1685                     (self.tcx.mk_lang_item(*rcvr_ty, LangItem::Pin), "Pin::new"),
1686                     (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Arc), "Arc::new"),
1687                     (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Rc), "Rc::new"),
1688                 ] {
1689                     if let Some(new_rcvr_t) = *rcvr_ty && let Ok(pick) = self.lookup_probe(
1690                         span,
1691                         item_name,
1692                         new_rcvr_t,
1693                         rcvr,
1694                         crate::check::method::probe::ProbeScope::AllTraits,
1695                     ) {
1696                         debug!("try_alt_rcvr: pick candidate {:?}", pick);
1697                         let did = Some(pick.item.container.id());
1698                         // We don't want to suggest a container type when the missing
1699                         // method is `.clone()` or `.deref()` otherwise we'd suggest
1700                         // `Arc::new(foo).clone()`, which is far from what the user wants.
1701                         // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
1702                         // implement the `AsRef` trait.
1703                         let skip = skippable.contains(&did)
1704                             || (("Pin::new" == *pre) && (sym::as_ref == item_name.name));
1705                         // Make sure the method is defined for the *actual* receiver: we don't
1706                         // want to treat `Box<Self>` as a receiver if it only works because of
1707                         // an autoderef to `&self`
1708                         if pick.autoderefs == 0 && !skip {
1709                             err.span_label(
1710                                 pick.item.ident(self.tcx).span,
1711                                 &format!("the method is available for `{}` here", new_rcvr_t),
1712                             );
1713                             err.multipart_suggestion(
1714                                 "consider wrapping the receiver expression with the \
1715                                     appropriate type",
1716                                 vec![
1717                                     (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1718                                     (rcvr.span.shrink_to_hi(), ")".to_string()),
1719                                 ],
1720                                 Applicability::MaybeIncorrect,
1721                             );
1722                             // We don't care about the other suggestions.
1723                             alt_rcvr_sugg = true;
1724                         }
1725                     }
1726                 }
1727             }
1728         }
1729         if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1730             return;
1731         }
1732
1733         let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1734
1735         let mut arbitrary_rcvr = vec![];
1736         // There are no traits implemented, so lets suggest some traits to
1737         // implement, by finding ones that have the item name, and are
1738         // legal to implement.
1739         let mut candidates = all_traits(self.tcx)
1740             .into_iter()
1741             // Don't issue suggestions for unstable traits since they're
1742             // unlikely to be implementable anyway
1743             .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1744                 Some(attr) => attr.level.is_stable(),
1745                 None => true,
1746             })
1747             .filter(|info| {
1748                 // We approximate the coherence rules to only suggest
1749                 // traits that are legal to implement by requiring that
1750                 // either the type or trait is local. Multi-dispatch means
1751                 // this isn't perfect (that is, there are cases when
1752                 // implementing a trait would be legal but is rejected
1753                 // here).
1754                 unsatisfied_predicates.iter().all(|(p, _, _)| {
1755                     match p.kind().skip_binder() {
1756                         // Hide traits if they are present in predicates as they can be fixed without
1757                         // having to implement them.
1758                         ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1759                         ty::PredicateKind::Projection(p) => {
1760                             p.projection_ty.item_def_id == info.def_id
1761                         }
1762                         _ => false,
1763                     }
1764                 }) && (type_is_local || info.def_id.is_local())
1765                     && self
1766                         .associated_value(info.def_id, item_name)
1767                         .filter(|item| {
1768                             if let ty::AssocKind::Fn = item.kind {
1769                                 let id = item
1770                                     .def_id
1771                                     .as_local()
1772                                     .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1773                                 if let Some(hir::Node::TraitItem(hir::TraitItem {
1774                                     kind: hir::TraitItemKind::Fn(fn_sig, method),
1775                                     ..
1776                                 })) = id.map(|id| self.tcx.hir().get(id))
1777                                 {
1778                                     let self_first_arg = match method {
1779                                         hir::TraitFn::Required([ident, ..]) => {
1780                                             ident.name == kw::SelfLower
1781                                         }
1782                                         hir::TraitFn::Provided(body_id) => {
1783                                             self.tcx.hir().body(*body_id).params.first().map_or(
1784                                                 false,
1785                                                 |param| {
1786                                                     matches!(
1787                                                         param.pat.kind,
1788                                                         hir::PatKind::Binding(_, _, ident, _)
1789                                                             if ident.name == kw::SelfLower
1790                                                     )
1791                                                 },
1792                                             )
1793                                         }
1794                                         _ => false,
1795                                     };
1796
1797                                     if !fn_sig.decl.implicit_self.has_implicit_self()
1798                                         && self_first_arg
1799                                     {
1800                                         if let Some(ty) = fn_sig.decl.inputs.get(0) {
1801                                             arbitrary_rcvr.push(ty.span);
1802                                         }
1803                                         return false;
1804                                     }
1805                                 }
1806                             }
1807                             // We only want to suggest public or local traits (#45781).
1808                             item.vis.is_public() || info.def_id.is_local()
1809                         })
1810                         .is_some()
1811             })
1812             .collect::<Vec<_>>();
1813         for span in &arbitrary_rcvr {
1814             err.span_label(
1815                 *span,
1816                 "the method might not be found because of this arbitrary self type",
1817             );
1818         }
1819         if alt_rcvr_sugg {
1820             return;
1821         }
1822
1823         if !candidates.is_empty() {
1824             // Sort from most relevant to least relevant.
1825             candidates.sort_by(|a, b| a.cmp(b).reverse());
1826             candidates.dedup();
1827
1828             let param_type = match rcvr_ty.kind() {
1829                 ty::Param(param) => Some(param),
1830                 ty::Ref(_, ty, _) => match ty.kind() {
1831                     ty::Param(param) => Some(param),
1832                     _ => None,
1833                 },
1834                 _ => None,
1835             };
1836             err.help(if param_type.is_some() {
1837                 "items from traits can only be used if the type parameter is bounded by the trait"
1838             } else {
1839                 "items from traits can only be used if the trait is implemented and in scope"
1840             });
1841             let candidates_len = candidates.len();
1842             let message = |action| {
1843                 format!(
1844                     "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1845                      {one_of_them}:",
1846                     traits_define =
1847                         if candidates_len == 1 { "trait defines" } else { "traits define" },
1848                     action = action,
1849                     one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1850                     name = item_name,
1851                 )
1852             };
1853             // Obtain the span for `param` and use it for a structured suggestion.
1854             if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1855                 let table_owner = table.borrow().hir_owner;
1856                 let generics = self.tcx.generics_of(table_owner.to_def_id());
1857                 let type_param = generics.type_param(param, self.tcx);
1858                 let hir = self.tcx.hir();
1859                 if let Some(def_id) = type_param.def_id.as_local() {
1860                     let id = hir.local_def_id_to_hir_id(def_id);
1861                     // Get the `hir::Param` to verify whether it already has any bounds.
1862                     // We do this to avoid suggesting code that ends up as `T: FooBar`,
1863                     // instead we suggest `T: Foo + Bar` in that case.
1864                     match hir.get(id) {
1865                         Node::GenericParam(param) => {
1866                             let mut impl_trait = false;
1867                             let has_bounds =
1868                                 if let hir::GenericParamKind::Type { synthetic: true, .. } =
1869                                     &param.kind
1870                                 {
1871                                     // We've found `fn foo(x: impl Trait)` instead of
1872                                     // `fn foo<T>(x: T)`. We want to suggest the correct
1873                                     // `fn foo(x: impl Trait + TraitBound)` instead of
1874                                     // `fn foo<T: TraitBound>(x: T)`. (#63706)
1875                                     impl_trait = true;
1876                                     param.bounds.get(1)
1877                                 } else {
1878                                     param.bounds.get(0)
1879                                 };
1880                             let sp = hir.span(id);
1881                             let sp = if let Some(first_bound) = has_bounds {
1882                                 // `sp` only covers `T`, change it so that it covers
1883                                 // `T:` when appropriate
1884                                 sp.until(first_bound.span())
1885                             } else {
1886                                 sp
1887                             };
1888                             let trait_def_ids: FxHashSet<DefId> = param
1889                                 .bounds
1890                                 .iter()
1891                                 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1892                                 .collect();
1893                             if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1894                                 err.span_suggestions(
1895                                     sp,
1896                                     &message(format!(
1897                                         "restrict type parameter `{}` with",
1898                                         param.name.ident(),
1899                                     )),
1900                                     candidates.iter().map(|t| {
1901                                         format!(
1902                                             "{}{} {}{}",
1903                                             param.name.ident(),
1904                                             if impl_trait { " +" } else { ":" },
1905                                             self.tcx.def_path_str(t.def_id),
1906                                             if has_bounds.is_some() { " + " } else { "" },
1907                                         )
1908                                     }),
1909                                     Applicability::MaybeIncorrect,
1910                                 );
1911                             }
1912                             return;
1913                         }
1914                         Node::Item(hir::Item {
1915                             kind: hir::ItemKind::Trait(.., bounds, _),
1916                             ident,
1917                             ..
1918                         }) => {
1919                             let (sp, sep, article) = if bounds.is_empty() {
1920                                 (ident.span.shrink_to_hi(), ":", "a")
1921                             } else {
1922                                 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1923                             };
1924                             err.span_suggestions(
1925                                 sp,
1926                                 &message(format!("add {} supertrait for", article)),
1927                                 candidates.iter().map(|t| {
1928                                     format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1929                                 }),
1930                                 Applicability::MaybeIncorrect,
1931                             );
1932                             return;
1933                         }
1934                         _ => {}
1935                     }
1936                 }
1937             }
1938
1939             let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1940                 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1941                 // cases where a positive bound implies a negative impl.
1942                 (candidates, Vec::new())
1943             } else if let Some(simp_rcvr_ty) =
1944                 simplify_type(self.tcx, rcvr_ty, TreatParams::AsBoundTypes)
1945             {
1946                 let mut potential_candidates = Vec::new();
1947                 let mut explicitly_negative = Vec::new();
1948                 for candidate in candidates {
1949                     // Check if there's a negative impl of `candidate` for `rcvr_ty`
1950                     if self
1951                         .tcx
1952                         .all_impls(candidate.def_id)
1953                         .filter(|imp_did| {
1954                             self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1955                         })
1956                         .any(|imp_did| {
1957                             let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1958                             let imp_simp =
1959                                 simplify_type(self.tcx, imp.self_ty(), TreatParams::AsBoundTypes);
1960                             imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1961                         })
1962                     {
1963                         explicitly_negative.push(candidate);
1964                     } else {
1965                         potential_candidates.push(candidate);
1966                     }
1967                 }
1968                 (potential_candidates, explicitly_negative)
1969             } else {
1970                 // We don't know enough about `recv_ty` to make proper suggestions.
1971                 (candidates, Vec::new())
1972             };
1973
1974             let action = if let Some(param) = param_type {
1975                 format!("restrict type parameter `{}` with", param)
1976             } else {
1977                 // FIXME: it might only need to be imported into scope, not implemented.
1978                 "implement".to_string()
1979             };
1980             match &potential_candidates[..] {
1981                 [] => {}
1982                 [trait_info] if trait_info.def_id.is_local() => {
1983                     let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1984                     err.span_note(
1985                         self.tcx.sess.source_map().guess_head_span(span),
1986                         &format!(
1987                             "`{}` defines an item `{}`, perhaps you need to {} it",
1988                             self.tcx.def_path_str(trait_info.def_id),
1989                             item_name,
1990                             action
1991                         ),
1992                     );
1993                 }
1994                 trait_infos => {
1995                     let mut msg = message(action);
1996                     for (i, trait_info) in trait_infos.iter().enumerate() {
1997                         msg.push_str(&format!(
1998                             "\ncandidate #{}: `{}`",
1999                             i + 1,
2000                             self.tcx.def_path_str(trait_info.def_id),
2001                         ));
2002                     }
2003                     err.note(&msg);
2004                 }
2005             }
2006             match &explicitly_negative[..] {
2007                 [] => {}
2008                 [trait_info] => {
2009                     let msg = format!(
2010                         "the trait `{}` defines an item `{}`, but is explicitly unimplemented",
2011                         self.tcx.def_path_str(trait_info.def_id),
2012                         item_name
2013                     );
2014                     err.note(&msg);
2015                 }
2016                 trait_infos => {
2017                     let mut msg = format!(
2018                         "the following traits define an item `{}`, but are explicitly unimplemented:",
2019                         item_name
2020                     );
2021                     for trait_info in trait_infos {
2022                         msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
2023                     }
2024                     err.note(&msg);
2025                 }
2026             }
2027         }
2028     }
2029
2030     /// Checks whether there is a local type somewhere in the chain of
2031     /// autoderefs of `rcvr_ty`.
2032     fn type_derefs_to_local(
2033         &self,
2034         span: Span,
2035         rcvr_ty: Ty<'tcx>,
2036         source: SelfSource<'tcx>,
2037     ) -> bool {
2038         fn is_local(ty: Ty<'_>) -> bool {
2039             match ty.kind() {
2040                 ty::Adt(def, _) => def.did().is_local(),
2041                 ty::Foreign(did) => did.is_local(),
2042                 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
2043                 ty::Param(_) => true,
2044
2045                 // Everything else (primitive types, etc.) is effectively
2046                 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
2047                 // the noise from these sort of types is usually just really
2048                 // annoying, rather than any sort of help).
2049                 _ => false,
2050             }
2051         }
2052
2053         // This occurs for UFCS desugaring of `T::method`, where there is no
2054         // receiver expression for the method call, and thus no autoderef.
2055         if let SelfSource::QPath(_) = source {
2056             return is_local(self.resolve_vars_with_obligations(rcvr_ty));
2057         }
2058
2059         self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
2060     }
2061 }
2062
2063 #[derive(Copy, Clone, Debug)]
2064 pub enum SelfSource<'a> {
2065     QPath(&'a hir::Ty<'a>),
2066     MethodCall(&'a hir::Expr<'a> /* rcvr */),
2067 }
2068
2069 #[derive(Copy, Clone)]
2070 pub struct TraitInfo {
2071     pub def_id: DefId,
2072 }
2073
2074 impl PartialEq for TraitInfo {
2075     fn eq(&self, other: &TraitInfo) -> bool {
2076         self.cmp(other) == Ordering::Equal
2077     }
2078 }
2079 impl Eq for TraitInfo {}
2080 impl PartialOrd for TraitInfo {
2081     fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
2082         Some(self.cmp(other))
2083     }
2084 }
2085 impl Ord for TraitInfo {
2086     fn cmp(&self, other: &TraitInfo) -> Ordering {
2087         // Local crates are more important than remote ones (local:
2088         // `cnum == 0`), and otherwise we throw in the defid for totality.
2089
2090         let lhs = (other.def_id.krate, other.def_id);
2091         let rhs = (self.def_id.krate, self.def_id);
2092         lhs.cmp(&rhs)
2093     }
2094 }
2095
2096 /// Retrieves all traits in this crate and any dependent crates,
2097 /// and wraps them into `TraitInfo` for custom sorting.
2098 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2099     tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
2100 }
2101
2102 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
2103     // FIXME(#94854): this code uses an out-of-date method for inferring a span
2104     // to suggest. It would be better to thread the ModSpans from the AST into
2105     // the HIR, and then use that to drive the suggestion here.
2106
2107     let mut span = None;
2108     let mut found_use = false;
2109     let (module, _, _) = tcx.hir().get_module(target_module);
2110
2111     // Find a `use` statement.
2112     for &item_id in module.item_ids {
2113         let item = tcx.hir().item(item_id);
2114         match item.kind {
2115             hir::ItemKind::Use(..) => {
2116                 // Don't suggest placing a `use` before the prelude
2117                 // import or other generated ones.
2118                 if !item.span.from_expansion() {
2119                     span = Some(item.span.shrink_to_lo());
2120                     found_use = true;
2121                     break;
2122                 }
2123             }
2124             // Don't place `use` before `extern crate`...
2125             hir::ItemKind::ExternCrate(_) => {}
2126             // ...but do place them before the first other item.
2127             _ => {
2128                 if span.map_or(true, |span| item.span < span) {
2129                     if !item.span.from_expansion() {
2130                         span = Some(item.span.shrink_to_lo());
2131                         // Don't insert between attributes and an item.
2132                         let attrs = tcx.hir().attrs(item.hir_id());
2133                         // Find the first attribute on the item.
2134                         // FIXME: This is broken for active attributes.
2135                         for attr in attrs {
2136                             if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
2137                                 span = Some(attr.span.shrink_to_lo());
2138                             }
2139                         }
2140                     }
2141                 }
2142             }
2143         }
2144     }
2145
2146     (span, found_use)
2147 }
2148
2149 fn print_disambiguation_help<'tcx>(
2150     item_name: Ident,
2151     args: Option<&'tcx [hir::Expr<'tcx>]>,
2152     err: &mut Diagnostic,
2153     trait_name: String,
2154     rcvr_ty: Ty<'_>,
2155     kind: ty::AssocKind,
2156     def_id: DefId,
2157     span: Span,
2158     candidate: Option<usize>,
2159     source_map: &source_map::SourceMap,
2160     fn_has_self_parameter: bool,
2161 ) {
2162     let mut applicability = Applicability::MachineApplicable;
2163     let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
2164         let args = format!(
2165             "({}{})",
2166             if rcvr_ty.is_region_ptr() {
2167                 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
2168             } else {
2169                 ""
2170             },
2171             args.iter()
2172                 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
2173                     applicability = Applicability::HasPlaceholders;
2174                     "_".to_owned()
2175                 }))
2176                 .collect::<Vec<_>>()
2177                 .join(", "),
2178         );
2179         let trait_name = if !fn_has_self_parameter {
2180             format!("<{} as {}>", rcvr_ty, trait_name)
2181         } else {
2182             trait_name
2183         };
2184         (span, format!("{}::{}{}", trait_name, item_name, args))
2185     } else {
2186         (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
2187     };
2188     err.span_suggestion_verbose(
2189         span,
2190         &format!(
2191             "disambiguate the {} for {}",
2192             kind.as_def_kind().descr(def_id),
2193             if let Some(candidate) = candidate {
2194                 format!("candidate #{}", candidate)
2195             } else {
2196                 "the candidate".to_string()
2197             },
2198         ),
2199         sugg,
2200         applicability,
2201     );
2202 }