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,
11 use rustc_hir::def_id::{DefId, LocalDefId};
12 use rustc_hir::lang_items::LangItem;
13 use rustc_hir::{ExprKind, Node, QPath};
14 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
15 use rustc_middle::traits::util::supertraits;
16 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
17 use rustc_middle::ty::print::with_crate_prefix;
18 use rustc_middle::ty::ToPolyTraitRef;
19 use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
20 use rustc_span::symbol::{kw, sym, Ident};
21 use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span};
22 use rustc_trait_selection::traits::error_reporting::on_unimplemented::InferCtxtExt as _;
23 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
24 use rustc_trait_selection::traits::{
25 FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedNote,
28 use std::cmp::Ordering;
31 use super::probe::Mode;
32 use super::{CandidateSource, MethodError, NoMatchData};
34 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35 fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
38 // Not all of these (e.g., unsafe fns) implement `FnOnce`,
39 // so we look for these beforehand.
40 ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
41 // If it's not a simple function, look for things which implement `FnOnce`.
43 let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
47 // This conditional prevents us from asking to call errors and unresolved types.
48 // It might seem that we can use `predicate_must_hold_modulo_regions`,
49 // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
50 // type resolution always gives a "maybe" here.
51 if self.autoderef(span, ty).any(|(ty, _)| {
52 info!("check deref {:?} error", ty);
53 matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
58 self.autoderef(span, ty).any(|(ty, _)| {
59 info!("check deref {:?} impl FnOnce", ty);
61 let fn_once_substs = tcx.mk_substs_trait(
64 .next_ty_var(TypeVariableOrigin {
65 kind: TypeVariableOriginKind::MiscVariable,
70 let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
71 let poly_trait_ref = ty::Binder::dummy(trait_ref);
72 let obligation = Obligation::misc(
76 poly_trait_ref.without_const().to_predicate(tcx),
78 self.predicate_may_hold(&obligation)
85 fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
86 self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
89 pub fn report_method_error(
94 source: SelfSource<'tcx>,
95 error: MethodError<'tcx>,
96 args: Option<&'tcx [hir::Expr<'tcx>]>,
97 ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
98 // Avoid suggestions when we don't know what's going on.
99 if rcvr_ty.references_error() {
103 let report_candidates = |span: Span,
104 err: &mut Diagnostic,
105 mut sources: Vec<CandidateSource>,
109 // Dynamic limit to avoid hiding just one candidate, which is silly.
110 let limit = if sources.len() == 5 { 5 } else { 4 };
112 for (idx, source) in sources.iter().take(limit).enumerate() {
114 CandidateSource::Impl(impl_did) => {
115 // Provide the best span we can. Use the item, if local to crate, else
116 // the impl, if local to crate (item may be defaulted), else nothing.
117 let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
118 let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
119 self.associated_value(impl_trait_ref.def_id, item_name)
126 .span_if_local(item.def_id)
127 .or_else(|| self.tcx.hir().span_if_local(impl_did));
129 let impl_ty = self.tcx.at(span).type_of(impl_did);
131 let insertion = match self.tcx.impl_trait_ref(impl_did) {
132 None => String::new(),
133 Some(trait_ref) => format!(
134 " of the trait `{}`",
135 self.tcx.def_path_str(trait_ref.def_id)
139 let (note_str, idx) = if sources.len() > 1 {
142 "candidate #{} is defined in an impl{} for the type `{}`",
152 "the candidate is defined in an impl{} for the type `{}`",
158 if let Some(note_span) = note_span {
159 // We have a span pointing to the method. Show note with snippet.
161 self.tcx.sess.source_map().guess_head_span(note_span),
167 if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
168 let path = self.tcx.def_path_str(trait_ref.def_id);
170 let ty = match item.kind {
171 ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
172 ty::AssocKind::Fn => self
178 .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
182 print_disambiguation_help(
192 self.tcx.sess.source_map(),
193 item.fn_has_self_parameter,
197 CandidateSource::Trait(trait_did) => {
198 let Some(item) = self.associated_value(trait_did, item_name) else { continue };
203 .guess_head_span(self.tcx.def_span(item.def_id));
204 let idx = if sources.len() > 1 {
206 "candidate #{} is defined in the trait `{}`",
208 self.tcx.def_path_str(trait_did)
210 err.span_note(item_span, msg);
214 "the candidate is defined in the trait `{}`",
215 self.tcx.def_path_str(trait_did)
217 err.span_note(item_span, msg);
220 let path = self.tcx.def_path_str(trait_did);
221 print_disambiguation_help(
231 self.tcx.sess.source_map(),
232 item.fn_has_self_parameter,
237 if sources.len() > limit {
238 err.note(&format!("and {} others", sources.len() - limit));
242 let sugg_span = if let SelfSource::MethodCall(expr) = source {
243 // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
244 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
250 MethodError::NoMatch(NoMatchData {
251 static_candidates: static_sources,
252 unsatisfied_predicates,
259 let actual = self.resolve_vars_if_possible(rcvr_ty);
260 let ty_str = self.ty_to_string(actual);
261 let is_method = mode == Mode::MethodCall;
262 let item_kind = if is_method {
264 } else if actual.is_enum() {
265 "variant or associated item"
267 match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
268 (Some(name), false) if name.is_lowercase() => "function or associated item",
269 (Some(_), false) => "associated item",
270 (Some(_), true) | (None, false) => "variant or associated item",
271 (None, true) => "variant",
274 // FIXME(eddyb) this indentation is probably unnecessary.
276 // Suggest clamping down the type if the method that is being attempted to
277 // be used exists at all, and the type is an ambiguous numeric type
278 // ({integer}/{float}).
279 let mut candidates = all_traits(self.tcx)
281 .filter_map(|info| self.associated_value(info.def_id, item_name));
282 // There are methods that are defined on the primitive types and won't be
283 // found when exploring `all_traits`, but we also need them to be accurate on
284 // our suggestions (#47759).
285 let found_assoc = |ty: Ty<'tcx>| {
286 simplify_type(tcx, ty, TreatParams::AsPlaceholders)
288 tcx.incoherent_impls(simp)
290 .find_map(|&id| self.associated_value(id, item_name))
294 let found_candidate = candidates.next().is_some()
295 || found_assoc(tcx.types.i8)
296 || found_assoc(tcx.types.i16)
297 || found_assoc(tcx.types.i32)
298 || found_assoc(tcx.types.i64)
299 || found_assoc(tcx.types.i128)
300 || found_assoc(tcx.types.u8)
301 || found_assoc(tcx.types.u16)
302 || found_assoc(tcx.types.u32)
303 || found_assoc(tcx.types.u64)
304 || found_assoc(tcx.types.u128)
305 || found_assoc(tcx.types.f32)
306 || found_assoc(tcx.types.f32);
307 if let (true, false, SelfSource::MethodCall(expr), true) = (
309 actual.has_concrete_skeleton(),
313 let mut err = struct_span_err!(
317 "can't call {} `{}` on ambiguous numeric type `{}`",
322 let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
324 ExprKind::Lit(ref lit) => {
329 .span_to_snippet(lit.span)
330 .unwrap_or_else(|_| "<numeric literal>".to_owned());
332 // If this is a floating point literal that ends with '.',
333 // get rid of it to stop this from becoming a member access.
334 let snippet = snippet.strip_suffix('.').unwrap_or(&snippet);
339 "you must specify a concrete type for this numeric value, \
343 format!("{snippet}_{concrete_type}"),
344 Applicability::MaybeIncorrect,
347 ExprKind::Path(QPath::Resolved(_, path)) => {
349 if let hir::def::Res::Local(hir_id) = path.res {
350 let span = tcx.hir().span(hir_id);
351 let snippet = tcx.sess.source_map().span_to_snippet(span);
352 let filename = tcx.sess.source_map().span_to_filename(span);
355 self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
357 "you must specify a type for this binding, like `{}`",
361 match (filename, parent_node, snippet) {
364 Node::Local(hir::Local {
365 source: hir::LocalSource::Normal,
372 // account for `let x: _ = 42;`
379 format!("{}: {}", snippet, concrete_type),
380 Applicability::MaybeIncorrect,
384 err.span_label(span, msg);
394 span = item_name.span;
396 // Don't show generic arguments when the method can't be found in any implementation (#81576).
397 let mut ty_str_reported = ty_str.clone();
398 if let ty::Adt(_, generics) = actual.kind() {
399 if generics.len() > 0 {
400 let mut autoderef = self.autoderef(span, actual);
401 let candidate_found = autoderef.any(|(ty, _)| {
402 if let ty::Adt(adt_deref, _) = ty.kind() {
404 .inherent_impls(adt_deref.did())
406 .filter_map(|def_id| {
407 self.associated_value(*def_id, item_name)
415 let has_deref = autoderef.step_count() > 0;
418 && unsatisfied_predicates.is_empty()
420 if let Some((path_string, _)) = ty_str.split_once('<') {
421 ty_str_reported = path_string.to_string();
427 let mut err = struct_span_err!(
431 "no {} named `{}` found for {} `{}` in the current scope",
434 actual.prefix_string(self.tcx),
437 if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source {
438 self.suggest_await_before_method(
439 &mut err, item_name, actual, cal, span,
443 tcx.resolutions(()).confused_type_with_std_module.get(&span)
445 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
448 "you are looking for the module in `std`, \
449 not the primitive type",
450 format!("std::{}", snippet),
451 Applicability::MachineApplicable,
455 if let ty::RawPtr(_) = &actual.kind() {
457 "try using `<*const T>::as_ref()` to get a reference to the \
458 type behind the pointer: https://doc.rust-lang.org/std/\
459 primitive.pointer.html#method.as_ref",
462 "using `<*const T>::as_ref()` on a pointer \
463 which is unaligned or points to invalid \
464 or uninitialized memory is undefined behavior",
471 if actual.references_error() {
472 err.downgrade_to_delayed_bug();
475 if let Some(def) = actual.ty_adt_def() {
476 if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
477 let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
481 "{} `{}` not found {}",
484 if def.is_enum() && !is_method { "here" } else { "for this" }
490 if self.is_fn_ty(rcvr_ty, span) {
491 fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
493 &format!("`{}` is a function, perhaps you wish to call it", name,),
497 if let SelfSource::MethodCall(expr) = source {
498 if let Ok(expr_string) = tcx.sess.source_map().span_to_snippet(expr.span) {
499 report_function(&mut err, expr_string);
500 } else if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
501 if let Some(segment) = path.segments.last() {
502 report_function(&mut err, segment.ident);
508 let mut custom_span_label = false;
510 if !static_sources.is_empty() {
512 "found the following associated functions; to be used as methods, \
513 functions must have a `self` parameter",
515 err.span_label(span, "this is an associated function, not a method");
516 custom_span_label = true;
518 if static_sources.len() == 1 {
520 if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) {
521 // When the "method" is resolved through dereferencing, we really want the
522 // original type that has the associated function for accurate suggestions.
524 let ty = tcx.at(span).type_of(*impl_did);
525 match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) {
526 (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
527 // Use `actual` as it will have more `substs` filled in.
528 self.ty_to_value_string(actual.peel_refs())
530 _ => self.ty_to_value_string(ty.peel_refs()),
533 self.ty_to_value_string(actual.peel_refs())
535 if let SelfSource::MethodCall(expr) = source {
538 "use associated function syntax instead",
539 format!("{}::{}", ty_str, item_name),
540 Applicability::MachineApplicable,
543 err.help(&format!("try with `{}::{}`", ty_str, item_name,));
546 report_candidates(span, &mut err, static_sources, sugg_span);
547 } else if static_sources.len() > 1 {
548 report_candidates(span, &mut err, static_sources, sugg_span);
551 let mut bound_spans = vec![];
552 let mut restrict_type_params = false;
553 let mut unsatisfied_bounds = false;
554 if item_name.name == sym::count && self.is_slice_ty(actual, span) {
555 let msg = "consider using `len` instead";
556 if let SelfSource::MethodCall(_expr) = source {
557 err.span_suggestion_short(
561 Applicability::MachineApplicable,
564 err.span_label(span, msg);
566 if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
567 let iterator_trait = self.tcx.def_path_str(iterator_trait);
568 err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
570 } else if !unsatisfied_predicates.is_empty() {
571 let def_span = |def_id| {
572 self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
574 let mut type_params = FxHashMap::default();
576 // Pick out the list of unimplemented traits on the receiver.
577 // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
578 let mut unimplemented_traits = FxHashMap::default();
579 let mut unimplemented_traits_only = true;
580 for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
581 if let (ty::PredicateKind::Trait(p), Some(cause)) =
582 (predicate.kind().skip_binder(), cause.as_ref())
584 if p.trait_ref.self_ty() != rcvr_ty {
585 // This is necessary, not just to keep the errors clean, but also
586 // because our derived obligations can wind up with a trait ref that
587 // requires a different param_env to be correctly compared.
590 unimplemented_traits.entry(p.trait_ref.def_id).or_insert((
591 predicate.kind().rebind(p.trait_ref),
593 cause: cause.clone(),
594 param_env: self.param_env,
595 predicate: predicate.clone(),
602 // Make sure that, if any traits other than the found ones were involved,
603 // we don't don't report an unimplemented trait.
604 // We don't want to say that `iter::Cloned` is not an iterator, just
605 // because of some non-Clone item being iterated over.
606 for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
607 match predicate.kind().skip_binder() {
608 ty::PredicateKind::Trait(p)
609 if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
611 unimplemented_traits_only = false;
617 let mut collect_type_param_suggestions =
618 |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
619 // We don't care about regions here, so it's fine to skip the binder here.
620 if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
621 (self_ty.kind(), parent_pred.kind().skip_binder())
623 let node = match p.trait_ref.self_ty().kind() {
625 // Account for `fn` items like in `issue-35677.rs` to
626 // suggest restricting its type params.
627 let did = self.tcx.hir().body_owner_def_id(hir::BodyId {
628 hir_id: self.body_id,
633 .get(self.tcx.hir().local_def_id_to_hir_id(did)),
636 ty::Adt(def, _) => def.did().as_local().map(|def_id| {
639 .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
643 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
644 if let Some(g) = kind.generics() {
645 let key = match g.where_clause.predicates {
646 [.., pred] => (pred.span().shrink_to_hi(), false),
648 g.where_clause.span_for_predicates_or_empty_place(),
654 .or_insert_with(FxHashSet::default)
655 .insert(obligation.to_owned());
660 let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
662 "doesn't satisfy `{}`",
663 if obligation.len() > 50 { quiet } else { obligation }
665 match &self_ty.kind() {
666 // Point at the type that couldn't satisfy the bound.
667 ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
668 // Point at the trait object that couldn't satisfy the bound.
669 ty::Dynamic(preds, _) => {
670 for pred in preds.iter() {
671 match pred.skip_binder() {
672 ty::ExistentialPredicate::Trait(tr) => {
673 bound_spans.push((def_span(tr.def_id), msg.clone()))
675 ty::ExistentialPredicate::Projection(_)
676 | ty::ExistentialPredicate::AutoTrait(_) => {}
680 // Point at the closure that couldn't satisfy the bound.
681 ty::Closure(def_id, _) => bound_spans
682 .push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
686 let mut format_pred = |pred: ty::Predicate<'tcx>| {
687 let bound_predicate = pred.kind();
688 match bound_predicate.skip_binder() {
689 ty::PredicateKind::Projection(pred) => {
690 let pred = bound_predicate.rebind(pred);
691 // `<Foo as Iterator>::Item = String`.
692 let projection_ty = pred.skip_binder().projection_ty;
694 let substs_with_infer_self = tcx.mk_substs(
695 iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
696 .chain(projection_ty.substs.iter().skip(1)),
699 let quiet_projection_ty = ty::ProjectionTy {
700 substs: substs_with_infer_self,
701 item_def_id: projection_ty.item_def_id,
704 let term = pred.skip_binder().term;
706 let obligation = format!("{} = {}", projection_ty, term);
707 let quiet = format!("{} = {}", quiet_projection_ty, term);
709 bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
710 Some((obligation, projection_ty.self_ty()))
712 ty::PredicateKind::Trait(poly_trait_ref) => {
713 let p = poly_trait_ref.trait_ref;
714 let self_ty = p.self_ty();
715 let path = p.print_only_trait_path();
716 let obligation = format!("{}: {}", self_ty, path);
717 let quiet = format!("_: {}", path);
718 bound_span_label(self_ty, &obligation, &quiet);
719 Some((obligation, self_ty))
725 // Find all the requirements that come from a local `impl` block.
726 let mut skip_list: FxHashSet<_> = Default::default();
727 let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
728 for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
730 .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
731 .filter_map(|(p, parent, c)| match c.code() {
732 ObligationCauseCode::ImplDerivedObligation(ref data) => {
733 Some((&data.derived, p, parent, data.impl_def_id, data.span))
738 let parent_trait_ref = data.parent_trait_pred;
739 let path = parent_trait_ref.print_modifiers_and_trait_path();
740 let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
741 let unsatisfied_msg = "unsatisfied trait bound introduced here".to_string();
743 "unsatisfied trait bound introduced in this `derive` macro";
744 match self.tcx.hir().get_if_local(impl_def_id) {
745 // Unmet obligation comes from a `derive` macro, point at it once to
746 // avoid multiple span labels pointing at the same place.
747 Some(Node::Item(hir::Item {
748 kind: hir::ItemKind::Trait(..),
752 ident.span.ctxt().outer_expn_data().kind,
753 ExpnKind::Macro(MacroKind::Derive, _)
756 let span = ident.span.ctxt().outer_expn_data().call_site;
757 let mut spans: MultiSpan = span.into();
758 spans.push_span_label(span, derive_msg.to_string());
759 let entry = spanned_predicates.entry(spans);
760 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
763 Some(Node::Item(hir::Item {
764 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
767 self_ty.span.ctxt().outer_expn_data().kind,
768 ExpnKind::Macro(MacroKind::Derive, _)
770 of_trait.as_ref().map(|t| t
776 Some(ExpnKind::Macro(MacroKind::Derive, _))
779 let span = self_ty.span.ctxt().outer_expn_data().call_site;
780 let mut spans: MultiSpan = span.into();
781 spans.push_span_label(span, derive_msg.to_string());
782 let entry = spanned_predicates.entry(spans.into());
783 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
786 // Unmet obligation coming from a `trait`.
787 Some(Node::Item(hir::Item {
788 kind: hir::ItemKind::Trait(..),
793 ident.span.ctxt().outer_expn_data().kind,
794 ExpnKind::Macro(MacroKind::Derive, _)
797 if let Some(pred) = parent_p {
798 // Done to add the "doesn't satisfy" `span_label`.
799 let _ = format_pred(*pred);
802 let mut spans = if cause_span != *item_span {
803 let mut spans: MultiSpan = cause_span.into();
804 spans.push_span_label(cause_span, unsatisfied_msg);
809 spans.push_span_label(ident.span, "in this trait".to_string());
810 let entry = spanned_predicates.entry(spans.into());
811 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
814 // Unmet obligation coming from an `impl`.
815 Some(Node::Item(hir::Item {
816 kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
820 self_ty.span.ctxt().outer_expn_data().kind,
821 ExpnKind::Macro(MacroKind::Derive, _)
823 of_trait.as_ref().map(|t| t
829 Some(ExpnKind::Macro(MacroKind::Derive, _))
832 if let Some(pred) = parent_p {
833 // Done to add the "doesn't satisfy" `span_label`.
834 let _ = format_pred(*pred);
837 let mut spans = if cause_span != *item_span {
838 let mut spans: MultiSpan = cause_span.into();
839 spans.push_span_label(cause_span, unsatisfied_msg);
842 let mut spans = Vec::with_capacity(2);
843 if let Some(trait_ref) = of_trait {
844 spans.push(trait_ref.path.span);
846 spans.push(self_ty.span);
849 if let Some(trait_ref) = of_trait {
850 spans.push_span_label(trait_ref.path.span, String::new());
852 spans.push_span_label(self_ty.span, String::new());
854 let entry = spanned_predicates.entry(spans.into());
855 entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
860 let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
861 spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
862 for (span, (_path, _self_ty, preds)) in spanned_predicates {
863 let mut preds: Vec<_> = preds
865 .filter_map(|pred| format_pred(*pred))
866 .map(|(p, _)| format!("`{}`", p))
870 let msg = if let [pred] = &preds[..] {
871 format!("trait bound {} was not satisfied", pred)
874 "the following trait bounds were not satisfied:\n{}",
878 err.span_note(span, &msg);
879 unsatisfied_bounds = true;
882 // The requirements that didn't have an `impl` span to show.
883 let mut bound_list = unsatisfied_predicates
885 .filter_map(|(pred, parent_pred, _cause)| {
886 format_pred(*pred).map(|(p, self_ty)| {
887 collect_type_param_suggestions(self_ty, *pred, &p);
890 None => format!("`{}`", &p),
891 Some(parent_pred) => match format_pred(*parent_pred) {
892 None => format!("`{}`", &p),
893 Some((parent_p, _)) => {
894 collect_type_param_suggestions(
900 "`{}`\nwhich is required by `{}`",
910 .filter(|(_, pred)| !skip_list.contains(&pred))
913 .collect::<Vec<(usize, String)>>();
915 for ((span, empty_where), obligations) in type_params.into_iter() {
916 restrict_type_params = true;
917 // #74886: Sort here so that the output is always the same.
918 let mut obligations = obligations.into_iter().collect::<Vec<_>>();
920 err.span_suggestion_verbose(
923 "consider restricting the type parameter{s} to satisfy the \
925 s = pluralize!(obligations.len())
929 if empty_where { " where" } else { "," },
930 obligations.join(", ")
932 Applicability::MaybeIncorrect,
936 bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
937 bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677
938 bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order.
940 if !bound_list.is_empty() || !skip_list.is_empty() {
941 let bound_list = bound_list
943 .map(|(_, path)| path)
946 let actual_prefix = actual.prefix_string(self.tcx);
947 info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
948 let (primary_message, label) = if unimplemented_traits.len() == 1
949 && unimplemented_traits_only
954 .map(|(_, (trait_ref, obligation))| {
955 if trait_ref.self_ty().references_error()
956 || actual.references_error()
961 let OnUnimplementedNote { message, label, .. } =
962 self.infcx.on_unimplemented_note(trait_ref, &obligation);
965 .unwrap_or((None, None))
969 let primary_message = primary_message.unwrap_or_else(|| format!(
970 "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
972 err.set_primary_message(&primary_message);
973 if let Some(label) = label {
974 custom_span_label = true;
975 err.span_label(span, label);
977 if !bound_list.is_empty() {
979 "the following trait bounds were not satisfied:\n{bound_list}"
982 self.suggest_derive(&mut err, &unsatisfied_predicates);
984 unsatisfied_bounds = true;
988 let mut label_span_not_found = || {
989 if unsatisfied_predicates.is_empty() {
990 err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
991 let is_string_or_ref_str = match actual.kind() {
992 ty::Ref(_, ty, _) => {
996 ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
999 ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
1002 if is_string_or_ref_str && item_name.name == sym::iter {
1003 err.span_suggestion_verbose(
1005 "because of the in-memory representation of `&str`, to obtain \
1006 an `Iterator` over each of its codepoint use method `chars`",
1007 String::from("chars"),
1008 Applicability::MachineApplicable,
1011 if let ty::Adt(adt, _) = rcvr_ty.kind() {
1012 let mut inherent_impls_candidate = self
1014 .inherent_impls(adt.did())
1018 if let Some(assoc) = self.associated_value(*def_id, item_name) {
1019 // Check for both mode is the same so we avoid suggesting
1020 // incorrect associated item.
1021 match (mode, assoc.fn_has_self_parameter, source) {
1022 (Mode::MethodCall, true, SelfSource::MethodCall(_)) => {
1023 // We check that the suggest type is actually
1024 // different from the received one
1025 // So we avoid suggestion method with Box<Self>
1027 self.tcx.at(span).type_of(*def_id) != actual
1028 && self.tcx.at(span).type_of(*def_id) != rcvr_ty
1030 (Mode::Path, false, _) => true,
1037 .collect::<Vec<_>>();
1038 if !inherent_impls_candidate.is_empty() {
1039 inherent_impls_candidate.sort();
1040 inherent_impls_candidate.dedup();
1042 // number of type to shows at most.
1043 let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
1044 let type_candidates = inherent_impls_candidate
1048 format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
1050 .collect::<Vec<_>>()
1052 let additional_types = if inherent_impls_candidate.len() > limit {
1054 "\nand {} more types",
1055 inherent_impls_candidate.len() - limit
1061 "the {item_kind} was found for\n{}{}",
1062 type_candidates, additional_types
1067 err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
1071 // If the method name is the name of a field with a function or closure type,
1072 // give a helping note that it has to be called as `(x.f)(...)`.
1073 if let SelfSource::MethodCall(expr) = source {
1074 let field_receiver =
1075 self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
1076 ty::Adt(def, substs) if !def.is_enum() => {
1077 let variant = &def.non_enum_variant();
1078 self.tcx.find_field_index(item_name, variant).map(|index| {
1079 let field = &variant.fields[index];
1080 let field_ty = field.ty(tcx, substs);
1087 if let Some((field, field_ty)) = field_receiver {
1088 let scope = self.tcx.parent_module(self.body_id).to_def_id();
1089 let is_accessible = field.vis.is_accessible_from(scope, self.tcx);
1092 if self.is_fn_ty(field_ty, span) {
1093 let expr_span = expr.span.to(item_name.span);
1094 err.multipart_suggestion(
1096 "to call the function stored in `{}`, \
1097 surround the field access with parentheses",
1101 (expr_span.shrink_to_lo(), '('.to_string()),
1102 (expr_span.shrink_to_hi(), ')'.to_string()),
1104 Applicability::MachineApplicable,
1107 let call_expr = self
1110 .expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1112 if let Some(span) = call_expr.span.trim_start(item_name.span) {
1113 err.span_suggestion(
1115 "remove the arguments",
1117 Applicability::MaybeIncorrect,
1123 let field_kind = if is_accessible { "field" } else { "private field" };
1124 err.span_label(item_name.span, format!("{}, not a method", field_kind));
1125 } else if lev_candidate.is_none() && !custom_span_label {
1126 label_span_not_found();
1128 } else if !custom_span_label {
1129 label_span_not_found();
1133 bound_spans.dedup();
1134 for (span, msg) in bound_spans.into_iter() {
1135 err.span_label(span, &msg);
1138 if actual.is_numeric() && actual.is_fresh() || restrict_type_params {
1140 self.suggest_traits_to_import(
1146 out_of_scope_traits,
1147 &unsatisfied_predicates,
1152 // Don't emit a suggestion if we found an actual method
1153 // that had unsatisfied trait bounds
1154 if unsatisfied_predicates.is_empty() && actual.is_enum() {
1155 let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
1156 if let Some(suggestion) = lev_distance::find_best_match_for_name(
1157 &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
1161 err.span_suggestion(
1163 "there is a variant with a similar name",
1164 suggestion.to_string(),
1165 Applicability::MaybeIncorrect,
1170 if item_name.name == sym::as_str && actual.peel_refs().is_str() {
1171 let msg = "remove this method call";
1172 let mut fallback_span = true;
1173 if let SelfSource::MethodCall(expr) = source {
1175 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
1176 if let Some(span) = call_expr.span.trim_start(expr.span) {
1177 err.span_suggestion(
1181 Applicability::MachineApplicable,
1183 fallback_span = false;
1187 err.span_label(span, msg);
1189 } else if let Some(lev_candidate) = lev_candidate {
1190 // Don't emit a suggestion if we found an actual method
1191 // that had unsatisfied trait bounds
1192 if unsatisfied_predicates.is_empty() {
1193 let def_kind = lev_candidate.kind.as_def_kind();
1194 err.span_suggestion(
1197 "there is {} {} with a similar name",
1199 def_kind.descr(lev_candidate.def_id),
1201 lev_candidate.name.to_string(),
1202 Applicability::MaybeIncorrect,
1210 MethodError::Ambiguity(sources) => {
1211 let mut err = struct_span_err!(
1215 "multiple applicable items in scope"
1217 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
1219 report_candidates(span, &mut err, sources, sugg_span);
1223 MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
1224 let kind = kind.descr(def_id);
1225 let mut err = struct_span_err!(
1229 "{} `{}` is private",
1233 err.span_label(item_name.span, &format!("private {}", kind));
1237 .span_if_local(def_id)
1238 .unwrap_or_else(|| self.tcx.def_span(def_id));
1239 err.span_label(sp, &format!("private {} defined here", kind));
1240 self.suggest_valid_traits(&mut err, out_of_scope_traits);
1244 MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
1245 let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
1246 let mut err = self.sess().struct_span_err(span, &msg);
1247 err.span_label(bound_span, "this has a `Sized` requirement");
1248 if !candidates.is_empty() {
1250 "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
1251 add a `use` for {one_of_them}:",
1252 an = if candidates.len() == 1 { "an" } else { "" },
1253 s = pluralize!(candidates.len()),
1254 were = if candidates.len() == 1 { "was" } else { "were" },
1255 one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
1257 self.suggest_use_candidates(&mut err, help, candidates);
1259 if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
1261 let trait_type = self.tcx.mk_ref(
1263 ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
1265 err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
1271 MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
1276 crate fn note_unmet_impls_on_type(
1278 err: &mut Diagnostic,
1279 errors: Vec<FulfillmentError<'tcx>>,
1281 let all_local_types_needing_impls =
1282 errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
1283 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
1284 ty::Adt(def, _) => def.did().is_local(),
1289 let mut preds: Vec<_> = errors
1291 .filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
1292 ty::PredicateKind::Trait(pred) => Some(pred),
1296 preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty()));
1299 .filter_map(|pred| match pred.self_ty().kind() {
1300 ty::Adt(def, _) => Some(def.did()),
1303 .collect::<FxHashSet<_>>();
1304 let sm = self.tcx.sess.source_map();
1305 let mut spans: MultiSpan = def_ids
1307 .filter_map(|def_id| {
1308 let span = self.tcx.def_span(*def_id);
1309 if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
1311 .collect::<Vec<_>>()
1314 for pred in &preds {
1315 match pred.self_ty().kind() {
1316 ty::Adt(def, _) => {
1317 spans.push_span_label(
1318 sm.guess_head_span(self.tcx.def_span(def.did())),
1319 format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
1326 if all_local_types_needing_impls && spans.primary_span().is_some() {
1327 let msg = if preds.len() == 1 {
1329 "an implementation of `{}` might be missing for `{}`",
1330 preds[0].trait_ref.print_only_trait_path(),
1335 "the following type{} would have to `impl` {} required trait{} for this \
1336 operation to be valid",
1337 pluralize!(def_ids.len()),
1338 if def_ids.len() == 1 { "its" } else { "their" },
1339 pluralize!(preds.len()),
1342 err.span_note(spans, &msg);
1345 let preds: Vec<_> = errors
1347 .map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
1349 self.suggest_derive(err, &preds);
1354 err: &mut Diagnostic,
1355 unsatisfied_predicates: &[(
1356 ty::Predicate<'tcx>,
1357 Option<ty::Predicate<'tcx>>,
1358 Option<ObligationCause<'tcx>>,
1361 let mut derives = Vec::<(String, Span, String)>::new();
1362 let mut traits = Vec::<Span>::new();
1363 for (pred, _, _) in unsatisfied_predicates {
1364 let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
1365 let adt = match trait_pred.self_ty().ty_adt_def() {
1366 Some(adt) if adt.did().is_local() => adt,
1369 if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1370 let can_derive = match diagnostic_name {
1371 sym::Default => !adt.is_enum(),
1379 | sym::Debug => true,
1383 let self_name = trait_pred.self_ty().to_string();
1384 let self_span = self.tcx.def_span(adt.did());
1385 if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
1386 for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
1388 if let Some(parent_diagnostic_name) =
1389 self.tcx.get_diagnostic_name(super_trait.def_id())
1394 parent_diagnostic_name.to_string(),
1399 derives.push((self_name, self_span, diagnostic_name.to_string()));
1401 traits.push(self.tcx.def_span(trait_pred.def_id()));
1404 traits.push(self.tcx.def_span(trait_pred.def_id()));
1413 let mut derives_grouped = Vec::<(String, Span, String)>::new();
1414 for (self_name, self_span, trait_name) in derives.into_iter() {
1415 if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
1417 if last_self_name == &self_name {
1418 last_trait_names.push_str(format!(", {}", trait_name).as_str());
1422 derives_grouped.push((self_name, self_span, trait_name));
1425 let len = traits.len();
1427 let span: MultiSpan = traits.into();
1430 &format!("the following trait{} must be implemented", pluralize!(len),),
1434 for (self_name, self_span, traits) in &derives_grouped {
1435 err.span_suggestion_verbose(
1436 self_span.shrink_to_lo(),
1437 &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits),
1438 format!("#[derive({})]\n", traits),
1439 Applicability::MaybeIncorrect,
1444 /// Print out the type for use in value namespace.
1445 fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
1447 ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)),
1448 _ => self.ty_to_string(ty),
1452 fn suggest_await_before_method(
1454 err: &mut Diagnostic,
1457 call: &hir::Expr<'_>,
1460 let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1461 Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
1464 let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);
1465 debug!("suggest_await_before_method: is_method_exist={}", method_exists);
1467 err.span_suggestion_verbose(
1468 span.shrink_to_lo(),
1469 "consider `await`ing on the `Future` and calling the method on its `Output`",
1470 "await.".to_string(),
1471 Applicability::MaybeIncorrect,
1476 fn suggest_use_candidates(
1478 err: &mut Diagnostic,
1480 candidates: Vec<DefId>,
1482 let parent_map = self.tcx.visible_parent_map(());
1484 // Separate out candidates that must be imported with a glob, because they are named `_`
1485 // and cannot be referred with their identifier.
1486 let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
1487 if let Some(parent_did) = parent_map.get(trait_did) {
1488 // If the item is re-exported as `_`, we should suggest a glob-import instead.
1489 if Some(*parent_did) != self.tcx.parent(*trait_did)
1492 .module_children(*parent_did)
1494 .filter(|child| child.res.opt_def_id() == Some(*trait_did))
1495 .all(|child| child.ident.name == kw::Underscore)
1504 let module_did = self.tcx.parent_module(self.body_id);
1505 let (span, found_use) = find_use_placement(self.tcx, module_did);
1506 if let Some(span) = span {
1507 let path_strings = candidates.iter().map(|trait_did| {
1508 // Produce an additional newline to separate the new use statement
1509 // from the directly following item.
1510 let additional_newline = if found_use { "" } else { "\n" };
1513 with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
1518 let glob_path_strings = globs.iter().map(|trait_did| {
1519 let parent_did = parent_map.get(trait_did).unwrap();
1521 // Produce an additional newline to separate the new use statement
1522 // from the directly following item.
1523 let additional_newline = if found_use { "" } else { "\n" };
1525 "use {}::*; // trait {}\n{}",
1526 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1527 self.tcx.item_name(*trait_did),
1532 err.span_suggestions(
1535 path_strings.chain(glob_path_strings),
1536 Applicability::MaybeIncorrect,
1539 let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 };
1540 for (i, trait_did) in candidates.iter().take(limit).enumerate() {
1541 if candidates.len() + globs.len() > 1 {
1542 msg.push_str(&format!(
1543 "\ncandidate #{}: `use {};`",
1545 with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1548 msg.push_str(&format!(
1550 with_crate_prefix!(self.tcx.def_path_str(*trait_did))
1554 for (i, trait_did) in
1555 globs.iter().take(limit.saturating_sub(candidates.len())).enumerate()
1557 let parent_did = parent_map.get(trait_did).unwrap();
1559 if candidates.len() + globs.len() > 1 {
1560 msg.push_str(&format!(
1561 "\ncandidate #{}: `use {}::*; // trait {}`",
1562 candidates.len() + i + 1,
1563 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1564 self.tcx.item_name(*trait_did),
1567 msg.push_str(&format!(
1568 "\n`use {}::*; // trait {}`",
1569 with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
1570 self.tcx.item_name(*trait_did),
1574 if candidates.len() > limit {
1575 msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit));
1581 fn suggest_valid_traits(
1583 err: &mut Diagnostic,
1584 valid_out_of_scope_traits: Vec<DefId>,
1586 if !valid_out_of_scope_traits.is_empty() {
1587 let mut candidates = valid_out_of_scope_traits;
1591 // `TryFrom` and `FromIterator` have no methods
1592 let edition_fix = candidates
1594 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
1597 err.help("items from traits can only be used if the trait is in scope");
1599 "the following {traits_are} implemented but not in scope; \
1600 perhaps add a `use` for {one_of_them}:",
1601 traits_are = if candidates.len() == 1 { "trait is" } else { "traits are" },
1602 one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
1605 self.suggest_use_candidates(err, msg, candidates);
1606 if let Some(did) = edition_fix {
1608 "'{}' is included in the prelude starting in Edition 2021",
1609 with_crate_prefix!(self.tcx.def_path_str(did))
1619 fn suggest_traits_to_import(
1621 err: &mut Diagnostic,
1625 source: SelfSource<'tcx>,
1626 valid_out_of_scope_traits: Vec<DefId>,
1627 unsatisfied_predicates: &[(
1628 ty::Predicate<'tcx>,
1629 Option<ty::Predicate<'tcx>>,
1630 Option<ObligationCause<'tcx>>,
1632 unsatisfied_bounds: bool,
1634 let mut alt_rcvr_sugg = false;
1635 if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
1636 debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
1638 self.tcx.lang_items().clone_trait(),
1639 self.tcx.lang_items().deref_trait(),
1640 self.tcx.lang_items().deref_mut_trait(),
1641 self.tcx.lang_items().drop_trait(),
1642 self.tcx.get_diagnostic_item(sym::AsRef),
1644 // Try alternative arbitrary self types that could fulfill this call.
1645 // FIXME: probe for all types that *could* be arbitrary self-types, not
1647 for (rcvr_ty, post) in &[
1649 (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
1650 (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
1652 match self.lookup_probe(
1657 crate::check::method::probe::ProbeScope::AllTraits,
1660 // If the method is defined for the receiver we have, it likely wasn't `use`d.
1661 // We point at the method, but we just skip the rest of the check for arbitrary
1662 // self types and rely on the suggestion to `use` the trait from
1663 // `suggest_valid_traits`.
1664 let did = Some(pick.item.container.id());
1665 let skip = skippable.contains(&did);
1666 if pick.autoderefs == 0 && !skip {
1668 pick.item.ident(self.tcx).span,
1669 &format!("the method is available for `{}` here", rcvr_ty),
1674 Err(MethodError::Ambiguity(_)) => {
1675 // If the method is defined (but ambiguous) for the receiver we have, it is also
1676 // likely we haven't `use`d it. It may be possible that if we `Box`/`Pin`/etc.
1677 // the receiver, then it might disambiguate this method, but I think these
1678 // suggestions are generally misleading (see #94218).
1684 for (rcvr_ty, pre) in &[
1685 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::OwnedBox), "Box::new"),
1686 (self.tcx.mk_lang_item(*rcvr_ty, LangItem::Pin), "Pin::new"),
1687 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Arc), "Arc::new"),
1688 (self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Rc), "Rc::new"),
1690 if let Some(new_rcvr_t) = *rcvr_ty && let Ok(pick) = self.lookup_probe(
1695 crate::check::method::probe::ProbeScope::AllTraits,
1697 debug!("try_alt_rcvr: pick candidate {:?}", pick);
1698 let did = Some(pick.item.container.id());
1699 // We don't want to suggest a container type when the missing
1700 // method is `.clone()` or `.deref()` otherwise we'd suggest
1701 // `Arc::new(foo).clone()`, which is far from what the user wants.
1702 // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
1703 // implement the `AsRef` trait.
1704 let skip = skippable.contains(&did)
1705 || (("Pin::new" == *pre) && (sym::as_ref == item_name.name));
1706 // Make sure the method is defined for the *actual* receiver: we don't
1707 // want to treat `Box<Self>` as a receiver if it only works because of
1708 // an autoderef to `&self`
1709 if pick.autoderefs == 0 && !skip {
1711 pick.item.ident(self.tcx).span,
1712 &format!("the method is available for `{}` here", new_rcvr_t),
1714 err.multipart_suggestion(
1715 "consider wrapping the receiver expression with the \
1718 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1719 (rcvr.span.shrink_to_hi(), ")".to_string()),
1721 Applicability::MaybeIncorrect,
1723 // We don't care about the other suggestions.
1724 alt_rcvr_sugg = true;
1730 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1734 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1736 let mut arbitrary_rcvr = vec![];
1737 // There are no traits implemented, so lets suggest some traits to
1738 // implement, by finding ones that have the item name, and are
1739 // legal to implement.
1740 let mut candidates = all_traits(self.tcx)
1742 // Don't issue suggestions for unstable traits since they're
1743 // unlikely to be implementable anyway
1744 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1745 Some(attr) => attr.level.is_stable(),
1749 // We approximate the coherence rules to only suggest
1750 // traits that are legal to implement by requiring that
1751 // either the type or trait is local. Multi-dispatch means
1752 // this isn't perfect (that is, there are cases when
1753 // implementing a trait would be legal but is rejected
1755 unsatisfied_predicates.iter().all(|(p, _, _)| {
1756 match p.kind().skip_binder() {
1757 // Hide traits if they are present in predicates as they can be fixed without
1758 // having to implement them.
1759 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1760 ty::PredicateKind::Projection(p) => {
1761 p.projection_ty.item_def_id == info.def_id
1765 }) && (type_is_local || info.def_id.is_local())
1767 .associated_value(info.def_id, item_name)
1769 if let ty::AssocKind::Fn = item.kind {
1773 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1774 if let Some(hir::Node::TraitItem(hir::TraitItem {
1775 kind: hir::TraitItemKind::Fn(fn_sig, method),
1777 })) = id.map(|id| self.tcx.hir().get(id))
1779 let self_first_arg = match method {
1780 hir::TraitFn::Required([ident, ..]) => {
1781 ident.name == kw::SelfLower
1783 hir::TraitFn::Provided(body_id) => {
1784 self.tcx.hir().body(*body_id).params.first().map_or(
1789 hir::PatKind::Binding(_, _, ident, _)
1790 if ident.name == kw::SelfLower
1798 if !fn_sig.decl.implicit_self.has_implicit_self()
1801 if let Some(ty) = fn_sig.decl.inputs.get(0) {
1802 arbitrary_rcvr.push(ty.span);
1808 // We only want to suggest public or local traits (#45781).
1809 item.vis.is_public() || info.def_id.is_local()
1813 .collect::<Vec<_>>();
1814 for span in &arbitrary_rcvr {
1817 "the method might not be found because of this arbitrary self type",
1824 if !candidates.is_empty() {
1825 // Sort from most relevant to least relevant.
1826 candidates.sort_by(|a, b| a.cmp(b).reverse());
1829 let param_type = match rcvr_ty.kind() {
1830 ty::Param(param) => Some(param),
1831 ty::Ref(_, ty, _) => match ty.kind() {
1832 ty::Param(param) => Some(param),
1837 err.help(if param_type.is_some() {
1838 "items from traits can only be used if the type parameter is bounded by the trait"
1840 "items from traits can only be used if the trait is implemented and in scope"
1842 let candidates_len = candidates.len();
1843 let message = |action| {
1845 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1848 if candidates_len == 1 { "trait defines" } else { "traits define" },
1850 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1854 // Obtain the span for `param` and use it for a structured suggestion.
1855 if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1856 let table_owner = table.borrow().hir_owner;
1857 let generics = self.tcx.generics_of(table_owner.to_def_id());
1858 let type_param = generics.type_param(param, self.tcx);
1859 let hir = self.tcx.hir();
1860 if let Some(def_id) = type_param.def_id.as_local() {
1861 let id = hir.local_def_id_to_hir_id(def_id);
1862 // Get the `hir::Param` to verify whether it already has any bounds.
1863 // We do this to avoid suggesting code that ends up as `T: FooBar`,
1864 // instead we suggest `T: Foo + Bar` in that case.
1866 Node::GenericParam(param) => {
1867 let mut impl_trait = false;
1869 if let hir::GenericParamKind::Type { synthetic: true, .. } =
1872 // We've found `fn foo(x: impl Trait)` instead of
1873 // `fn foo<T>(x: T)`. We want to suggest the correct
1874 // `fn foo(x: impl Trait + TraitBound)` instead of
1875 // `fn foo<T: TraitBound>(x: T)`. (#63706)
1881 let sp = hir.span(id);
1882 let sp = if let Some(first_bound) = has_bounds {
1883 // `sp` only covers `T`, change it so that it covers
1884 // `T:` when appropriate
1885 sp.until(first_bound.span())
1889 let trait_def_ids: FxHashSet<DefId> = param
1892 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1894 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1895 err.span_suggestions(
1898 "restrict type parameter `{}` with",
1901 candidates.iter().map(|t| {
1905 if impl_trait { " +" } else { ":" },
1906 self.tcx.def_path_str(t.def_id),
1907 if has_bounds.is_some() { " + " } else { "" },
1910 Applicability::MaybeIncorrect,
1915 Node::Item(hir::Item {
1916 kind: hir::ItemKind::Trait(.., bounds, _),
1920 let (sp, sep, article) = if bounds.is_empty() {
1921 (ident.span.shrink_to_hi(), ":", "a")
1923 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1925 err.span_suggestions(
1927 &message(format!("add {} supertrait for", article)),
1928 candidates.iter().map(|t| {
1929 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1931 Applicability::MaybeIncorrect,
1940 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1941 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1942 // cases where a positive bound implies a negative impl.
1943 (candidates, Vec::new())
1944 } else if let Some(simp_rcvr_ty) =
1945 simplify_type(self.tcx, rcvr_ty, TreatParams::AsBoundTypes)
1947 let mut potential_candidates = Vec::new();
1948 let mut explicitly_negative = Vec::new();
1949 for candidate in candidates {
1950 // Check if there's a negative impl of `candidate` for `rcvr_ty`
1953 .all_impls(candidate.def_id)
1955 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1958 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1960 simplify_type(self.tcx, imp.self_ty(), TreatParams::AsBoundTypes);
1961 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1964 explicitly_negative.push(candidate);
1966 potential_candidates.push(candidate);
1969 (potential_candidates, explicitly_negative)
1971 // We don't know enough about `recv_ty` to make proper suggestions.
1972 (candidates, Vec::new())
1975 let action = if let Some(param) = param_type {
1976 format!("restrict type parameter `{}` with", param)
1978 // FIXME: it might only need to be imported into scope, not implemented.
1979 "implement".to_string()
1981 match &potential_candidates[..] {
1983 [trait_info] if trait_info.def_id.is_local() => {
1984 let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1986 self.tcx.sess.source_map().guess_head_span(span),
1988 "`{}` defines an item `{}`, perhaps you need to {} it",
1989 self.tcx.def_path_str(trait_info.def_id),
1996 let mut msg = message(action);
1997 for (i, trait_info) in trait_infos.iter().enumerate() {
1998 msg.push_str(&format!(
1999 "\ncandidate #{}: `{}`",
2001 self.tcx.def_path_str(trait_info.def_id),
2007 match &explicitly_negative[..] {
2011 "the trait `{}` defines an item `{}`, but is explicitly unimplemented",
2012 self.tcx.def_path_str(trait_info.def_id),
2018 let mut msg = format!(
2019 "the following traits define an item `{}`, but are explicitly unimplemented:",
2022 for trait_info in trait_infos {
2023 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
2031 /// Checks whether there is a local type somewhere in the chain of
2032 /// autoderefs of `rcvr_ty`.
2033 fn type_derefs_to_local(
2037 source: SelfSource<'tcx>,
2039 fn is_local(ty: Ty<'_>) -> bool {
2041 ty::Adt(def, _) => def.did().is_local(),
2042 ty::Foreign(did) => did.is_local(),
2043 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
2044 ty::Param(_) => true,
2046 // Everything else (primitive types, etc.) is effectively
2047 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
2048 // the noise from these sort of types is usually just really
2049 // annoying, rather than any sort of help).
2054 // This occurs for UFCS desugaring of `T::method`, where there is no
2055 // receiver expression for the method call, and thus no autoderef.
2056 if let SelfSource::QPath(_) = source {
2057 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
2060 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
2064 #[derive(Copy, Clone, Debug)]
2065 pub enum SelfSource<'a> {
2066 QPath(&'a hir::Ty<'a>),
2067 MethodCall(&'a hir::Expr<'a> /* rcvr */),
2070 #[derive(Copy, Clone)]
2071 pub struct TraitInfo {
2075 impl PartialEq for TraitInfo {
2076 fn eq(&self, other: &TraitInfo) -> bool {
2077 self.cmp(other) == Ordering::Equal
2080 impl Eq for TraitInfo {}
2081 impl PartialOrd for TraitInfo {
2082 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
2083 Some(self.cmp(other))
2086 impl Ord for TraitInfo {
2087 fn cmp(&self, other: &TraitInfo) -> Ordering {
2088 // Local crates are more important than remote ones (local:
2089 // `cnum == 0`), and otherwise we throw in the defid for totality.
2091 let lhs = (other.def_id.krate, other.def_id);
2092 let rhs = (self.def_id.krate, self.def_id);
2097 /// Retrieves all traits in this crate and any dependent crates,
2098 /// and wraps them into `TraitInfo` for custom sorting.
2099 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2100 tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
2103 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
2104 // FIXME(#94854): this code uses an out-of-date method for inferring a span
2105 // to suggest. It would be better to thread the ModSpans from the AST into
2106 // the HIR, and then use that to drive the suggestion here.
2108 let mut span = None;
2109 let mut found_use = false;
2110 let (module, _, _) = tcx.hir().get_module(target_module);
2112 // Find a `use` statement.
2113 for &item_id in module.item_ids {
2114 let item = tcx.hir().item(item_id);
2116 hir::ItemKind::Use(..) => {
2117 // Don't suggest placing a `use` before the prelude
2118 // import or other generated ones.
2119 if !item.span.from_expansion() {
2120 span = Some(item.span.shrink_to_lo());
2125 // Don't place `use` before `extern crate`...
2126 hir::ItemKind::ExternCrate(_) => {}
2127 // ...but do place them before the first other item.
2129 if span.map_or(true, |span| item.span < span) {
2130 if !item.span.from_expansion() {
2131 span = Some(item.span.shrink_to_lo());
2132 // Don't insert between attributes and an item.
2133 let attrs = tcx.hir().attrs(item.hir_id());
2134 // Find the first attribute on the item.
2135 // FIXME: This is broken for active attributes.
2137 if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
2138 span = Some(attr.span.shrink_to_lo());
2150 fn print_disambiguation_help<'tcx>(
2152 args: Option<&'tcx [hir::Expr<'tcx>]>,
2153 err: &mut Diagnostic,
2156 kind: ty::AssocKind,
2159 candidate: Option<usize>,
2160 source_map: &source_map::SourceMap,
2161 fn_has_self_parameter: bool,
2163 let mut applicability = Applicability::MachineApplicable;
2164 let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
2167 if rcvr_ty.is_region_ptr() {
2168 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
2173 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
2174 applicability = Applicability::HasPlaceholders;
2177 .collect::<Vec<_>>()
2180 let trait_name = if !fn_has_self_parameter {
2181 format!("<{} as {}>", rcvr_ty, trait_name)
2185 (span, format!("{}::{}{}", trait_name, item_name, args))
2187 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
2189 err.span_suggestion_verbose(
2192 "disambiguate the {} for {}",
2193 kind.as_def_kind().descr(def_id),
2194 if let Some(candidate) = candidate {
2195 format!("candidate #{}", candidate)
2197 "the candidate".to_string()