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