1 //! Give useful errors and suggestions to users when an item can't be
2 //! found or is otherwise invalid.
6 use rustc_ast::ast::Mutability;
7 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
9 pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
13 use rustc_hir::def::DefKind;
14 use rustc_hir::def_id::DefId;
15 use rustc_hir::lang_items::LangItem;
16 use rustc_hir::{ExprKind, Node, QPath};
17 use rustc_infer::infer::{
18 type_variable::{TypeVariableOrigin, TypeVariableOriginKind},
21 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
22 use rustc_middle::traits::util::supertraits;
23 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
24 use rustc_middle::ty::print::with_crate_prefix;
25 use rustc_middle::ty::{
26 self, DefIdTree, GenericArg, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable,
28 use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
29 use rustc_span::symbol::{kw, sym, Ident};
30 use rustc_span::Symbol;
31 use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span};
32 use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
33 use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;
34 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
35 use rustc_trait_selection::traits::{
36 FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
39 use std::cmp::Ordering;
42 use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
43 use super::{CandidateSource, MethodError, NoMatchData};
45 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
46 fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
49 // Not all of these (e.g., unsafe fns) implement `FnOnce`,
50 // so we look for these beforehand.
51 ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
52 // If it's not a simple function, look for things which implement `FnOnce`.
54 let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
58 // This conditional prevents us from asking to call errors and unresolved types.
59 // It might seem that we can use `predicate_must_hold_modulo_regions`,
60 // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
61 // type resolution always gives a "maybe" here.
62 if self.autoderef(span, ty).any(|(ty, _)| {
63 info!("check deref {:?} error", ty);
64 matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
69 self.autoderef(span, ty).any(|(ty, _)| {
70 info!("check deref {:?} impl FnOnce", ty);
72 let fn_once_substs = tcx.mk_substs_trait(
75 .next_ty_var(TypeVariableOrigin {
76 kind: TypeVariableOriginKind::MiscVariable,
81 let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
82 let poly_trait_ref = ty::Binder::dummy(trait_ref);
83 let obligation = Obligation::misc(
87 poly_trait_ref.without_const().to_predicate(tcx),
89 self.predicate_may_hold(&obligation)
96 fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
97 self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
100 pub fn report_method_error(
105 source: SelfSource<'tcx>,
106 error: MethodError<'tcx>,
107 args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
108 ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
109 // Avoid suggestions when we don't know what's going on.
110 if rcvr_ty.references_error() {
114 let report_candidates = |span: Span,
115 err: &mut Diagnostic,
116 sources: &mut Vec<CandidateSource>,
120 // Dynamic limit to avoid hiding just one candidate, which is silly.
121 let limit = if sources.len() == 5 { 5 } else { 4 };
123 for (idx, source) in sources.iter().take(limit).enumerate() {
125 CandidateSource::Impl(impl_did) => {
126 // Provide the best span we can. Use the item, if local to crate, else
127 // the impl, if local to crate (item may be defaulted), else nothing.
128 let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
129 let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
130 self.associated_value(impl_trait_ref.def_id, item_name)
135 let note_span = if item.def_id.is_local() {
136 Some(self.tcx.def_span(item.def_id))
137 } else if impl_did.is_local() {
138 Some(self.tcx.def_span(impl_did))
143 let impl_ty = self.tcx.at(span).type_of(impl_did);
145 let insertion = match self.tcx.impl_trait_ref(impl_did) {
146 None => String::new(),
147 Some(trait_ref) => format!(
148 " of the trait `{}`",
149 self.tcx.def_path_str(trait_ref.def_id)
153 let (note_str, idx) = if sources.len() > 1 {
156 "candidate #{} is defined in an impl{} for the type `{}`",
166 "the candidate is defined in an impl{} for the type `{}`",
172 if let Some(note_span) = note_span {
173 // We have a span pointing to the method. Show note with snippet.
174 err.span_note(note_span, ¬e_str);
178 if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
179 let path = self.tcx.def_path_str(trait_ref.def_id);
181 let ty = match item.kind {
182 ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
183 ty::AssocKind::Fn => self
189 .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
193 print_disambiguation_help(
203 self.tcx.sess.source_map(),
204 item.fn_has_self_parameter,
208 CandidateSource::Trait(trait_did) => {
209 let Some(item) = self.associated_value(trait_did, item_name) else { continue };
210 let item_span = self.tcx.def_span(item.def_id);
211 let idx = if sources.len() > 1 {
213 "candidate #{} is defined in the trait `{}`",
215 self.tcx.def_path_str(trait_did)
217 err.span_note(item_span, msg);
221 "the candidate is defined in the trait `{}`",
222 self.tcx.def_path_str(trait_did)
224 err.span_note(item_span, msg);
227 let path = self.tcx.def_path_str(trait_did);
228 print_disambiguation_help(
238 self.tcx.sess.source_map(),
239 item.fn_has_self_parameter,
244 if sources.len() > limit {
245 err.note(&format!("and {} others", sources.len() - limit));
249 let sugg_span = if let SelfSource::MethodCall(expr) = source {
250 // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
251 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
257 MethodError::NoMatch(NoMatchData {
258 mut static_candidates,
259 unsatisfied_predicates,
266 let actual = self.resolve_vars_if_possible(rcvr_ty);
267 let ty_str = self.ty_to_string(actual);
268 let is_method = mode == Mode::MethodCall;
269 let item_kind = if is_method {
271 } else if actual.is_enum() {
272 "variant or associated item"
274 match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
275 (Some(name), false) if name.is_lowercase() => "function or associated item",
276 (Some(_), false) => "associated item",
277 (Some(_), true) | (None, false) => "variant or associated item",
278 (None, true) => "variant",
282 if self.suggest_wrapping_range_with_parens(
283 tcx, actual, source, span, item_name, &ty_str,
284 ) || self.suggest_constraining_numerical_ty(
285 tcx, actual, source, span, item_kind, item_name, &ty_str,
289 span = item_name.span;
291 // Don't show generic arguments when the method can't be found in any implementation (#81576).
292 let mut ty_str_reported = ty_str.clone();
293 if let ty::Adt(_, generics) = actual.kind() {
294 if generics.len() > 0 {
295 let mut autoderef = self.autoderef(span, actual);
296 let candidate_found = autoderef.any(|(ty, _)| {
297 if let ty::Adt(adt_def, _) = ty.kind() {
299 .inherent_impls(adt_def.did())
301 .filter_map(|def_id| self.associated_value(*def_id, item_name))
308 let has_deref = autoderef.step_count() > 0;
309 if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
310 if let Some((path_string, _)) = ty_str.split_once('<') {
311 ty_str_reported = path_string.to_string();
317 let mut err = struct_span_err!(
321 "no {} named `{}` found for {} `{}` in the current scope",
324 actual.prefix_string(self.tcx),
327 if actual.references_error() {
328 err.downgrade_to_delayed_bug();
331 if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source {
332 self.suggest_await_before_method(
333 &mut err, item_name, actual, cal, span,
336 if let Some(span) = tcx.resolutions(()).confused_type_with_std_module.get(&span) {
339 "you are looking for the module in `std`, not the primitive type",
341 Applicability::MachineApplicable,
344 if let ty::RawPtr(_) = &actual.kind() {
346 "try using `<*const T>::as_ref()` to get a reference to the \
347 type behind the pointer: https://doc.rust-lang.org/std/\
348 primitive.pointer.html#method.as_ref",
351 "using `<*const T>::as_ref()` on a pointer which is unaligned or points \
352 to invalid or uninitialized memory is undefined behavior",
356 let ty_span = match actual.kind() {
357 ty::Param(param_type) => Some(
358 param_type.span_from_generics(self.tcx, self.body_id.owner.to_def_id()),
360 ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
363 if let Some(span) = ty_span {
367 "{item_kind} `{item_name}` not found for this {}",
368 actual.prefix_string(self.tcx)
373 if let SelfSource::MethodCall(rcvr_expr) = source {
374 self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
378 .expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id));
379 let probe = self.lookup_probe(
384 ProbeScope::AllTraits,
390 let mut custom_span_label = false;
392 if !static_candidates.is_empty() {
394 "found the following associated functions; to be used as methods, \
395 functions must have a `self` parameter",
397 err.span_label(span, "this is an associated function, not a method");
398 custom_span_label = true;
400 if static_candidates.len() == 1 {
401 let mut has_unsuggestable_args = false;
402 let ty_str = if let Some(CandidateSource::Impl(impl_did)) =
403 static_candidates.get(0)
405 // When the "method" is resolved through dereferencing, we really want the
406 // original type that has the associated function for accurate suggestions.
408 let ty = tcx.at(span).type_of(*impl_did);
409 match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) {
410 (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => {
411 // If there are any inferred arguments, (`{integer}`), we should replace
412 // them with underscores to allow the compiler to infer them
413 let infer_substs: Vec<GenericArg<'_>> = substs
416 if !arg.is_suggestable(tcx, true) {
417 has_unsuggestable_args = true;
419 GenericArgKind::Lifetime(_) => self
420 .next_region_var(RegionVariableOrigin::MiscVariable(
421 rustc_span::DUMMY_SP,
424 GenericArgKind::Type(_) => self
425 .next_ty_var(TypeVariableOrigin {
426 span: rustc_span::DUMMY_SP,
427 kind: TypeVariableOriginKind::MiscVariable,
430 GenericArgKind::Const(arg) => self
433 ConstVariableOrigin {
434 span: rustc_span::DUMMY_SP,
435 kind: ConstVariableOriginKind::MiscVariable,
444 .collect::<Vec<_>>();
446 tcx.value_path_str_with_substs(
448 tcx.intern_substs(&infer_substs),
451 _ => self.ty_to_value_string(ty.peel_refs()),
454 self.ty_to_value_string(actual.peel_refs())
456 if let SelfSource::MethodCall(_) = source {
457 let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) &&
458 let Some(assoc) = self.associated_value(*impl_did, item_name) {
459 let sig = self.tcx.fn_sig(assoc.def_id);
460 if let Some(first) = sig.inputs().skip_binder().get(0) {
461 if first.peel_refs() == rcvr_ty.peel_refs() {
464 Some(if first.is_region_ptr() {
465 if first.is_mutable_ptr() { "&mut " } else { "&" }
476 let mut applicability = Applicability::MachineApplicable;
477 let args = if let Some((receiver, args)) = args {
478 // The first arg is the same kind as the receiver
479 let explicit_args = if first_arg.is_some() {
480 std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
482 // There is no `Self` kind to infer the arguments from
483 if has_unsuggestable_args {
484 applicability = Applicability::HasPlaceholders;
486 args.iter().collect()
490 first_arg.unwrap_or(""),
496 .span_to_snippet(arg.span)
497 .unwrap_or_else(|_| {
498 applicability = Applicability::HasPlaceholders;
505 applicability = Applicability::HasPlaceholders;
510 "use associated function syntax instead",
511 format!("{}::{}{}", ty_str, item_name, args),
515 err.help(&format!("try with `{}::{}`", ty_str, item_name,));
518 report_candidates(span, &mut err, &mut static_candidates, sugg_span);
519 } else if static_candidates.len() > 1 {
520 report_candidates(span, &mut err, &mut static_candidates, sugg_span);
523 let mut bound_spans = vec![];
524 let mut restrict_type_params = false;
525 let mut unsatisfied_bounds = false;
526 if item_name.name == sym::count && self.is_slice_ty(actual, span) {
527 let msg = "consider using `len` instead";
528 if let SelfSource::MethodCall(_expr) = source {
529 err.span_suggestion_short(
533 Applicability::MachineApplicable,
536 err.span_label(span, msg);
538 if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
539 let iterator_trait = self.tcx.def_path_str(iterator_trait);
540 err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
542 } else if !unsatisfied_predicates.is_empty() {
543 let mut type_params = FxHashMap::default();
545 // Pick out the list of unimplemented traits on the receiver.
546 // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
547 let mut unimplemented_traits = FxHashMap::default();
548 let mut unimplemented_traits_only = true;
549 for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
550 if let (ty::PredicateKind::Trait(p), Some(cause)) =
551 (predicate.kind().skip_binder(), cause.as_ref())
553 if p.trait_ref.self_ty() != rcvr_ty {
554 // This is necessary, not just to keep the errors clean, but also
555 // because our derived obligations can wind up with a trait ref that
556 // requires a different param_env to be correctly compared.
559 unimplemented_traits.entry(p.trait_ref.def_id).or_insert((
560 predicate.kind().rebind(p.trait_ref),
562 cause: cause.clone(),
563 param_env: self.param_env,
564 predicate: *predicate,
571 // Make sure that, if any traits other than the found ones were involved,
572 // we don't don't report an unimplemented trait.
573 // We don't want to say that `iter::Cloned` is not an iterator, just
574 // because of some non-Clone item being iterated over.
575 for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
576 match predicate.kind().skip_binder() {
577 ty::PredicateKind::Trait(p)
578 if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
580 unimplemented_traits_only = false;
586 let mut collect_type_param_suggestions =
587 |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
588 // We don't care about regions here, so it's fine to skip the binder here.
589 if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
590 (self_ty.kind(), parent_pred.kind().skip_binder())
592 let hir = self.tcx.hir();
593 let node = match p.trait_ref.self_ty().kind() {
595 // Account for `fn` items like in `issue-35677.rs` to
596 // suggest restricting its type params.
598 hir.body_owner(hir::BodyId { hir_id: self.body_id });
599 Some(hir.get(parent_body))
602 def.did().as_local().map(|def_id| hir.get_by_def_id(def_id))
606 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
607 if let Some(g) = kind.generics() {
609 g.tail_span_for_predicate_suggestion(),
610 g.add_where_or_trailing_comma(),
614 .or_insert_with(FxHashSet::default)
615 .insert(obligation.to_owned());
620 let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
622 "doesn't satisfy `{}`",
623 if obligation.len() > 50 { quiet } else { obligation }
625 match &self_ty.kind() {
626 // Point at the type that couldn't satisfy the bound.
628 bound_spans.push((self.tcx.def_span(def.did()), msg))
630 // Point at the trait object that couldn't satisfy the bound.
631 ty::Dynamic(preds, _, _) => {
632 for pred in preds.iter() {
633 match pred.skip_binder() {
634 ty::ExistentialPredicate::Trait(tr) => bound_spans
635 .push((self.tcx.def_span(tr.def_id), msg.clone())),
636 ty::ExistentialPredicate::Projection(_)
637 | ty::ExistentialPredicate::AutoTrait(_) => {}
641 // Point at the closure that couldn't satisfy the bound.
642 ty::Closure(def_id, _) => bound_spans.push((
643 tcx.def_span(*def_id),
644 format!("doesn't satisfy `{}`", quiet),
649 let mut format_pred = |pred: ty::Predicate<'tcx>| {
650 let bound_predicate = pred.kind();
651 match bound_predicate.skip_binder() {
652 ty::PredicateKind::Projection(pred) => {
653 let pred = bound_predicate.rebind(pred);
654 // `<Foo as Iterator>::Item = String`.
655 let projection_ty = pred.skip_binder().projection_ty;
657 let substs_with_infer_self = tcx.mk_substs(
658 iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
659 .chain(projection_ty.substs.iter().skip(1)),
662 let quiet_projection_ty = ty::ProjectionTy {
663 substs: substs_with_infer_self,
664 item_def_id: projection_ty.item_def_id,
667 let term = pred.skip_binder().term;
669 let obligation = format!("{} = {}", projection_ty, term);
670 let quiet = format!("{} = {}", quiet_projection_ty, term);
672 bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
673 Some((obligation, projection_ty.self_ty()))
675 ty::PredicateKind::Trait(poly_trait_ref) => {
676 let p = poly_trait_ref.trait_ref;
677 let self_ty = p.self_ty();
678 let path = p.print_only_trait_path();
679 let obligation = format!("{}: {}", self_ty, path);
680 let quiet = format!("_: {}", path);
681 bound_span_label(self_ty, &obligation, &quiet);
682 Some((obligation, self_ty))
688 // Find all the requirements that come from a local `impl` block.
689 let mut skip_list: FxHashSet<_> = Default::default();
690 let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
691 for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
693 .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
694 .filter_map(|(p, parent, c)| match c.code() {
695 ObligationCauseCode::ImplDerivedObligation(data) => {
696 Some((&data.derived, p, parent, data.impl_def_id, data))
701 let parent_trait_ref = data.parent_trait_pred;
702 let path = parent_trait_ref.print_modifiers_and_trait_path();
703 let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
704 let unsatisfied_msg = "unsatisfied trait bound introduced here";
706 "unsatisfied trait bound introduced in this `derive` macro";
707 match self.tcx.hir().get_if_local(impl_def_id) {
708 // Unmet obligation comes from a `derive` macro, point at it once to
709 // avoid multiple span labels pointing at the same place.
710 Some(Node::Item(hir::Item {
711 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
714 self_ty.span.ctxt().outer_expn_data().kind,
715 ExpnKind::Macro(MacroKind::Derive, _)
717 of_trait.as_ref().map(|t| t
723 Some(ExpnKind::Macro(MacroKind::Derive, _))
726 let span = self_ty.span.ctxt().outer_expn_data().call_site;
727 let mut spans: MultiSpan = span.into();
728 spans.push_span_label(span, derive_msg);
729 let entry = spanned_predicates.entry(spans);
730 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
733 // Unmet obligation coming from an `impl`.
734 Some(Node::Item(hir::Item {
736 hir::ItemKind::Impl(hir::Impl {
737 of_trait, self_ty, generics, ..
743 unsatisfied_predicates.iter().any(|(pred, _, _)| {
744 match pred.kind().skip_binder() {
745 ty::PredicateKind::Trait(pred) => {
747 == self.tcx.lang_items().sized_trait()
748 && pred.polarity == ty::ImplPolarity::Positive
753 for param in generics.params {
754 if param.span == cause.span && sized_pred {
755 let (sp, sugg) = match param.colon_span {
756 Some(sp) => (sp.shrink_to_hi(), " ?Sized +"),
757 None => (param.span.shrink_to_hi(), ": ?Sized"),
759 err.span_suggestion_verbose(
761 "consider relaxing the type parameter's implicit \
764 Applicability::MachineApplicable,
768 if let Some(pred) = parent_p {
769 // Done to add the "doesn't satisfy" `span_label`.
770 let _ = format_pred(*pred);
773 let mut spans = if cause.span != *item_span {
774 let mut spans: MultiSpan = cause.span.into();
775 spans.push_span_label(cause.span, unsatisfied_msg);
778 let mut spans = Vec::with_capacity(2);
779 if let Some(trait_ref) = of_trait {
780 spans.push(trait_ref.path.span);
782 spans.push(self_ty.span);
785 if let Some(trait_ref) = of_trait {
786 spans.push_span_label(trait_ref.path.span, "");
788 spans.push_span_label(self_ty.span, "");
790 let entry = spanned_predicates.entry(spans);
791 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
793 Some(_) => unreachable!(),
797 let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
798 spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
799 for (span, (_path, _self_ty, preds)) in spanned_predicates {
800 let mut preds: Vec<_> = preds
802 .filter_map(|pred| format_pred(*pred))
803 .map(|(p, _)| format!("`{}`", p))
807 let msg = if let [pred] = &preds[..] {
808 format!("trait bound {} was not satisfied", pred)
811 "the following trait bounds were not satisfied:\n{}",
815 err.span_note(span, &msg);
816 unsatisfied_bounds = true;
819 // The requirements that didn't have an `impl` span to show.
820 let mut bound_list = unsatisfied_predicates
822 .filter_map(|(pred, parent_pred, _cause)| {
823 format_pred(*pred).map(|(p, self_ty)| {
824 collect_type_param_suggestions(self_ty, *pred, &p);
827 None => format!("`{}`", &p),
828 Some(parent_pred) => match format_pred(*parent_pred) {
829 None => format!("`{}`", &p),
830 Some((parent_p, _)) => {
831 collect_type_param_suggestions(
837 "`{}`\nwhich is required by `{}`",
847 .filter(|(_, pred)| !skip_list.contains(&pred))
850 .collect::<Vec<(usize, String)>>();
852 for ((span, add_where_or_comma), obligations) in type_params.into_iter() {
853 restrict_type_params = true;
854 // #74886: Sort here so that the output is always the same.
855 let mut obligations = obligations.into_iter().collect::<Vec<_>>();
857 err.span_suggestion_verbose(
860 "consider restricting the type parameter{s} to satisfy the \
862 s = pluralize!(obligations.len())
864 format!("{} {}", add_where_or_comma, obligations.join(", ")),
865 Applicability::MaybeIncorrect,
869 bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
870 bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677
871 bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order.
873 if !bound_list.is_empty() || !skip_list.is_empty() {
874 let bound_list = bound_list
876 .map(|(_, path)| path)
879 let actual_prefix = actual.prefix_string(self.tcx);
880 info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
881 let (primary_message, label) =
882 if unimplemented_traits.len() == 1 && unimplemented_traits_only {
886 .map(|(_, (trait_ref, obligation))| {
887 if trait_ref.self_ty().references_error()
888 || actual.references_error()
893 let OnUnimplementedNote { message, label, .. } = self
895 .on_unimplemented_note(trait_ref, &obligation);
902 let primary_message = primary_message.unwrap_or_else(|| format!(
903 "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
905 err.set_primary_message(&primary_message);
906 if let Some(label) = label {
907 custom_span_label = true;
908 err.span_label(span, label);
910 if !bound_list.is_empty() {
912 "the following trait bounds were not satisfied:\n{bound_list}"
915 self.suggest_derive(&mut err, &unsatisfied_predicates);
917 unsatisfied_bounds = true;
921 let label_span_not_found = |err: &mut Diagnostic| {
922 if unsatisfied_predicates.is_empty() {
923 err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
924 let is_string_or_ref_str = match actual.kind() {
925 ty::Ref(_, ty, _) => {
929 ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
932 ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
935 if is_string_or_ref_str && item_name.name == sym::iter {
936 err.span_suggestion_verbose(
938 "because of the in-memory representation of `&str`, to obtain \
939 an `Iterator` over each of its codepoint use method `chars`",
941 Applicability::MachineApplicable,
944 if let ty::Adt(adt, _) = rcvr_ty.kind() {
945 let mut inherent_impls_candidate = self
947 .inherent_impls(adt.did())
951 if let Some(assoc) = self.associated_value(*def_id, item_name) {
952 // Check for both mode is the same so we avoid suggesting
953 // incorrect associated item.
954 match (mode, assoc.fn_has_self_parameter, source) {
955 (Mode::MethodCall, true, SelfSource::MethodCall(_)) => {
956 // We check that the suggest type is actually
957 // different from the received one
958 // So we avoid suggestion method with Box<Self>
960 self.tcx.at(span).type_of(*def_id) != actual
961 && self.tcx.at(span).type_of(*def_id) != rcvr_ty
963 (Mode::Path, false, _) => true,
970 .collect::<Vec<_>>();
971 if !inherent_impls_candidate.is_empty() {
972 inherent_impls_candidate.sort();
973 inherent_impls_candidate.dedup();
975 // number of type to shows at most.
976 let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
977 let type_candidates = inherent_impls_candidate
981 format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
985 let additional_types = if inherent_impls_candidate.len() > limit {
987 "\nand {} more types",
988 inherent_impls_candidate.len() - limit
994 "the {item_kind} was found for\n{}{}",
995 type_candidates, additional_types
1000 err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
1004 // If the method name is the name of a field with a function or closure type,
1005 // give a helping note that it has to be called as `(x.f)(...)`.
1006 if let SelfSource::MethodCall(expr) = source {
1007 if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err)
1008 && lev_candidate.is_none()
1009 && !custom_span_label
1011 label_span_not_found(&mut err);
1013 } else if !custom_span_label {
1014 label_span_not_found(&mut err);
1017 // Don't suggest (for example) `expr.field.clone()` if `expr.clone()`
1018 // can't be called due to `typeof(expr): Clone` not holding.
1019 if unsatisfied_predicates.is_empty() {
1020 self.suggest_calling_method_on_field(&mut err, source, span, actual, item_name);
1023 self.check_for_inner_self(&mut err, source, span, actual, item_name);
1026 bound_spans.dedup();
1027 for (span, msg) in bound_spans.into_iter() {
1028 err.span_label(span, &msg);
1031 if actual.is_numeric() && actual.is_fresh() || restrict_type_params {
1033 self.suggest_traits_to_import(
1038 args.map(|(_, args)| args.len() + 1),
1040 out_of_scope_traits,
1041 &unsatisfied_predicates,
1047 // Don't emit a suggestion if we found an actual method
1048 // that had unsatisfied trait bounds
1049 if unsatisfied_predicates.is_empty() && actual.is_enum() {
1050 let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
1051 if let Some(suggestion) = lev_distance::find_best_match_for_name(
1052 &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
1056 err.span_suggestion(
1058 "there is a variant with a similar name",
1060 Applicability::MaybeIncorrect,
1065 if item_name.name == sym::as_str && actual.peel_refs().is_str() {
1066 let msg = "remove this method call";
1067 let mut fallback_span = true;
1068 if let SelfSource::MethodCall(expr) = source {
1070 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1071 if let Some(span) = call_expr.span.trim_start(expr.span) {
1072 err.span_suggestion(span, msg, "", Applicability::MachineApplicable);
1073 fallback_span = false;
1077 err.span_label(span, msg);
1079 } else if let Some(lev_candidate) = lev_candidate {
1080 // Don't emit a suggestion if we found an actual method
1081 // that had unsatisfied trait bounds
1082 if unsatisfied_predicates.is_empty() {
1083 let def_kind = lev_candidate.kind.as_def_kind();
1084 // Methods are defined within the context of a struct and their first parameter is always self,
1085 // which represents the instance of the struct the method is being called on
1086 // Associated functions don’t take self as a parameter and
1087 // they are not methods because they don’t have an instance of the struct to work with.
1088 if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter {
1089 err.span_suggestion(
1091 &format!("there is a method with a similar name",),
1093 Applicability::MaybeIncorrect,
1096 err.span_suggestion(
1099 "there is {} {} with a similar name",
1101 def_kind.descr(lev_candidate.def_id),
1104 Applicability::MaybeIncorrect,
1110 self.check_for_deref_method(&mut err, source, rcvr_ty, item_name);
1115 MethodError::Ambiguity(mut sources) => {
1116 let mut err = struct_span_err!(
1120 "multiple applicable items in scope"
1122 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
1124 report_candidates(span, &mut err, &mut sources, sugg_span);
1128 MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
1129 let kind = kind.descr(def_id);
1130 let mut err = struct_span_err!(
1134 "{} `{}` is private",
1138 err.span_label(item_name.span, &format!("private {}", kind));
1142 .span_if_local(def_id)
1143 .unwrap_or_else(|| self.tcx.def_span(def_id));
1144 err.span_label(sp, &format!("private {} defined here", kind));
1145 self.suggest_valid_traits(&mut err, out_of_scope_traits);
1149 MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
1150 let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
1151 let mut err = self.sess().struct_span_err(span, &msg);
1152 err.span_label(bound_span, "this has a `Sized` requirement");
1153 if !candidates.is_empty() {
1155 "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
1156 add a `use` for {one_of_them}:",
1157 an = if candidates.len() == 1 { "an" } else { "" },
1158 s = pluralize!(candidates.len()),
1159 were = pluralize!("was", candidates.len()),
1160 one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
1162 self.suggest_use_candidates(&mut err, help, candidates);
1164 if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
1166 let trait_type = self.tcx.mk_ref(
1168 ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
1170 err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
1176 MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
1181 /// Suggest calling a field with a type that implements the `Fn*` traits instead of a method with
1182 /// the same name as the field i.e. `(a.my_fn_ptr)(10)` instead of `a.my_fn_ptr(10)`.
1183 fn suggest_calling_field_as_fn(
1187 expr: &hir::Expr<'_>,
1189 err: &mut Diagnostic,
1192 let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
1193 ty::Adt(def, substs) if !def.is_enum() => {
1194 let variant = &def.non_enum_variant();
1195 tcx.find_field_index(item_name, variant).map(|index| {
1196 let field = &variant.fields[index];
1197 let field_ty = field.ty(tcx, substs);
1203 if let Some((field, field_ty)) = field_receiver {
1204 let scope = tcx.parent_module(self.body_id);
1205 let is_accessible = field.vis.is_accessible_from(scope, tcx);
1208 if self.is_fn_ty(field_ty, span) {
1209 let expr_span = expr.span.to(item_name.span);
1210 err.multipart_suggestion(
1212 "to call the function stored in `{}`, \
1213 surround the field access with parentheses",
1217 (expr_span.shrink_to_lo(), '('.to_string()),
1218 (expr_span.shrink_to_hi(), ')'.to_string()),
1220 Applicability::MachineApplicable,
1223 let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
1225 if let Some(span) = call_expr.span.trim_start(item_name.span) {
1226 err.span_suggestion(
1228 "remove the arguments",
1230 Applicability::MaybeIncorrect,
1236 let field_kind = if is_accessible { "field" } else { "private field" };
1237 err.span_label(item_name.span, format!("{}, not a method", field_kind));
1243 /// Suggest possible range with adding parentheses, for example:
1244 /// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`.
1245 fn suggest_wrapping_range_with_parens(
1249 source: SelfSource<'tcx>,
1254 if let SelfSource::MethodCall(expr) = source {
1255 for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
1256 if let Node::Expr(parent_expr) = parent {
1257 let lang_item = match parent_expr.kind {
1258 ExprKind::Struct(ref qpath, _, _) => match **qpath {
1259 QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
1260 QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
1261 QPath::LangItem(LangItem::RangeToInclusive, ..) => {
1262 Some(LangItem::RangeToInclusive)
1266 ExprKind::Call(ref func, _) => match func.kind {
1267 // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1268 ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)) => {
1269 Some(LangItem::RangeInclusiveStruct)
1276 if lang_item.is_none() {
1280 let span_included = match parent_expr.kind {
1281 hir::ExprKind::Struct(_, eps, _) => {
1282 eps.len() > 0 && eps.last().map_or(false, |ep| ep.span.contains(span))
1284 // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1285 hir::ExprKind::Call(ref func, ..) => func.span.contains(span),
1293 let range_def_id = self.tcx.require_lang_item(lang_item.unwrap(), None);
1295 self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]);
1297 let pick = self.probe_for_name(
1304 ProbeScope::AllTraits,
1307 let range_span = parent_expr.span.with_hi(expr.span.hi());
1308 tcx.sess.emit_err(errors::MissingParentheseInRange {
1310 ty_str: ty_str.to_string(),
1311 method_name: item_name.as_str().to_string(),
1312 add_missing_parentheses: Some(errors::AddMissingParenthesesInRange {
1313 func_name: item_name.name.as_str().to_string(),
1314 left: range_span.shrink_to_lo(),
1315 right: range_span.shrink_to_hi(),
1326 fn suggest_constraining_numerical_ty(
1330 source: SelfSource<'_>,
1336 let found_candidate = all_traits(self.tcx)
1338 .any(|info| self.associated_value(info.def_id, item_name).is_some());
1339 let found_assoc = |ty: Ty<'tcx>| {
1340 simplify_type(tcx, ty, TreatParams::AsInfer)
1342 tcx.incoherent_impls(simp)
1344 .find_map(|&id| self.associated_value(id, item_name))
1348 let found_candidate = found_candidate
1349 || found_assoc(tcx.types.i8)
1350 || found_assoc(tcx.types.i16)
1351 || found_assoc(tcx.types.i32)
1352 || found_assoc(tcx.types.i64)
1353 || found_assoc(tcx.types.i128)
1354 || found_assoc(tcx.types.u8)
1355 || found_assoc(tcx.types.u16)
1356 || found_assoc(tcx.types.u32)
1357 || found_assoc(tcx.types.u64)
1358 || found_assoc(tcx.types.u128)
1359 || found_assoc(tcx.types.f32)
1360 || found_assoc(tcx.types.f32);
1362 && actual.is_numeric()
1363 && !actual.has_concrete_skeleton()
1364 && let SelfSource::MethodCall(expr) = source
1366 let mut err = struct_span_err!(
1370 "can't call {} `{}` on ambiguous numeric type `{}`",
1375 let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
1377 ExprKind::Lit(ref lit) => {
1382 .span_to_snippet(lit.span)
1383 .unwrap_or_else(|_| "<numeric literal>".to_owned());
1385 // If this is a floating point literal that ends with '.',
1386 // get rid of it to stop this from becoming a member access.
1387 let snippet = snippet.strip_suffix('.').unwrap_or(&snippet);
1388 err.span_suggestion(
1391 "you must specify a concrete type for this numeric value, \
1395 format!("{snippet}_{concrete_type}"),
1396 Applicability::MaybeIncorrect,
1399 ExprKind::Path(QPath::Resolved(_, path)) => {
1401 if let hir::def::Res::Local(hir_id) = path.res {
1402 let span = tcx.hir().span(hir_id);
1403 let filename = tcx.sess.source_map().span_to_filename(span);
1406 self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
1408 "you must specify a type for this binding, like `{}`",
1412 match (filename, parent_node) {
1415 Node::Local(hir::Local {
1416 source: hir::LocalSource::Normal,
1421 let type_span = ty.map(|ty| ty.span.with_lo(span.hi())).unwrap_or(span.shrink_to_hi());
1422 err.span_suggestion(
1423 // account for `let x: _ = 42;`
1427 format!(": {concrete_type}"),
1428 Applicability::MaybeIncorrect,
1432 err.span_label(span, msg);
1445 /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()`
1446 fn suggest_calling_method_on_field(
1448 err: &mut Diagnostic,
1449 source: SelfSource<'tcx>,
1454 if let SelfSource::MethodCall(expr) = source
1455 && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id()
1456 && let Some((fields, substs)) =
1457 self.get_field_candidates_considering_privacy(span, actual, mod_id)
1459 let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1461 let lang_items = self.tcx.lang_items();
1462 let never_mention_traits = [
1463 lang_items.clone_trait(),
1464 lang_items.deref_trait(),
1465 lang_items.deref_mut_trait(),
1466 self.tcx.get_diagnostic_item(sym::AsRef),
1467 self.tcx.get_diagnostic_item(sym::AsMut),
1468 self.tcx.get_diagnostic_item(sym::Borrow),
1469 self.tcx.get_diagnostic_item(sym::BorrowMut),
1471 let candidate_fields: Vec<_> = fields
1472 .filter_map(|candidate_field| {
1473 self.check_for_nested_field_satisfying(
1481 ProbeScope::TraitsInScope,
1483 .map_or(false, |pick| {
1484 !never_mention_traits
1487 .any(|def_id| self.tcx.parent(pick.item.def_id) == *def_id)
1499 .map(|id| id.name.to_ident_string())
1500 .collect::<Vec<String>>()
1505 let len = candidate_fields.len();
1507 err.span_suggestions(
1508 item_name.span.shrink_to_lo(),
1510 "{} of the expressions' fields {} a method of the same name",
1511 if len > 1 { "some" } else { "one" },
1512 if len > 1 { "have" } else { "has" },
1514 candidate_fields.iter().map(|path| format!("{path}.")),
1515 Applicability::MaybeIncorrect,
1521 fn check_for_inner_self(
1523 err: &mut Diagnostic,
1524 source: SelfSource<'tcx>,
1530 let SelfSource::MethodCall(expr) = source else { return; };
1531 let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
1533 let ty::Adt(kind, substs) = actual.kind() else { return; };
1534 match kind.adt_kind() {
1535 ty::AdtKind::Enum => {
1536 let matching_variants: Vec<_> = kind
1539 .flat_map(|variant| {
1540 let [field] = &variant.fields[..] else { return None; };
1541 let field_ty = field.ty(tcx, substs);
1543 // Skip `_`, since that'll just lead to ambiguity.
1544 if self.resolve_vars_if_possible(field_ty).is_ty_var() {
1553 ProbeScope::TraitsInScope,
1556 .map(|pick| (variant, field, pick))
1560 let ret_ty_matches = |diagnostic_item| {
1561 if let Some(ret_ty) = self
1564 .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
1565 && let ty::Adt(kind, _) = ret_ty.kind()
1566 && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
1574 match &matching_variants[..] {
1575 [(_, field, pick)] => {
1576 let self_ty = field.ty(tcx, substs);
1578 tcx.def_span(pick.item.def_id),
1579 &format!("the method `{item_name}` exists on the type `{self_ty}`"),
1581 let (article, kind, variant, question) =
1582 if tcx.is_diagnostic_item(sym::Result, kind.did()) {
1583 ("a", "Result", "Err", ret_ty_matches(sym::Result))
1584 } else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
1585 ("an", "Option", "None", ret_ty_matches(sym::Option))
1590 err.span_suggestion_verbose(
1591 expr.span.shrink_to_hi(),
1593 "use the `?` operator to extract the `{self_ty}` value, propagating \
1594 {article} `{kind}::{variant}` value to the caller"
1597 Applicability::MachineApplicable,
1600 err.span_suggestion_verbose(
1601 expr.span.shrink_to_hi(),
1603 "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
1604 panicking if the value is {article} `{kind}::{variant}`"
1606 ".expect(\"REASON\")",
1607 Applicability::HasPlaceholders,
1611 // FIXME(compiler-errors): Support suggestions for other matching enum variants
1615 // Target wrapper types - types that wrap or pretend to wrap another type,
1616 // perhaps this inner type is meant to be called?
1617 ty::AdtKind::Struct | ty::AdtKind::Union => {
1618 let [first] = ***substs else { return; };
1619 let ty::GenericArgKind::Type(ty) = first.unpack() else { return; };
1620 let Ok(pick) = self.lookup_probe(
1625 ProbeScope::TraitsInScope,
1628 let name = self.ty_to_value_string(actual);
1629 let inner_id = kind.did();
1630 let mutable = if let Some(AutorefOrPtrAdjustment::Autoref { mutbl, .. }) =
1631 pick.autoref_or_ptr_adjustment
1638 if tcx.is_diagnostic_item(sym::LocalKey, inner_id) {
1639 err.help("use `with` or `try_with` to access thread local storage");
1640 } else if Some(kind.did()) == tcx.lang_items().maybe_uninit() {
1642 "if this `{name}` has been initialized, \
1643 use one of the `assume_init` methods to access the inner value"
1645 } else if tcx.is_diagnostic_item(sym::RefCell, inner_id) {
1646 let (suggestion, borrow_kind, panic_if) = match mutable {
1647 Some(Mutability::Not) => (".borrow()", "borrow", "a mutable borrow exists"),
1648 Some(Mutability::Mut) => {
1649 (".borrow_mut()", "mutably borrow", "any borrows exist")
1653 err.span_suggestion_verbose(
1654 expr.span.shrink_to_hi(),
1656 "use `{suggestion}` to {borrow_kind} the `{ty}`, \
1657 panicking if {panic_if}"
1660 Applicability::MaybeIncorrect,
1662 } else if tcx.is_diagnostic_item(sym::Mutex, inner_id) {
1663 err.span_suggestion_verbose(
1664 expr.span.shrink_to_hi(),
1666 "use `.lock().unwrap()` to borrow the `{ty}`, \
1667 blocking the current thread until it can be acquired"
1670 Applicability::MaybeIncorrect,
1672 } else if tcx.is_diagnostic_item(sym::RwLock, inner_id) {
1673 let (suggestion, borrow_kind) = match mutable {
1674 Some(Mutability::Not) => (".read().unwrap()", "borrow"),
1675 Some(Mutability::Mut) => (".write().unwrap()", "mutably borrow"),
1678 err.span_suggestion_verbose(
1679 expr.span.shrink_to_hi(),
1681 "use `{suggestion}` to {borrow_kind} the `{ty}`, \
1682 blocking the current thread until it can be acquired"
1685 Applicability::MaybeIncorrect,
1692 tcx.def_span(pick.item.def_id),
1693 &format!("the method `{item_name}` exists on the type `{ty}`"),
1699 pub(crate) fn note_unmet_impls_on_type(
1701 err: &mut Diagnostic,
1702 errors: Vec<FulfillmentError<'tcx>>,
1704 let all_local_types_needing_impls =
1705 errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
1706 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
1707 ty::Adt(def, _) => def.did().is_local(),
1712 let mut preds: Vec<_> = errors
1714 .filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
1715 ty::PredicateKind::Trait(pred) => Some(pred),
1719 preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty()));
1722 .filter_map(|pred| match pred.self_ty().kind() {
1723 ty::Adt(def, _) => Some(def.did()),
1726 .collect::<FxHashSet<_>>();
1727 let mut spans: MultiSpan = def_ids
1729 .filter_map(|def_id| {
1730 let span = self.tcx.def_span(*def_id);
1731 if span.is_dummy() { None } else { Some(span) }
1733 .collect::<Vec<_>>()
1736 for pred in &preds {
1737 match pred.self_ty().kind() {
1738 ty::Adt(def, _) if def.did().is_local() => {
1739 spans.push_span_label(
1740 self.tcx.def_span(def.did()),
1741 format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
1748 if all_local_types_needing_impls && spans.primary_span().is_some() {
1749 let msg = if preds.len() == 1 {
1751 "an implementation of `{}` might be missing for `{}`",
1752 preds[0].trait_ref.print_only_trait_path(),
1757 "the following type{} would have to `impl` {} required trait{} for this \
1758 operation to be valid",
1759 pluralize!(def_ids.len()),
1760 if def_ids.len() == 1 { "its" } else { "their" },
1761 pluralize!(preds.len()),
1764 err.span_note(spans, &msg);
1767 let preds: Vec<_> = errors
1769 .map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
1771 self.suggest_derive(err, &preds);
1776 err: &mut Diagnostic,
1777 unsatisfied_predicates: &[(
1778 ty::Predicate<'tcx>,
1779 Option<ty::Predicate<'tcx>>,
1780 Option<ObligationCause<'tcx>>,
1783 let mut derives = Vec::<(String, Span, Symbol)>::new();
1784 let mut traits = Vec::<Span>::new();
1785 for (pred, _, _) in unsatisfied_predicates {
1786 let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
1787 let adt = match trait_pred.self_ty().ty_adt_def() {
1788 Some(adt) if adt.did().is_local() => adt,
1791 if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1792 let can_derive = match diagnostic_name {
1793 sym::Default => !adt.is_enum(),
1801 | sym::Debug => true,
1805 let self_name = trait_pred.self_ty().to_string();
1806 let self_span = self.tcx.def_span(adt.did());
1807 if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
1808 for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
1810 if let Some(parent_diagnostic_name) =
1811 self.tcx.get_diagnostic_name(super_trait.def_id())
1816 parent_diagnostic_name,
1821 derives.push((self_name, self_span, diagnostic_name));
1823 traits.push(self.tcx.def_span(trait_pred.def_id()));
1826 traits.push(self.tcx.def_span(trait_pred.def_id()));
1835 let mut derives_grouped = Vec::<(String, Span, String)>::new();
1836 for (self_name, self_span, trait_name) in derives.into_iter() {
1837 if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
1839 if last_self_name == &self_name {
1840 last_trait_names.push_str(format!(", {}", trait_name).as_str());
1844 derives_grouped.push((self_name, self_span, trait_name.to_string()));
1847 let len = traits.len();
1849 let span: MultiSpan = traits.into();
1852 &format!("the following trait{} must be implemented", pluralize!(len),),
1856 for (self_name, self_span, traits) in &derives_grouped {
1857 err.span_suggestion_verbose(
1858 self_span.shrink_to_lo(),
1859 &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits),
1860 format!("#[derive({})]\n", traits),
1861 Applicability::MaybeIncorrect,
1866 fn check_for_deref_method(
1868 err: &mut Diagnostic,
1869 self_source: SelfSource<'tcx>,
1873 let SelfSource::QPath(ty) = self_source else { return; };
1874 for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) {
1875 if let Ok(pick) = self.probe_for_name(
1882 ProbeScope::TraitsInScope,
1884 if deref_ty.is_suggestable(self.tcx, true)
1885 // If this method receives `&self`, then the provided
1886 // argument _should_ coerce, so it's valid to suggest
1887 // just changing the path.
1888 && pick.item.fn_has_self_parameter
1889 && let Some(self_ty) =
1890 self.tcx.fn_sig(pick.item.def_id).inputs().skip_binder().get(0)
1893 let suggested_path = match deref_ty.kind() {
1902 | ty::Param(_) => format!("{deref_ty}"),
1903 _ => format!("<{deref_ty}>"),
1905 err.span_suggestion_verbose(
1907 format!("the function `{item_name}` is implemented on `{deref_ty}`"),
1909 Applicability::MaybeIncorrect,
1914 format!("the function `{item_name}` is implemented on `{deref_ty}`"),
1922 /// Print out the type for use in value namespace.
1923 fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
1925 ty::Adt(def, substs) => self.tcx.def_path_str_with_substs(def.did(), substs),
1926 _ => self.ty_to_string(ty),
1930 fn suggest_await_before_method(
1932 err: &mut Diagnostic,
1935 call: &hir::Expr<'_>,
1938 let output_ty = match self.get_impl_future_output_ty(ty) {
1939 Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
1942 let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);
1943 debug!("suggest_await_before_method: is_method_exist={}", method_exists);
1945 err.span_suggestion_verbose(
1946 span.shrink_to_lo(),
1947 "consider `await`ing on the `Future` and calling the method on its `Output`",
1949 Applicability::MaybeIncorrect,
1954 fn suggest_use_candidates(&self, err: &mut Diagnostic, msg: String, candidates: Vec<DefId>) {
1955 let parent_map = self.tcx.visible_parent_map(());
1957 // Separate out candidates that must be imported with a glob, because they are named `_`
1958 // and cannot be referred with their identifier.
1959 let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
1960 if let Some(parent_did) = parent_map.get(trait_did) {
1961 // If the item is re-exported as `_`, we should suggest a glob-import instead.
1962 if *parent_did != self.tcx.parent(*trait_did)
1965 .module_children(*parent_did)
1967 .filter(|child| child.res.opt_def_id() == Some(*trait_did))
1968 .all(|child| child.ident.name == kw::Underscore)
1977 let module_did = self.tcx.parent_module(self.body_id);
1978 let (module, _, _) = self.tcx.hir().get_module(module_did);
1979 let span = module.spans.inject_use_span;
1981 let path_strings = candidates.iter().map(|trait_did| {
1982 format!("use {};\n", with_crate_prefix!(self.tcx.def_path_str(*trait_did)),)
1985 let glob_path_strings = globs.iter().map(|trait_did| {
1986 let parent_did = parent_map.get(trait_did).unwrap();
1988 "use {}::*; // trait {}\n",
1989 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1990 self.tcx.item_name(*trait_did),
1994 err.span_suggestions(
1997 path_strings.chain(glob_path_strings),
1998 Applicability::MaybeIncorrect,
2002 fn suggest_valid_traits(
2004 err: &mut Diagnostic,
2005 valid_out_of_scope_traits: Vec<DefId>,
2007 if !valid_out_of_scope_traits.is_empty() {
2008 let mut candidates = valid_out_of_scope_traits;
2012 // `TryFrom` and `FromIterator` have no methods
2013 let edition_fix = candidates
2015 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
2018 err.help("items from traits can only be used if the trait is in scope");
2020 "the following {traits_are} implemented but not in scope; \
2021 perhaps add a `use` for {one_of_them}:",
2022 traits_are = if candidates.len() == 1 { "trait is" } else { "traits are" },
2023 one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
2026 self.suggest_use_candidates(err, msg, candidates);
2027 if let Some(did) = edition_fix {
2029 "'{}' is included in the prelude starting in Edition 2021",
2030 with_crate_prefix!(self.tcx.def_path_str(did))
2040 fn suggest_traits_to_import(
2042 err: &mut Diagnostic,
2046 inputs_len: Option<usize>,
2047 source: SelfSource<'tcx>,
2048 valid_out_of_scope_traits: Vec<DefId>,
2049 unsatisfied_predicates: &[(
2050 ty::Predicate<'tcx>,
2051 Option<ty::Predicate<'tcx>>,
2052 Option<ObligationCause<'tcx>>,
2054 static_candidates: &[CandidateSource],
2055 unsatisfied_bounds: bool,
2057 let mut alt_rcvr_sugg = false;
2058 if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
2060 "suggest_traits_to_import: span={:?}, item_name={:?}, rcvr_ty={:?}, rcvr={:?}",
2061 span, item_name, rcvr_ty, rcvr
2064 self.tcx.lang_items().clone_trait(),
2065 self.tcx.lang_items().deref_trait(),
2066 self.tcx.lang_items().deref_mut_trait(),
2067 self.tcx.lang_items().drop_trait(),
2068 self.tcx.get_diagnostic_item(sym::AsRef),
2070 // Try alternative arbitrary self types that could fulfill this call.
2071 // FIXME: probe for all types that *could* be arbitrary self-types, not
2073 for (rcvr_ty, post) in &[
2075 (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
2076 (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
2078 match self.lookup_probe(span, item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) {
2080 // If the method is defined for the receiver we have, it likely wasn't `use`d.
2081 // We point at the method, but we just skip the rest of the check for arbitrary
2082 // self types and rely on the suggestion to `use` the trait from
2083 // `suggest_valid_traits`.
2084 let did = Some(pick.item.container_id(self.tcx));
2085 let skip = skippable.contains(&did);
2086 if pick.autoderefs == 0 && !skip {
2088 pick.item.ident(self.tcx).span,
2089 &format!("the method is available for `{}` here", rcvr_ty),
2094 Err(MethodError::Ambiguity(_)) => {
2095 // If the method is defined (but ambiguous) for the receiver we have, it is also
2096 // likely we haven't `use`d it. It may be possible that if we `Box`/`Pin`/etc.
2097 // the receiver, then it might disambiguate this method, but I think these
2098 // suggestions are generally misleading (see #94218).
2104 for (rcvr_ty, pre) in &[
2105 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::OwnedBox), "Box::new"),
2106 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::Pin), "Pin::new"),
2107 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Arc), "Arc::new"),
2108 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Rc), "Rc::new"),
2110 if let Some(new_rcvr_t) = *rcvr_ty
2111 && let Ok(pick) = self.lookup_probe(
2116 ProbeScope::AllTraits,
2119 debug!("try_alt_rcvr: pick candidate {:?}", pick);
2120 let did = Some(pick.item.container_id(self.tcx));
2121 // We don't want to suggest a container type when the missing
2122 // method is `.clone()` or `.deref()` otherwise we'd suggest
2123 // `Arc::new(foo).clone()`, which is far from what the user wants.
2124 // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
2125 // implement the `AsRef` trait.
2126 let skip = skippable.contains(&did)
2127 || (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
2128 || inputs_len.map_or(false, |inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().inputs().len() != inputs_len);
2129 // Make sure the method is defined for the *actual* receiver: we don't
2130 // want to treat `Box<Self>` as a receiver if it only works because of
2131 // an autoderef to `&self`
2132 if pick.autoderefs == 0 && !skip {
2134 pick.item.ident(self.tcx).span,
2135 &format!("the method is available for `{}` here", new_rcvr_t),
2137 err.multipart_suggestion(
2138 "consider wrapping the receiver expression with the \
2141 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
2142 (rcvr.span.shrink_to_hi(), ")".to_string()),
2144 Applicability::MaybeIncorrect,
2146 // We don't care about the other suggestions.
2147 alt_rcvr_sugg = true;
2153 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
2157 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
2159 let mut arbitrary_rcvr = vec![];
2160 // There are no traits implemented, so lets suggest some traits to
2161 // implement, by finding ones that have the item name, and are
2162 // legal to implement.
2163 let mut candidates = all_traits(self.tcx)
2165 // Don't issue suggestions for unstable traits since they're
2166 // unlikely to be implementable anyway
2167 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
2168 Some(attr) => attr.level.is_stable(),
2172 // Static candidates are already implemented, and known not to work
2173 // Do not suggest them again
2174 static_candidates.iter().all(|sc| match *sc {
2175 CandidateSource::Trait(def_id) => def_id != info.def_id,
2176 CandidateSource::Impl(def_id) => {
2177 self.tcx.trait_id_of_impl(def_id) != Some(info.def_id)
2182 // We approximate the coherence rules to only suggest
2183 // traits that are legal to implement by requiring that
2184 // either the type or trait is local. Multi-dispatch means
2185 // this isn't perfect (that is, there are cases when
2186 // implementing a trait would be legal but is rejected
2188 unsatisfied_predicates.iter().all(|(p, _, _)| {
2189 match p.kind().skip_binder() {
2190 // Hide traits if they are present in predicates as they can be fixed without
2191 // having to implement them.
2192 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
2193 ty::PredicateKind::Projection(p) => {
2194 p.projection_ty.item_def_id == info.def_id
2198 }) && (type_is_local || info.def_id.is_local())
2200 .associated_value(info.def_id, item_name)
2202 if let ty::AssocKind::Fn = item.kind {
2206 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
2207 if let Some(hir::Node::TraitItem(hir::TraitItem {
2208 kind: hir::TraitItemKind::Fn(fn_sig, method),
2210 })) = id.map(|id| self.tcx.hir().get(id))
2212 let self_first_arg = match method {
2213 hir::TraitFn::Required([ident, ..]) => {
2214 ident.name == kw::SelfLower
2216 hir::TraitFn::Provided(body_id) => {
2217 self.tcx.hir().body(*body_id).params.first().map_or(
2222 hir::PatKind::Binding(_, _, ident, _)
2223 if ident.name == kw::SelfLower
2231 if !fn_sig.decl.implicit_self.has_implicit_self()
2234 if let Some(ty) = fn_sig.decl.inputs.get(0) {
2235 arbitrary_rcvr.push(ty.span);
2241 // We only want to suggest public or local traits (#45781).
2242 item.visibility(self.tcx).is_public() || info.def_id.is_local()
2246 .collect::<Vec<_>>();
2247 for span in &arbitrary_rcvr {
2250 "the method might not be found because of this arbitrary self type",
2257 if !candidates.is_empty() {
2258 // Sort from most relevant to least relevant.
2259 candidates.sort_by(|a, b| a.cmp(b).reverse());
2262 let param_type = match rcvr_ty.kind() {
2263 ty::Param(param) => Some(param),
2264 ty::Ref(_, ty, _) => match ty.kind() {
2265 ty::Param(param) => Some(param),
2270 err.help(if param_type.is_some() {
2271 "items from traits can only be used if the type parameter is bounded by the trait"
2273 "items from traits can only be used if the trait is implemented and in scope"
2275 let candidates_len = candidates.len();
2276 let message = |action| {
2278 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
2281 if candidates_len == 1 { "trait defines" } else { "traits define" },
2283 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
2287 // Obtain the span for `param` and use it for a structured suggestion.
2288 if let Some(param) = param_type {
2289 let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
2290 let type_param = generics.type_param(param, self.tcx);
2291 let hir = self.tcx.hir();
2292 if let Some(def_id) = type_param.def_id.as_local() {
2293 let id = hir.local_def_id_to_hir_id(def_id);
2294 // Get the `hir::Param` to verify whether it already has any bounds.
2295 // We do this to avoid suggesting code that ends up as `T: FooBar`,
2296 // instead we suggest `T: Foo + Bar` in that case.
2298 Node::GenericParam(param) => {
2304 let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
2305 let (sp, mut introducer) = if let Some(span) =
2306 ast_generics.bounds_span_for_suggestions(def_id)
2308 (span, Introducer::Plus)
2309 } else if let Some(colon_span) = param.colon_span {
2310 (colon_span.shrink_to_hi(), Introducer::Nothing)
2312 (param.span.shrink_to_hi(), Introducer::Colon)
2316 hir::GenericParamKind::Type { synthetic: true, .. },
2318 introducer = Introducer::Plus
2320 let trait_def_ids: FxHashSet<DefId> = ast_generics
2321 .bounds_for_param(def_id)
2322 .flat_map(|bp| bp.bounds.iter())
2323 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
2325 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
2326 err.span_suggestions(
2329 "restrict type parameter `{}` with",
2332 candidates.iter().map(|t| {
2336 Introducer::Plus => " +",
2337 Introducer::Colon => ":",
2338 Introducer::Nothing => "",
2340 self.tcx.def_path_str(t.def_id),
2343 Applicability::MaybeIncorrect,
2348 Node::Item(hir::Item {
2349 kind: hir::ItemKind::Trait(.., bounds, _),
2353 let (sp, sep, article) = if bounds.is_empty() {
2354 (ident.span.shrink_to_hi(), ":", "a")
2356 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
2358 err.span_suggestions(
2360 &message(format!("add {} supertrait for", article)),
2361 candidates.iter().map(|t| {
2362 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
2364 Applicability::MaybeIncorrect,
2373 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
2374 // FIXME: Even though negative bounds are not implemented, we could maybe handle
2375 // cases where a positive bound implies a negative impl.
2376 (candidates, Vec::new())
2377 } else if let Some(simp_rcvr_ty) =
2378 simplify_type(self.tcx, rcvr_ty, TreatParams::AsPlaceholder)
2380 let mut potential_candidates = Vec::new();
2381 let mut explicitly_negative = Vec::new();
2382 for candidate in candidates {
2383 // Check if there's a negative impl of `candidate` for `rcvr_ty`
2386 .all_impls(candidate.def_id)
2388 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
2391 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
2393 simplify_type(self.tcx, imp.self_ty(), TreatParams::AsPlaceholder);
2394 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
2397 explicitly_negative.push(candidate);
2399 potential_candidates.push(candidate);
2402 (potential_candidates, explicitly_negative)
2404 // We don't know enough about `recv_ty` to make proper suggestions.
2405 (candidates, Vec::new())
2408 let action = if let Some(param) = param_type {
2409 format!("restrict type parameter `{}` with", param)
2411 // FIXME: it might only need to be imported into scope, not implemented.
2412 "implement".to_string()
2414 match &potential_candidates[..] {
2416 [trait_info] if trait_info.def_id.is_local() => {
2418 self.tcx.def_span(trait_info.def_id),
2420 "`{}` defines an item `{}`, perhaps you need to {} it",
2421 self.tcx.def_path_str(trait_info.def_id),
2428 let mut msg = message(action);
2429 for (i, trait_info) in trait_infos.iter().enumerate() {
2430 msg.push_str(&format!(
2431 "\ncandidate #{}: `{}`",
2433 self.tcx.def_path_str(trait_info.def_id),
2439 match &explicitly_negative[..] {
2443 "the trait `{}` defines an item `{}`, but is explicitly unimplemented",
2444 self.tcx.def_path_str(trait_info.def_id),
2450 let mut msg = format!(
2451 "the following traits define an item `{}`, but are explicitly unimplemented:",
2454 for trait_info in trait_infos {
2455 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
2463 /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else`
2464 /// FIXME: currently not working for suggesting `map_or_else`, see #102408
2465 pub(crate) fn suggest_else_fn_with_closure(
2467 err: &mut Diagnostic,
2468 expr: &hir::Expr<'_>,
2472 let Some((_def_id_or_name, output, _inputs)) = self.extract_callable_info(expr, found)
2473 else { return false; };
2475 if !self.can_coerce(output, expected) {
2479 let parent = self.tcx.hir().get_parent_node(expr.hir_id);
2480 if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
2481 let hir::ExprKind::MethodCall(
2482 hir::PathSegment { ident: method_name, .. },
2486 ) = call_expr.kind &&
2487 let Some(self_ty) = self.typeck_results.borrow().expr_ty_opt(self_expr) {
2488 let new_name = Ident {
2489 name: Symbol::intern(&format!("{}_else", method_name.as_str())),
2490 span: method_name.span,
2492 let probe = self.lookup_probe(
2497 ProbeScope::TraitsInScope,
2500 // check the method arguments number
2501 if let Ok(pick) = probe &&
2502 let fn_sig = self.tcx.fn_sig(pick.item.def_id) &&
2503 let fn_args = fn_sig.skip_binder().inputs() &&
2504 fn_args.len() == args.len() + 1 {
2505 err.span_suggestion_verbose(
2506 method_name.span.shrink_to_hi(),
2507 &format!("try calling `{}` instead", new_name.name.as_str()),
2509 Applicability::MaybeIncorrect,
2517 /// Checks whether there is a local type somewhere in the chain of
2518 /// autoderefs of `rcvr_ty`.
2519 fn type_derefs_to_local(
2523 source: SelfSource<'tcx>,
2525 fn is_local(ty: Ty<'_>) -> bool {
2527 ty::Adt(def, _) => def.did().is_local(),
2528 ty::Foreign(did) => did.is_local(),
2529 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
2530 ty::Param(_) => true,
2532 // Everything else (primitive types, etc.) is effectively
2533 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
2534 // the noise from these sort of types is usually just really
2535 // annoying, rather than any sort of help).
2540 // This occurs for UFCS desugaring of `T::method`, where there is no
2541 // receiver expression for the method call, and thus no autoderef.
2542 if let SelfSource::QPath(_) = source {
2543 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
2546 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
2550 #[derive(Copy, Clone, Debug)]
2551 pub enum SelfSource<'a> {
2552 QPath(&'a hir::Ty<'a>),
2553 MethodCall(&'a hir::Expr<'a> /* rcvr */),
2556 #[derive(Copy, Clone)]
2557 pub struct TraitInfo {
2561 impl PartialEq for TraitInfo {
2562 fn eq(&self, other: &TraitInfo) -> bool {
2563 self.cmp(other) == Ordering::Equal
2566 impl Eq for TraitInfo {}
2567 impl PartialOrd for TraitInfo {
2568 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
2569 Some(self.cmp(other))
2572 impl Ord for TraitInfo {
2573 fn cmp(&self, other: &TraitInfo) -> Ordering {
2574 // Local crates are more important than remote ones (local:
2575 // `cnum == 0`), and otherwise we throw in the defid for totality.
2577 let lhs = (other.def_id.krate, other.def_id);
2578 let rhs = (self.def_id.krate, self.def_id);
2583 /// Retrieves all traits in this crate and any dependent crates,
2584 /// and wraps them into `TraitInfo` for custom sorting.
2585 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2586 tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
2589 fn print_disambiguation_help<'tcx>(
2591 args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
2592 err: &mut Diagnostic,
2595 kind: ty::AssocKind,
2598 candidate: Option<usize>,
2599 source_map: &source_map::SourceMap,
2600 fn_has_self_parameter: bool,
2602 let mut applicability = Applicability::MachineApplicable;
2603 let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
2606 if rcvr_ty.is_region_ptr() {
2607 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
2611 std::iter::once(receiver)
2613 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
2614 applicability = Applicability::HasPlaceholders;
2617 .collect::<Vec<_>>()
2620 let trait_name = if !fn_has_self_parameter {
2621 format!("<{} as {}>", rcvr_ty, trait_name)
2625 (span, format!("{}::{}{}", trait_name, item_name, args))
2627 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
2629 err.span_suggestion_verbose(
2632 "disambiguate the {} for {}",
2633 kind.as_def_kind().descr(def_id),
2634 if let Some(candidate) = candidate {
2635 format!("candidate #{}", candidate)
2637 "the candidate".to_string()