1 //! Give useful errors and suggestions to users when an item can't be
2 //! found or is otherwise invalid.
4 use crate::check::FnCtxt;
5 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
7 pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
10 use rustc_hir::def_id::{DefId, LocalDefId};
11 use rustc_hir::lang_items::LangItem;
12 use rustc_hir::{ExprKind, Node, QPath};
13 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
14 use rustc_middle::traits::util::supertraits;
15 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
16 use rustc_middle::ty::print::with_crate_prefix;
17 use rustc_middle::ty::ToPolyTraitRef;
18 use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
19 use rustc_span::symbol::{kw, sym, Ident};
20 use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, MultiSpan, Span};
21 use rustc_trait_selection::traits::error_reporting::on_unimplemented::InferCtxtExt as _;
22 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
23 use rustc_trait_selection::traits::{
24 FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedNote,
27 use std::cmp::Ordering;
30 use super::probe::Mode;
31 use super::{CandidateSource, MethodError, NoMatchData};
33 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34 fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
37 // Not all of these (e.g., unsafe fns) implement `FnOnce`,
38 // so we look for these beforehand.
39 ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
40 // If it's not a simple function, look for things which implement `FnOnce`.
42 let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
46 // This conditional prevents us from asking to call errors and unresolved types.
47 // It might seem that we can use `predicate_must_hold_modulo_regions`,
48 // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
49 // type resolution always gives a "maybe" here.
50 if self.autoderef(span, ty).any(|(ty, _)| {
51 info!("check deref {:?} error", ty);
52 matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
57 self.autoderef(span, ty).any(|(ty, _)| {
58 info!("check deref {:?} impl FnOnce", ty);
60 let fn_once_substs = tcx.mk_substs_trait(
63 .next_ty_var(TypeVariableOrigin {
64 kind: TypeVariableOriginKind::MiscVariable,
69 let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
70 let poly_trait_ref = ty::Binder::dummy(trait_ref);
71 let obligation = Obligation::misc(
75 poly_trait_ref.without_const().to_predicate(tcx),
77 self.predicate_may_hold(&obligation)
84 fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
85 self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
88 pub fn report_method_error(
93 source: SelfSource<'tcx>,
94 error: MethodError<'tcx>,
95 args: Option<&'tcx [hir::Expr<'tcx>]>,
96 ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
97 // Avoid suggestions when we don't know what's going on.
98 if rcvr_ty.references_error() {
102 let report_candidates = |span: Span,
103 err: &mut Diagnostic,
104 mut sources: Vec<CandidateSource>,
108 // Dynamic limit to avoid hiding just one candidate, which is silly.
109 let limit = if sources.len() == 5 { 5 } else { 4 };
111 for (idx, source) in sources.iter().take(limit).enumerate() {
113 CandidateSource::Impl(impl_did) => {
114 // Provide the best span we can. Use the item, if local to crate, else
115 // the impl, if local to crate (item may be defaulted), else nothing.
116 let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
117 let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
118 self.associated_value(impl_trait_ref.def_id, item_name)
125 .span_if_local(item.def_id)
126 .or_else(|| self.tcx.hir().span_if_local(impl_did));
128 let impl_ty = self.tcx.at(span).type_of(impl_did);
130 let insertion = match self.tcx.impl_trait_ref(impl_did) {
131 None => String::new(),
132 Some(trait_ref) => format!(
133 " of the trait `{}`",
134 self.tcx.def_path_str(trait_ref.def_id)
138 let (note_str, idx) = if sources.len() > 1 {
141 "candidate #{} is defined in an impl{} for the type `{}`",
151 "the candidate is defined in an impl{} for the type `{}`",
157 if let Some(note_span) = note_span {
158 // We have a span pointing to the method. Show note with snippet.
160 self.tcx.sess.source_map().guess_head_span(note_span),
166 if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
167 let path = self.tcx.def_path_str(trait_ref.def_id);
169 let ty = match item.kind {
170 ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
171 ty::AssocKind::Fn => self
177 .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
181 print_disambiguation_help(
191 self.tcx.sess.source_map(),
192 item.fn_has_self_parameter,
196 CandidateSource::Trait(trait_did) => {
197 let Some(item) = self.associated_value(trait_did, item_name) else { continue };
202 .guess_head_span(self.tcx.def_span(item.def_id));
203 let idx = if sources.len() > 1 {
205 "candidate #{} is defined in the trait `{}`",
207 self.tcx.def_path_str(trait_did)
209 err.span_note(item_span, msg);
213 "the candidate is defined in the trait `{}`",
214 self.tcx.def_path_str(trait_did)
216 err.span_note(item_span, msg);
219 let path = self.tcx.def_path_str(trait_did);
220 print_disambiguation_help(
230 self.tcx.sess.source_map(),
231 item.fn_has_self_parameter,
236 if sources.len() > limit {
237 err.note(&format!("and {} others", sources.len() - limit));
241 let sugg_span = if let SelfSource::MethodCall(expr) = source {
242 // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
243 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
249 MethodError::NoMatch(NoMatchData {
250 static_candidates: static_sources,
251 unsatisfied_predicates,
258 let actual = self.resolve_vars_if_possible(rcvr_ty);
259 let ty_str = self.ty_to_string(actual);
260 let is_method = mode == Mode::MethodCall;
261 let item_kind = if is_method {
263 } else if actual.is_enum() {
264 "variant or associated item"
266 match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
267 (Some(name), false) if name.is_lowercase() => "function or associated item",
268 (Some(_), false) => "associated item",
269 (Some(_), true) | (None, false) => "variant or associated item",
270 (None, true) => "variant",
273 // FIXME(eddyb) this indentation is probably unnecessary.
275 // Suggest clamping down the type if the method that is being attempted to
276 // be used exists at all, and the type is an ambiguous numeric type
277 // ({integer}/{float}).
278 let mut candidates = all_traits(self.tcx)
280 .filter_map(|info| self.associated_value(info.def_id, item_name));
281 // There are methods that are defined on the primitive types and won't be
282 // found when exploring `all_traits`, but we also need them to be accurate on
283 // our suggestions (#47759).
284 let found_assoc = |ty: Ty<'tcx>| {
285 simplify_type(tcx, ty, TreatParams::AsPlaceholders)
287 tcx.incoherent_impls(simp)
289 .find_map(|&id| self.associated_value(id, item_name))
293 let found_candidate = candidates.next().is_some()
294 || found_assoc(tcx.types.i8)
295 || found_assoc(tcx.types.i16)
296 || found_assoc(tcx.types.i32)
297 || found_assoc(tcx.types.i64)
298 || found_assoc(tcx.types.i128)
299 || found_assoc(tcx.types.u8)
300 || found_assoc(tcx.types.u16)
301 || found_assoc(tcx.types.u32)
302 || found_assoc(tcx.types.u64)
303 || found_assoc(tcx.types.u128)
304 || found_assoc(tcx.types.f32)
305 || found_assoc(tcx.types.f32);
306 if let (true, false, SelfSource::MethodCall(expr), true) = (
308 actual.has_concrete_skeleton(),
312 let mut err = struct_span_err!(
316 "can't call {} `{}` on ambiguous numeric type `{}`",
321 let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
323 ExprKind::Lit(ref lit) => {
328 .span_to_snippet(lit.span)
329 .unwrap_or_else(|_| "<numeric literal>".to_owned());
331 // If this is a floating point literal that ends with '.',
332 // get rid of it to stop this from becoming a member access.
333 let snippet = snippet.strip_suffix('.').unwrap_or(&snippet);
338 "you must specify a concrete type for this numeric value, \
342 format!("{snippet}_{concrete_type}"),
343 Applicability::MaybeIncorrect,
346 ExprKind::Path(QPath::Resolved(_, path)) => {
348 if let hir::def::Res::Local(hir_id) = path.res {
349 let span = tcx.hir().span(hir_id);
350 let snippet = tcx.sess.source_map().span_to_snippet(span);
351 let filename = tcx.sess.source_map().span_to_filename(span);
354 self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
356 "you must specify a type for this binding, like `{}`",
360 match (filename, parent_node, snippet) {
363 Node::Local(hir::Local {
364 source: hir::LocalSource::Normal,
371 // account for `let x: _ = 42;`
378 format!("{}: {}", snippet, concrete_type),
379 Applicability::MaybeIncorrect,
383 err.span_label(span, msg);
393 span = item_name.span;
395 // Don't show generic arguments when the method can't be found in any implementation (#81576).
396 let mut ty_str_reported = ty_str.clone();
397 if let ty::Adt(_, generics) = actual.kind() {
398 if generics.len() > 0 {
399 let mut autoderef = self.autoderef(span, actual);
400 let candidate_found = autoderef.any(|(ty, _)| {
401 if let ty::Adt(adt_deref, _) = ty.kind() {
403 .inherent_impls(adt_deref.did())
405 .filter_map(|def_id| {
406 self.associated_value(*def_id, item_name)
414 let has_deref = autoderef.step_count() > 0;
417 && unsatisfied_predicates.is_empty()
419 if let Some((path_string, _)) = ty_str.split_once('<') {
420 ty_str_reported = path_string.to_string();
426 let mut err = struct_span_err!(
430 "no {} named `{}` found for {} `{}` in the current scope",
433 actual.prefix_string(self.tcx),
436 if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source {
437 self.suggest_await_before_method(
438 &mut err, item_name, actual, cal, span,
442 tcx.resolutions(()).confused_type_with_std_module.get(&span)
444 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
447 "you are looking for the module in `std`, \
448 not the primitive type",
449 format!("std::{}", snippet),
450 Applicability::MachineApplicable,
454 if let ty::RawPtr(_) = &actual.kind() {
456 "try using `<*const T>::as_ref()` to get a reference to the \
457 type behind the pointer: https://doc.rust-lang.org/std/\
458 primitive.pointer.html#method.as_ref",
461 "using `<*const T>::as_ref()` on a pointer \
462 which is unaligned or points to invalid \
463 or uninitialized memory is undefined behavior",
470 if actual.references_error() {
471 err.downgrade_to_delayed_bug();
474 if let Some(def) = actual.ty_adt_def() {
475 if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
476 let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
480 "{} `{}` not found {}",
483 if def.is_enum() && !is_method { "here" } else { "for this" }
489 if self.is_fn_ty(rcvr_ty, span) {
490 fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
492 &format!("`{}` is a function, perhaps you wish to call it", name,),
496 if let SelfSource::MethodCall(expr) = source {
497 if let Ok(expr_string) = tcx.sess.source_map().span_to_snippet(expr.span) {
498 report_function(&mut err, expr_string);
499 } else if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
500 if let Some(segment) = path.segments.last() {
501 report_function(&mut err, segment.ident);
507 let mut custom_span_label = false;
509 if !static_sources.is_empty() {
511 "found the following associated functions; to be used as methods, \
512 functions must have a `self` parameter",
514 err.span_label(span, "this is an associated function, not a method");
515 custom_span_label = true;
517 if static_sources.len() == 1 {
519 if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) {
520 // When the "method" is resolved through dereferencing, we really want the
521 // original type that has the associated function for accurate suggestions.
523 let ty = tcx.at(span).type_of(*impl_did);
524 match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) {
525 (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
526 // Use `actual` as it will have more `substs` filled in.
527 self.ty_to_value_string(actual.peel_refs())
529 _ => self.ty_to_value_string(ty.peel_refs()),
532 self.ty_to_value_string(actual.peel_refs())
534 if let SelfSource::MethodCall(expr) = source {
537 "use associated function syntax instead",
538 format!("{}::{}", ty_str, item_name),
539 Applicability::MachineApplicable,
542 err.help(&format!("try with `{}::{}`", ty_str, item_name,));
545 report_candidates(span, &mut err, static_sources, sugg_span);
546 } else if static_sources.len() > 1 {
547 report_candidates(span, &mut err, static_sources, sugg_span);
550 let mut bound_spans = vec![];
551 let mut restrict_type_params = false;
552 let mut unsatisfied_bounds = false;
553 if item_name.name == sym::count && self.is_slice_ty(actual, span) {
554 let msg = "consider using `len` instead";
555 if let SelfSource::MethodCall(_expr) = source {
556 err.span_suggestion_short(
560 Applicability::MachineApplicable,
563 err.span_label(span, msg);
565 if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
566 let iterator_trait = self.tcx.def_path_str(iterator_trait);
567 err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
569 } else if !unsatisfied_predicates.is_empty() {
570 let def_span = |def_id| {
571 self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
573 let mut type_params = FxHashMap::default();
575 // Pick out the list of unimplemented traits on the receiver.
576 // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
577 let mut unimplemented_traits = FxHashMap::default();
578 let mut unimplemented_traits_only = true;
579 for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
580 if let (ty::PredicateKind::Trait(p), Some(cause)) =
581 (predicate.kind().skip_binder(), cause.as_ref())
583 if p.trait_ref.self_ty() != rcvr_ty {
584 // This is necessary, not just to keep the errors clean, but also
585 // because our derived obligations can wind up with a trait ref that
586 // requires a different param_env to be correctly compared.
589 unimplemented_traits.entry(p.trait_ref.def_id).or_insert((
590 predicate.kind().rebind(p.trait_ref),
592 cause: cause.clone(),
593 param_env: self.param_env,
594 predicate: predicate.clone(),
601 // Make sure that, if any traits other than the found ones were involved,
602 // we don't don't report an unimplemented trait.
603 // We don't want to say that `iter::Cloned` is not an iterator, just
604 // because of some non-Clone item being iterated over.
605 for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
606 match predicate.kind().skip_binder() {
607 ty::PredicateKind::Trait(p)
608 if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
610 unimplemented_traits_only = false;
616 let mut collect_type_param_suggestions =
617 |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
618 // We don't care about regions here, so it's fine to skip the binder here.
619 if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
620 (self_ty.kind(), parent_pred.kind().skip_binder())
622 let node = match p.trait_ref.self_ty().kind() {
624 // Account for `fn` items like in `issue-35677.rs` to
625 // suggest restricting its type params.
626 let did = self.tcx.hir().body_owner_def_id(hir::BodyId {
627 hir_id: self.body_id,
632 .get(self.tcx.hir().local_def_id_to_hir_id(did)),
635 ty::Adt(def, _) => def.did().as_local().map(|def_id| {
638 .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
642 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
643 if let Some(g) = kind.generics() {
644 let key = match g.where_clause.predicates {
645 [.., pred] => (pred.span().shrink_to_hi(), false),
647 g.where_clause.span_for_predicates_or_empty_place(),
653 .or_insert_with(FxHashSet::default)
654 .insert(obligation.to_owned());
659 let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
661 "doesn't satisfy `{}`",
662 if obligation.len() > 50 { quiet } else { obligation }
664 match &self_ty.kind() {
665 // Point at the type that couldn't satisfy the bound.
666 ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
667 // Point at the trait object that couldn't satisfy the bound.
668 ty::Dynamic(preds, _) => {
669 for pred in preds.iter() {
670 match pred.skip_binder() {
671 ty::ExistentialPredicate::Trait(tr) => {
672 bound_spans.push((def_span(tr.def_id), msg.clone()))
674 ty::ExistentialPredicate::Projection(_)
675 | ty::ExistentialPredicate::AutoTrait(_) => {}
679 // Point at the closure that couldn't satisfy the bound.
680 ty::Closure(def_id, _) => bound_spans
681 .push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
685 let mut format_pred = |pred: ty::Predicate<'tcx>| {
686 let bound_predicate = pred.kind();
687 match bound_predicate.skip_binder() {
688 ty::PredicateKind::Projection(pred) => {
689 let pred = bound_predicate.rebind(pred);
690 // `<Foo as Iterator>::Item = String`.
691 let projection_ty = pred.skip_binder().projection_ty;
693 let substs_with_infer_self = tcx.mk_substs(
694 iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
695 .chain(projection_ty.substs.iter().skip(1)),
698 let quiet_projection_ty = ty::ProjectionTy {
699 substs: substs_with_infer_self,
700 item_def_id: projection_ty.item_def_id,
703 let term = pred.skip_binder().term;
705 let obligation = format!("{} = {}", projection_ty, term);
706 let quiet = format!("{} = {}", quiet_projection_ty, term);
708 bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
709 Some((obligation, projection_ty.self_ty()))
711 ty::PredicateKind::Trait(poly_trait_ref) => {
712 let p = poly_trait_ref.trait_ref;
713 let self_ty = p.self_ty();
714 let path = p.print_only_trait_path();
715 let obligation = format!("{}: {}", self_ty, path);
716 let quiet = format!("_: {}", path);
717 bound_span_label(self_ty, &obligation, &quiet);
718 Some((obligation, self_ty))
724 // Find all the requirements that come from a local `impl` block.
725 let mut skip_list: FxHashSet<_> = Default::default();
726 let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
727 for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
729 .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
730 .filter_map(|(p, parent, c)| match c.code() {
731 ObligationCauseCode::ImplDerivedObligation(ref data) => {
732 Some((&data.derived, p, parent, data.impl_def_id, data.span))
737 let parent_trait_ref = data.parent_trait_pred;
738 let path = parent_trait_ref.print_modifiers_and_trait_path();
739 let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
740 let unsatisfied_msg = "unsatisfied trait bound introduced here".to_string();
742 "unsatisfied trait bound introduced in this `derive` macro";
743 match self.tcx.hir().get_if_local(impl_def_id) {
744 // Unmet obligation comes from a `derive` macro, point at it once to
745 // avoid multiple span labels pointing at the same place.
746 Some(Node::Item(hir::Item {
747 kind: hir::ItemKind::Trait(..),
751 ident.span.ctxt().outer_expn_data().kind,
752 ExpnKind::Macro(MacroKind::Derive, _)
755 let span = ident.span.ctxt().outer_expn_data().call_site;
756 let mut spans: MultiSpan = span.into();
757 spans.push_span_label(span, derive_msg.to_string());
758 let entry = spanned_predicates.entry(spans);
759 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
762 Some(Node::Item(hir::Item {
763 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
766 self_ty.span.ctxt().outer_expn_data().kind,
767 ExpnKind::Macro(MacroKind::Derive, _)
769 of_trait.as_ref().map(|t| t
775 Some(ExpnKind::Macro(MacroKind::Derive, _))
778 let span = self_ty.span.ctxt().outer_expn_data().call_site;
779 let mut spans: MultiSpan = span.into();
780 spans.push_span_label(span, derive_msg.to_string());
781 let entry = spanned_predicates.entry(spans.into());
782 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
785 // Unmet obligation coming from a `trait`.
786 Some(Node::Item(hir::Item {
787 kind: hir::ItemKind::Trait(..),
792 ident.span.ctxt().outer_expn_data().kind,
793 ExpnKind::Macro(MacroKind::Derive, _)
796 if let Some(pred) = parent_p {
797 // Done to add the "doesn't satisfy" `span_label`.
798 let _ = format_pred(*pred);
801 let mut spans = if cause_span != *item_span {
802 let mut spans: MultiSpan = cause_span.into();
803 spans.push_span_label(cause_span, unsatisfied_msg);
808 spans.push_span_label(ident.span, "in this trait".to_string());
809 let entry = spanned_predicates.entry(spans.into());
810 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
813 // Unmet obligation coming from an `impl`.
814 Some(Node::Item(hir::Item {
815 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
819 self_ty.span.ctxt().outer_expn_data().kind,
820 ExpnKind::Macro(MacroKind::Derive, _)
822 of_trait.as_ref().map(|t| t
828 Some(ExpnKind::Macro(MacroKind::Derive, _))
831 if let Some(pred) = parent_p {
832 // Done to add the "doesn't satisfy" `span_label`.
833 let _ = format_pred(*pred);
836 let mut spans = if cause_span != *item_span {
837 let mut spans: MultiSpan = cause_span.into();
838 spans.push_span_label(cause_span, unsatisfied_msg);
841 let mut spans = Vec::with_capacity(2);
842 if let Some(trait_ref) = of_trait {
843 spans.push(trait_ref.path.span);
845 spans.push(self_ty.span);
848 if let Some(trait_ref) = of_trait {
849 spans.push_span_label(trait_ref.path.span, String::new());
851 spans.push_span_label(self_ty.span, String::new());
853 let entry = spanned_predicates.entry(spans.into());
854 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
859 let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
860 spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
861 for (span, (_path, _self_ty, preds)) in spanned_predicates {
862 let mut preds: Vec<_> = preds
864 .filter_map(|pred| format_pred(*pred))
865 .map(|(p, _)| format!("`{}`", p))
869 let msg = if let [pred] = &preds[..] {
870 format!("trait bound {} was not satisfied", pred)
873 "the following trait bounds were not satisfied:\n{}",
877 err.span_note(span, &msg);
878 unsatisfied_bounds = true;
881 // The requirements that didn't have an `impl` span to show.
882 let mut bound_list = unsatisfied_predicates
884 .filter_map(|(pred, parent_pred, _cause)| {
885 format_pred(*pred).map(|(p, self_ty)| {
886 collect_type_param_suggestions(self_ty, *pred, &p);
889 None => format!("`{}`", &p),
890 Some(parent_pred) => match format_pred(*parent_pred) {
891 None => format!("`{}`", &p),
892 Some((parent_p, _)) => {
893 collect_type_param_suggestions(
899 "`{}`\nwhich is required by `{}`",
909 .filter(|(_, pred)| !skip_list.contains(&pred))
912 .collect::<Vec<(usize, String)>>();
914 for ((span, empty_where), obligations) in type_params.into_iter() {
915 restrict_type_params = true;
916 // #74886: Sort here so that the output is always the same.
917 let mut obligations = obligations.into_iter().collect::<Vec<_>>();
919 err.span_suggestion_verbose(
922 "consider restricting the type parameter{s} to satisfy the \
924 s = pluralize!(obligations.len())
928 if empty_where { " where" } else { "," },
929 obligations.join(", ")
931 Applicability::MaybeIncorrect,
935 bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
936 bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677
937 bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order.
939 if !bound_list.is_empty() || !skip_list.is_empty() {
940 let bound_list = bound_list
942 .map(|(_, path)| path)
945 let actual_prefix = actual.prefix_string(self.tcx);
946 info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
947 let (primary_message, label) = if unimplemented_traits.len() == 1
948 && unimplemented_traits_only
953 .map(|(_, (trait_ref, obligation))| {
954 if trait_ref.self_ty().references_error()
955 || actual.references_error()
960 let OnUnimplementedNote { message, label, .. } =
961 self.infcx.on_unimplemented_note(trait_ref, &obligation);
964 .unwrap_or((None, None))
968 let primary_message = primary_message.unwrap_or_else(|| format!(
969 "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
971 err.set_primary_message(&primary_message);
972 if let Some(label) = label {
973 custom_span_label = true;
974 err.span_label(span, label);
976 if !bound_list.is_empty() {
978 "the following trait bounds were not satisfied:\n{bound_list}"
981 self.suggest_derive(&mut err, &unsatisfied_predicates);
983 unsatisfied_bounds = true;
987 let mut label_span_not_found = || {
988 if unsatisfied_predicates.is_empty() {
989 err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
990 let is_string_or_ref_str = match actual.kind() {
991 ty::Ref(_, ty, _) => {
995 ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
998 ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
1001 if is_string_or_ref_str && item_name.name == sym::iter {
1002 err.span_suggestion_verbose(
1004 "because of the in-memory representation of `&str`, to obtain \
1005 an `Iterator` over each of its codepoint use method `chars`",
1006 String::from("chars"),
1007 Applicability::MachineApplicable,
1010 if let ty::Adt(adt, _) = rcvr_ty.kind() {
1011 let mut inherent_impls_candidate = self
1013 .inherent_impls(adt.did())
1017 if let Some(assoc) = self.associated_value(*def_id, item_name) {
1018 // Check for both mode is the same so we avoid suggesting
1019 // incorrect associated item.
1020 match (mode, assoc.fn_has_self_parameter, source) {
1021 (Mode::MethodCall, true, SelfSource::MethodCall(_)) => {
1022 // We check that the suggest type is actually
1023 // different from the received one
1024 // So we avoid suggestion method with Box<Self>
1026 self.tcx.at(span).type_of(*def_id) != actual
1027 && self.tcx.at(span).type_of(*def_id) != rcvr_ty
1029 (Mode::Path, false, _) => true,
1036 .collect::<Vec<_>>();
1037 if !inherent_impls_candidate.is_empty() {
1038 inherent_impls_candidate.sort();
1039 inherent_impls_candidate.dedup();
1041 // number of type to shows at most.
1042 let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
1043 let type_candidates = inherent_impls_candidate
1047 format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
1049 .collect::<Vec<_>>()
1051 let additional_types = if inherent_impls_candidate.len() > limit {
1053 "\nand {} more types",
1054 inherent_impls_candidate.len() - limit
1060 "the {item_kind} was found for\n{}{}",
1061 type_candidates, additional_types
1066 err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
1070 // If the method name is the name of a field with a function or closure type,
1071 // give a helping note that it has to be called as `(x.f)(...)`.
1072 if let SelfSource::MethodCall(expr) = source {
1073 let field_receiver =
1074 self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
1075 ty::Adt(def, substs) if !def.is_enum() => {
1076 let variant = &def.non_enum_variant();
1077 self.tcx.find_field_index(item_name, variant).map(|index| {
1078 let field = &variant.fields[index];
1079 let field_ty = field.ty(tcx, substs);
1086 if let Some((field, field_ty)) = field_receiver {
1087 let scope = self.tcx.parent_module(self.body_id).to_def_id();
1088 let is_accessible = field.vis.is_accessible_from(scope, self.tcx);
1091 if self.is_fn_ty(field_ty, span) {
1092 let expr_span = expr.span.to(item_name.span);
1093 err.multipart_suggestion(
1095 "to call the function stored in `{}`, \
1096 surround the field access with parentheses",
1100 (expr_span.shrink_to_lo(), '('.to_string()),
1101 (expr_span.shrink_to_hi(), ')'.to_string()),
1103 Applicability::MachineApplicable,
1106 let call_expr = self
1109 .expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1111 if let Some(span) = call_expr.span.trim_start(item_name.span) {
1112 err.span_suggestion(
1114 "remove the arguments",
1116 Applicability::MaybeIncorrect,
1122 let field_kind = if is_accessible { "field" } else { "private field" };
1123 err.span_label(item_name.span, format!("{}, not a method", field_kind));
1124 } else if lev_candidate.is_none() && !custom_span_label {
1125 label_span_not_found();
1127 } else if !custom_span_label {
1128 label_span_not_found();
1132 bound_spans.dedup();
1133 for (span, msg) in bound_spans.into_iter() {
1134 err.span_label(span, &msg);
1137 if actual.is_numeric() && actual.is_fresh() || restrict_type_params {
1139 self.suggest_traits_to_import(
1145 out_of_scope_traits,
1146 &unsatisfied_predicates,
1151 // Don't emit a suggestion if we found an actual method
1152 // that had unsatisfied trait bounds
1153 if unsatisfied_predicates.is_empty() && actual.is_enum() {
1154 let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
1155 if let Some(suggestion) = lev_distance::find_best_match_for_name(
1156 &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
1160 err.span_suggestion(
1162 "there is a variant with a similar name",
1163 suggestion.to_string(),
1164 Applicability::MaybeIncorrect,
1169 if item_name.name == sym::as_str && actual.peel_refs().is_str() {
1170 let msg = "remove this method call";
1171 let mut fallback_span = true;
1172 if let SelfSource::MethodCall(expr) = source {
1174 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1175 if let Some(span) = call_expr.span.trim_start(expr.span) {
1176 err.span_suggestion(
1180 Applicability::MachineApplicable,
1182 fallback_span = false;
1186 err.span_label(span, msg);
1188 } else if let Some(lev_candidate) = lev_candidate {
1189 // Don't emit a suggestion if we found an actual method
1190 // that had unsatisfied trait bounds
1191 if unsatisfied_predicates.is_empty() {
1192 let def_kind = lev_candidate.kind.as_def_kind();
1193 err.span_suggestion(
1196 "there is {} {} with a similar name",
1198 def_kind.descr(lev_candidate.def_id),
1200 lev_candidate.name.to_string(),
1201 Applicability::MaybeIncorrect,
1209 MethodError::Ambiguity(sources) => {
1210 let mut err = struct_span_err!(
1214 "multiple applicable items in scope"
1216 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
1218 report_candidates(span, &mut err, sources, sugg_span);
1222 MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
1223 let kind = kind.descr(def_id);
1224 let mut err = struct_span_err!(
1228 "{} `{}` is private",
1232 err.span_label(item_name.span, &format!("private {}", kind));
1236 .span_if_local(def_id)
1237 .unwrap_or_else(|| self.tcx.def_span(def_id));
1238 err.span_label(sp, &format!("private {} defined here", kind));
1239 self.suggest_valid_traits(&mut err, out_of_scope_traits);
1243 MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
1244 let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
1245 let mut err = self.sess().struct_span_err(span, &msg);
1246 err.span_label(bound_span, "this has a `Sized` requirement");
1247 if !candidates.is_empty() {
1249 "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
1250 add a `use` for {one_of_them}:",
1251 an = if candidates.len() == 1 { "an" } else { "" },
1252 s = pluralize!(candidates.len()),
1253 were = if candidates.len() == 1 { "was" } else { "were" },
1254 one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
1256 self.suggest_use_candidates(&mut err, help, candidates);
1258 if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
1260 let trait_type = self.tcx.mk_ref(
1262 ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
1264 err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
1270 MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
1275 crate fn note_unmet_impls_on_type(
1277 err: &mut Diagnostic,
1278 errors: Vec<FulfillmentError<'tcx>>,
1280 let all_local_types_needing_impls =
1281 errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
1282 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
1283 ty::Adt(def, _) => def.did().is_local(),
1288 let mut preds: Vec<_> = errors
1290 .filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
1291 ty::PredicateKind::Trait(pred) => Some(pred),
1295 preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty()));
1298 .filter_map(|pred| match pred.self_ty().kind() {
1299 ty::Adt(def, _) => Some(def.did()),
1302 .collect::<FxHashSet<_>>();
1303 let sm = self.tcx.sess.source_map();
1304 let mut spans: MultiSpan = def_ids
1306 .filter_map(|def_id| {
1307 let span = self.tcx.def_span(*def_id);
1308 if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
1310 .collect::<Vec<_>>()
1313 for pred in &preds {
1314 match pred.self_ty().kind() {
1315 ty::Adt(def, _) => {
1316 spans.push_span_label(
1317 sm.guess_head_span(self.tcx.def_span(def.did())),
1318 format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
1325 if all_local_types_needing_impls && spans.primary_span().is_some() {
1326 let msg = if preds.len() == 1 {
1328 "an implementation of `{}` might be missing for `{}`",
1329 preds[0].trait_ref.print_only_trait_path(),
1334 "the following type{} would have to `impl` {} required trait{} for this \
1335 operation to be valid",
1336 pluralize!(def_ids.len()),
1337 if def_ids.len() == 1 { "its" } else { "their" },
1338 pluralize!(preds.len()),
1341 err.span_note(spans, &msg);
1344 let preds: Vec<_> = errors
1346 .map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
1348 self.suggest_derive(err, &preds);
1353 err: &mut Diagnostic,
1354 unsatisfied_predicates: &[(
1355 ty::Predicate<'tcx>,
1356 Option<ty::Predicate<'tcx>>,
1357 Option<ObligationCause<'tcx>>,
1360 let mut derives = Vec::<(String, Span, String)>::new();
1361 let mut traits = Vec::<Span>::new();
1362 for (pred, _, _) in unsatisfied_predicates {
1363 let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
1364 let adt = match trait_pred.self_ty().ty_adt_def() {
1365 Some(adt) if adt.did().is_local() => adt,
1368 if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1369 let can_derive = match diagnostic_name {
1370 sym::Default => !adt.is_enum(),
1378 | sym::Debug => true,
1382 let self_name = trait_pred.self_ty().to_string();
1383 let self_span = self.tcx.def_span(adt.did());
1384 if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
1385 for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
1387 if let Some(parent_diagnostic_name) =
1388 self.tcx.get_diagnostic_name(super_trait.def_id())
1393 parent_diagnostic_name.to_string(),
1398 derives.push((self_name, self_span, diagnostic_name.to_string()));
1400 traits.push(self.tcx.def_span(trait_pred.def_id()));
1403 traits.push(self.tcx.def_span(trait_pred.def_id()));
1412 let mut derives_grouped = Vec::<(String, Span, String)>::new();
1413 for (self_name, self_span, trait_name) in derives.into_iter() {
1414 if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
1416 if last_self_name == &self_name {
1417 last_trait_names.push_str(format!(", {}", trait_name).as_str());
1421 derives_grouped.push((self_name, self_span, trait_name));
1424 let len = traits.len();
1426 let span: MultiSpan = traits.into();
1429 &format!("the following trait{} must be implemented", pluralize!(len),),
1433 for (self_name, self_span, traits) in &derives_grouped {
1434 err.span_suggestion_verbose(
1435 self_span.shrink_to_lo(),
1436 &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits),
1437 format!("#[derive({})]\n", traits),
1438 Applicability::MaybeIncorrect,
1443 /// Print out the type for use in value namespace.
1444 fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
1446 ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)),
1447 _ => self.ty_to_string(ty),
1451 fn suggest_await_before_method(
1453 err: &mut Diagnostic,
1456 call: &hir::Expr<'_>,
1459 let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1460 Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
1463 let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);
1464 debug!("suggest_await_before_method: is_method_exist={}", method_exists);
1466 err.span_suggestion_verbose(
1467 span.shrink_to_lo(),
1468 "consider `await`ing on the `Future` and calling the method on its `Output`",
1469 "await.".to_string(),
1470 Applicability::MaybeIncorrect,
1475 fn suggest_use_candidates(
1477 err: &mut Diagnostic,
1479 candidates: Vec<DefId>,
1481 let parent_map = self.tcx.visible_parent_map(());
1483 // Separate out candidates that must be imported with a glob, because they are named `_`
1484 // and cannot be referred with their identifier.
1485 let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
1486 if let Some(parent_did) = parent_map.get(trait_did) {
1487 // If the item is re-exported as `_`, we should suggest a glob-import instead.
1488 if Some(*parent_did) != self.tcx.parent(*trait_did)
1491 .module_children(*parent_did)
1493 .filter(|child| child.res.opt_def_id() == Some(*trait_did))
1494 .all(|child| child.ident.name == kw::Underscore)
1503 let module_did = self.tcx.parent_module(self.body_id);
1504 let (span, found_use) = find_use_placement(self.tcx, module_did);
1505 if let Some(span) = span {
1506 let path_strings = candidates.iter().map(|trait_did| {
1507 // Produce an additional newline to separate the new use statement
1508 // from the directly following item.
1509 let additional_newline = if found_use { "" } else { "\n" };
1512 with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
1517 let glob_path_strings = globs.iter().map(|trait_did| {
1518 let parent_did = parent_map.get(trait_did).unwrap();
1520 // Produce an additional newline to separate the new use statement
1521 // from the directly following item.
1522 let additional_newline = if found_use { "" } else { "\n" };
1524 "use {}::*; // trait {}\n{}",
1525 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1526 self.tcx.item_name(*trait_did),
1531 err.span_suggestions(
1534 path_strings.chain(glob_path_strings),
1535 Applicability::MaybeIncorrect,
1538 let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 };
1539 for (i, trait_did) in candidates.iter().take(limit).enumerate() {
1540 if candidates.len() + globs.len() > 1 {
1541 msg.push_str(&format!(
1542 "\ncandidate #{}: `use {};`",
1544 with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1547 msg.push_str(&format!(
1549 with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1553 for (i, trait_did) in
1554 globs.iter().take(limit.saturating_sub(candidates.len())).enumerate()
1556 let parent_did = parent_map.get(trait_did).unwrap();
1558 if candidates.len() + globs.len() > 1 {
1559 msg.push_str(&format!(
1560 "\ncandidate #{}: `use {}::*; // trait {}`",
1561 candidates.len() + i + 1,
1562 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1563 self.tcx.item_name(*trait_did),
1566 msg.push_str(&format!(
1567 "\n`use {}::*; // trait {}`",
1568 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1569 self.tcx.item_name(*trait_did),
1573 if candidates.len() > limit {
1574 msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit));
1580 fn suggest_valid_traits(
1582 err: &mut Diagnostic,
1583 valid_out_of_scope_traits: Vec<DefId>,
1585 if !valid_out_of_scope_traits.is_empty() {
1586 let mut candidates = valid_out_of_scope_traits;
1590 // `TryFrom` and `FromIterator` have no methods
1591 let edition_fix = candidates
1593 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
1596 err.help("items from traits can only be used if the trait is in scope");
1598 "the following {traits_are} implemented but not in scope; \
1599 perhaps add a `use` for {one_of_them}:",
1600 traits_are = if candidates.len() == 1 { "trait is" } else { "traits are" },
1601 one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
1604 self.suggest_use_candidates(err, msg, candidates);
1605 if let Some(did) = edition_fix {
1607 "'{}' is included in the prelude starting in Edition 2021",
1608 with_crate_prefix!(self.tcx.def_path_str(did))
1618 fn suggest_traits_to_import(
1620 err: &mut Diagnostic,
1624 source: SelfSource<'tcx>,
1625 valid_out_of_scope_traits: Vec<DefId>,
1626 unsatisfied_predicates: &[(
1627 ty::Predicate<'tcx>,
1628 Option<ty::Predicate<'tcx>>,
1629 Option<ObligationCause<'tcx>>,
1631 unsatisfied_bounds: bool,
1633 let mut alt_rcvr_sugg = false;
1634 if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
1635 debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
1637 self.tcx.lang_items().clone_trait(),
1638 self.tcx.lang_items().deref_trait(),
1639 self.tcx.lang_items().deref_mut_trait(),
1640 self.tcx.lang_items().drop_trait(),
1641 self.tcx.get_diagnostic_item(sym::AsRef),
1643 // Try alternative arbitrary self types that could fulfill this call.
1644 // FIXME: probe for all types that *could* be arbitrary self-types, not
1646 for (rcvr_ty, post) in &[
1648 (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
1649 (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
1651 match self.lookup_probe(
1656 crate::check::method::probe::ProbeScope::AllTraits,
1659 // If the method is defined for the receiver we have, it likely wasn't `use`d.
1660 // We point at the method, but we just skip the rest of the check for arbitrary
1661 // self types and rely on the suggestion to `use` the trait from
1662 // `suggest_valid_traits`.
1663 let did = Some(pick.item.container.id());
1664 let skip = skippable.contains(&did);
1665 if pick.autoderefs == 0 && !skip {
1667 pick.item.ident(self.tcx).span,
1668 &format!("the method is available for `{}` here", rcvr_ty),
1673 Err(MethodError::Ambiguity(_)) => {
1674 // If the method is defined (but ambiguous) for the receiver we have, it is also
1675 // likely we haven't `use`d it. It may be possible that if we `Box`/`Pin`/etc.
1676 // the receiver, then it might disambiguate this method, but I think these
1677 // suggestions are generally misleading (see #94218).
1683 for (rcvr_ty, pre) in &[
1684 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::OwnedBox), "Box::new"),
1685 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::Pin), "Pin::new"),
1686 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Arc), "Arc::new"),
1687 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Rc), "Rc::new"),
1689 if let Some(new_rcvr_t) = *rcvr_ty && let Ok(pick) = self.lookup_probe(
1694 crate::check::method::probe::ProbeScope::AllTraits,
1696 debug!("try_alt_rcvr: pick candidate {:?}", pick);
1697 let did = Some(pick.item.container.id());
1698 // We don't want to suggest a container type when the missing
1699 // method is `.clone()` or `.deref()` otherwise we'd suggest
1700 // `Arc::new(foo).clone()`, which is far from what the user wants.
1701 // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
1702 // implement the `AsRef` trait.
1703 let skip = skippable.contains(&did)
1704 || (("Pin::new" == *pre) && (sym::as_ref == item_name.name));
1705 // Make sure the method is defined for the *actual* receiver: we don't
1706 // want to treat `Box<Self>` as a receiver if it only works because of
1707 // an autoderef to `&self`
1708 if pick.autoderefs == 0 && !skip {
1710 pick.item.ident(self.tcx).span,
1711 &format!("the method is available for `{}` here", new_rcvr_t),
1713 err.multipart_suggestion(
1714 "consider wrapping the receiver expression with the \
1717 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1718 (rcvr.span.shrink_to_hi(), ")".to_string()),
1720 Applicability::MaybeIncorrect,
1722 // We don't care about the other suggestions.
1723 alt_rcvr_sugg = true;
1729 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1733 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1735 let mut arbitrary_rcvr = vec![];
1736 // There are no traits implemented, so lets suggest some traits to
1737 // implement, by finding ones that have the item name, and are
1738 // legal to implement.
1739 let mut candidates = all_traits(self.tcx)
1741 // Don't issue suggestions for unstable traits since they're
1742 // unlikely to be implementable anyway
1743 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1744 Some(attr) => attr.level.is_stable(),
1748 // We approximate the coherence rules to only suggest
1749 // traits that are legal to implement by requiring that
1750 // either the type or trait is local. Multi-dispatch means
1751 // this isn't perfect (that is, there are cases when
1752 // implementing a trait would be legal but is rejected
1754 unsatisfied_predicates.iter().all(|(p, _, _)| {
1755 match p.kind().skip_binder() {
1756 // Hide traits if they are present in predicates as they can be fixed without
1757 // having to implement them.
1758 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1759 ty::PredicateKind::Projection(p) => {
1760 p.projection_ty.item_def_id == info.def_id
1764 }) && (type_is_local || info.def_id.is_local())
1766 .associated_value(info.def_id, item_name)
1768 if let ty::AssocKind::Fn = item.kind {
1772 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1773 if let Some(hir::Node::TraitItem(hir::TraitItem {
1774 kind: hir::TraitItemKind::Fn(fn_sig, method),
1776 })) = id.map(|id| self.tcx.hir().get(id))
1778 let self_first_arg = match method {
1779 hir::TraitFn::Required([ident, ..]) => {
1780 ident.name == kw::SelfLower
1782 hir::TraitFn::Provided(body_id) => {
1783 self.tcx.hir().body(*body_id).params.first().map_or(
1788 hir::PatKind::Binding(_, _, ident, _)
1789 if ident.name == kw::SelfLower
1797 if !fn_sig.decl.implicit_self.has_implicit_self()
1800 if let Some(ty) = fn_sig.decl.inputs.get(0) {
1801 arbitrary_rcvr.push(ty.span);
1807 // We only want to suggest public or local traits (#45781).
1808 item.vis.is_public() || info.def_id.is_local()
1812 .collect::<Vec<_>>();
1813 for span in &arbitrary_rcvr {
1816 "the method might not be found because of this arbitrary self type",
1823 if !candidates.is_empty() {
1824 // Sort from most relevant to least relevant.
1825 candidates.sort_by(|a, b| a.cmp(b).reverse());
1828 let param_type = match rcvr_ty.kind() {
1829 ty::Param(param) => Some(param),
1830 ty::Ref(_, ty, _) => match ty.kind() {
1831 ty::Param(param) => Some(param),
1836 err.help(if param_type.is_some() {
1837 "items from traits can only be used if the type parameter is bounded by the trait"
1839 "items from traits can only be used if the trait is implemented and in scope"
1841 let candidates_len = candidates.len();
1842 let message = |action| {
1844 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1847 if candidates_len == 1 { "trait defines" } else { "traits define" },
1849 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1853 // Obtain the span for `param` and use it for a structured suggestion.
1854 if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1855 let table_owner = table.borrow().hir_owner;
1856 let generics = self.tcx.generics_of(table_owner.to_def_id());
1857 let type_param = generics.type_param(param, self.tcx);
1858 let hir = self.tcx.hir();
1859 if let Some(def_id) = type_param.def_id.as_local() {
1860 let id = hir.local_def_id_to_hir_id(def_id);
1861 // Get the `hir::Param` to verify whether it already has any bounds.
1862 // We do this to avoid suggesting code that ends up as `T: FooBar`,
1863 // instead we suggest `T: Foo + Bar` in that case.
1865 Node::GenericParam(param) => {
1866 let mut impl_trait = false;
1868 if let hir::GenericParamKind::Type { synthetic: true, .. } =
1871 // We've found `fn foo(x: impl Trait)` instead of
1872 // `fn foo<T>(x: T)`. We want to suggest the correct
1873 // `fn foo(x: impl Trait + TraitBound)` instead of
1874 // `fn foo<T: TraitBound>(x: T)`. (#63706)
1880 let sp = hir.span(id);
1881 let sp = if let Some(first_bound) = has_bounds {
1882 // `sp` only covers `T`, change it so that it covers
1883 // `T:` when appropriate
1884 sp.until(first_bound.span())
1888 let trait_def_ids: FxHashSet<DefId> = param
1891 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1893 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1894 err.span_suggestions(
1897 "restrict type parameter `{}` with",
1900 candidates.iter().map(|t| {
1904 if impl_trait { " +" } else { ":" },
1905 self.tcx.def_path_str(t.def_id),
1906 if has_bounds.is_some() { " + " } else { "" },
1909 Applicability::MaybeIncorrect,
1914 Node::Item(hir::Item {
1915 kind: hir::ItemKind::Trait(.., bounds, _),
1919 let (sp, sep, article) = if bounds.is_empty() {
1920 (ident.span.shrink_to_hi(), ":", "a")
1922 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1924 err.span_suggestions(
1926 &message(format!("add {} supertrait for", article)),
1927 candidates.iter().map(|t| {
1928 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1930 Applicability::MaybeIncorrect,
1939 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1940 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1941 // cases where a positive bound implies a negative impl.
1942 (candidates, Vec::new())
1943 } else if let Some(simp_rcvr_ty) =
1944 simplify_type(self.tcx, rcvr_ty, TreatParams::AsBoundTypes)
1946 let mut potential_candidates = Vec::new();
1947 let mut explicitly_negative = Vec::new();
1948 for candidate in candidates {
1949 // Check if there's a negative impl of `candidate` for `rcvr_ty`
1952 .all_impls(candidate.def_id)
1954 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1957 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1959 simplify_type(self.tcx, imp.self_ty(), TreatParams::AsBoundTypes);
1960 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1963 explicitly_negative.push(candidate);
1965 potential_candidates.push(candidate);
1968 (potential_candidates, explicitly_negative)
1970 // We don't know enough about `recv_ty` to make proper suggestions.
1971 (candidates, Vec::new())
1974 let action = if let Some(param) = param_type {
1975 format!("restrict type parameter `{}` with", param)
1977 // FIXME: it might only need to be imported into scope, not implemented.
1978 "implement".to_string()
1980 match &potential_candidates[..] {
1982 [trait_info] if trait_info.def_id.is_local() => {
1983 let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1985 self.tcx.sess.source_map().guess_head_span(span),
1987 "`{}` defines an item `{}`, perhaps you need to {} it",
1988 self.tcx.def_path_str(trait_info.def_id),
1995 let mut msg = message(action);
1996 for (i, trait_info) in trait_infos.iter().enumerate() {
1997 msg.push_str(&format!(
1998 "\ncandidate #{}: `{}`",
2000 self.tcx.def_path_str(trait_info.def_id),
2006 match &explicitly_negative[..] {
2010 "the trait `{}` defines an item `{}`, but is explicitly unimplemented",
2011 self.tcx.def_path_str(trait_info.def_id),
2017 let mut msg = format!(
2018 "the following traits define an item `{}`, but are explicitly unimplemented:",
2021 for trait_info in trait_infos {
2022 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
2030 /// Checks whether there is a local type somewhere in the chain of
2031 /// autoderefs of `rcvr_ty`.
2032 fn type_derefs_to_local(
2036 source: SelfSource<'tcx>,
2038 fn is_local(ty: Ty<'_>) -> bool {
2040 ty::Adt(def, _) => def.did().is_local(),
2041 ty::Foreign(did) => did.is_local(),
2042 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
2043 ty::Param(_) => true,
2045 // Everything else (primitive types, etc.) is effectively
2046 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
2047 // the noise from these sort of types is usually just really
2048 // annoying, rather than any sort of help).
2053 // This occurs for UFCS desugaring of `T::method`, where there is no
2054 // receiver expression for the method call, and thus no autoderef.
2055 if let SelfSource::QPath(_) = source {
2056 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
2059 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
2063 #[derive(Copy, Clone, Debug)]
2064 pub enum SelfSource<'a> {
2065 QPath(&'a hir::Ty<'a>),
2066 MethodCall(&'a hir::Expr<'a> /* rcvr */),
2069 #[derive(Copy, Clone)]
2070 pub struct TraitInfo {
2074 impl PartialEq for TraitInfo {
2075 fn eq(&self, other: &TraitInfo) -> bool {
2076 self.cmp(other) == Ordering::Equal
2079 impl Eq for TraitInfo {}
2080 impl PartialOrd for TraitInfo {
2081 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
2082 Some(self.cmp(other))
2085 impl Ord for TraitInfo {
2086 fn cmp(&self, other: &TraitInfo) -> Ordering {
2087 // Local crates are more important than remote ones (local:
2088 // `cnum == 0`), and otherwise we throw in the defid for totality.
2090 let lhs = (other.def_id.krate, other.def_id);
2091 let rhs = (self.def_id.krate, self.def_id);
2096 /// Retrieves all traits in this crate and any dependent crates,
2097 /// and wraps them into `TraitInfo` for custom sorting.
2098 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2099 tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
2102 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
2103 // FIXME(#94854): this code uses an out-of-date method for inferring a span
2104 // to suggest. It would be better to thread the ModSpans from the AST into
2105 // the HIR, and then use that to drive the suggestion here.
2107 let mut span = None;
2108 let mut found_use = false;
2109 let (module, _, _) = tcx.hir().get_module(target_module);
2111 // Find a `use` statement.
2112 for &item_id in module.item_ids {
2113 let item = tcx.hir().item(item_id);
2115 hir::ItemKind::Use(..) => {
2116 // Don't suggest placing a `use` before the prelude
2117 // import or other generated ones.
2118 if !item.span.from_expansion() {
2119 span = Some(item.span.shrink_to_lo());
2124 // Don't place `use` before `extern crate`...
2125 hir::ItemKind::ExternCrate(_) => {}
2126 // ...but do place them before the first other item.
2128 if span.map_or(true, |span| item.span < span) {
2129 if !item.span.from_expansion() {
2130 span = Some(item.span.shrink_to_lo());
2131 // Don't insert between attributes and an item.
2132 let attrs = tcx.hir().attrs(item.hir_id());
2133 // Find the first attribute on the item.
2134 // FIXME: This is broken for active attributes.
2136 if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
2137 span = Some(attr.span.shrink_to_lo());
2149 fn print_disambiguation_help<'tcx>(
2151 args: Option<&'tcx [hir::Expr<'tcx>]>,
2152 err: &mut Diagnostic,
2155 kind: ty::AssocKind,
2158 candidate: Option<usize>,
2159 source_map: &source_map::SourceMap,
2160 fn_has_self_parameter: bool,
2162 let mut applicability = Applicability::MachineApplicable;
2163 let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
2166 if rcvr_ty.is_region_ptr() {
2167 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
2172 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
2173 applicability = Applicability::HasPlaceholders;
2176 .collect::<Vec<_>>()
2179 let trait_name = if !fn_has_self_parameter {
2180 format!("<{} as {}>", rcvr_ty, trait_name)
2184 (span, format!("{}::{}{}", trait_name, item_name, args))
2186 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
2188 err.span_suggestion_verbose(
2191 "disambiguate the {} for {}",
2192 kind.as_def_kind().descr(def_id),
2193 if let Some(candidate) = candidate {
2194 format!("candidate #{}", candidate)
2196 "the candidate".to_string()