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};
6 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
8 use rustc_hir::def::{DefKind, Namespace, Res};
9 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
10 use rustc_hir::lang_items::LangItem;
11 use rustc_hir::{ExprKind, Node, QPath};
12 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
13 use rustc_middle::ty::fast_reject::simplify_type;
14 use rustc_middle::ty::print::with_crate_prefix;
15 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
16 use rustc_span::lev_distance;
17 use rustc_span::symbol::{kw, sym, Ident};
18 use rustc_span::{source_map, FileName, MultiSpan, Span};
19 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
20 use rustc_trait_selection::traits::{FulfillmentError, Obligation};
22 use std::cmp::Ordering;
25 use super::probe::Mode;
26 use super::{CandidateSource, MethodError, NoMatchData};
28 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29 fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
32 // Not all of these (e.g., unsafe fns) implement `FnOnce`,
33 // so we look for these beforehand.
34 ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
35 // If it's not a simple function, look for things which implement `FnOnce`.
37 let fn_once = match tcx.lang_items().require(LangItem::FnOnce) {
38 Ok(fn_once) => fn_once,
39 Err(..) => return false,
42 self.autoderef(span, ty).any(|(ty, _)| {
44 let fn_once_substs = tcx.mk_substs_trait(
47 .next_ty_var(TypeVariableOrigin {
48 kind: TypeVariableOriginKind::MiscVariable,
53 let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
54 let poly_trait_ref = ty::Binder::dummy(trait_ref);
55 let obligation = Obligation::misc(
59 poly_trait_ref.without_const().to_predicate(tcx),
61 self.predicate_may_hold(&obligation)
68 pub fn report_method_error(
73 source: SelfSource<'tcx>,
74 error: MethodError<'tcx>,
75 args: Option<&'tcx [hir::Expr<'tcx>]>,
76 ) -> Option<DiagnosticBuilder<'_>> {
77 // Avoid suggestions when we don't know what's going on.
78 if rcvr_ty.references_error() {
82 let report_candidates = |span: Span,
83 err: &mut DiagnosticBuilder<'_>,
84 mut sources: Vec<CandidateSource>,
88 // Dynamic limit to avoid hiding just one candidate, which is silly.
89 let limit = if sources.len() == 5 { 5 } else { 4 };
91 for (idx, source) in sources.iter().take(limit).enumerate() {
93 CandidateSource::ImplSource(impl_did) => {
94 // Provide the best span we can. Use the item, if local to crate, else
95 // the impl, if local to crate (item may be defaulted), else nothing.
97 .associated_item(impl_did, item_name, Namespace::ValueNS)
99 let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
100 self.associated_item(
101 impl_trait_ref.def_id,
112 .span_if_local(item.def_id)
113 .or_else(|| self.tcx.hir().span_if_local(impl_did));
115 let impl_ty = self.tcx.at(span).type_of(impl_did);
117 let insertion = match self.tcx.impl_trait_ref(impl_did) {
118 None => String::new(),
119 Some(trait_ref) => format!(
120 " of the trait `{}`",
121 self.tcx.def_path_str(trait_ref.def_id)
125 let (note_str, idx) = if sources.len() > 1 {
128 "candidate #{} is defined in an impl{} for the type `{}`",
138 "the candidate is defined in an impl{} for the type `{}`",
144 if let Some(note_span) = note_span {
145 // We have a span pointing to the method. Show note with snippet.
147 self.tcx.sess.source_map().guess_head_span(note_span),
153 if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
154 let path = self.tcx.def_path_str(trait_ref.def_id);
156 let ty = match item.kind {
157 ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
158 ty::AssocKind::Fn => self
164 .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
168 print_disambiguation_help(
178 self.tcx.sess.source_map(),
179 item.fn_has_self_parameter,
183 CandidateSource::TraitSource(trait_did) => {
185 match self.associated_item(trait_did, item_name, Namespace::ValueNS) {
193 .guess_head_span(self.tcx.def_span(item.def_id));
194 let idx = if sources.len() > 1 {
196 "candidate #{} is defined in the trait `{}`",
198 self.tcx.def_path_str(trait_did)
200 err.span_note(item_span, msg);
204 "the candidate is defined in the trait `{}`",
205 self.tcx.def_path_str(trait_did)
207 err.span_note(item_span, msg);
210 let path = self.tcx.def_path_str(trait_did);
211 print_disambiguation_help(
221 self.tcx.sess.source_map(),
222 item.fn_has_self_parameter,
227 if sources.len() > limit {
228 err.note(&format!("and {} others", sources.len() - limit));
232 let sugg_span = if let SelfSource::MethodCall(expr) = source {
233 // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
234 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span
240 MethodError::NoMatch(NoMatchData {
241 static_candidates: static_sources,
242 unsatisfied_predicates,
249 let actual = self.resolve_vars_if_possible(rcvr_ty);
250 let ty_str = self.ty_to_string(actual);
251 let is_method = mode == Mode::MethodCall;
252 let item_kind = if is_method {
254 } else if actual.is_enum() {
255 "variant or associated item"
257 match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
258 (Some(name), false) if name.is_lowercase() => "function or associated item",
259 (Some(_), false) => "associated item",
260 (Some(_), true) | (None, false) => "variant or associated item",
261 (None, true) => "variant",
264 let mut err = if !actual.references_error() {
265 // Suggest clamping down the type if the method that is being attempted to
266 // be used exists at all, and the type is an ambiguous numeric type
267 // ({integer}/{float}).
268 let mut candidates = all_traits(self.tcx).into_iter().filter_map(|info| {
269 self.associated_item(info.def_id, item_name, Namespace::ValueNS)
271 // There are methods that are defined on the primitive types and won't be
272 // found when exploring `all_traits`, but we also need them to be acurate on
273 // our suggestions (#47759).
274 let fund_assoc = |opt_def_id: Option<DefId>| {
276 .and_then(|id| self.associated_item(id, item_name, Namespace::ValueNS))
279 let lang_items = tcx.lang_items();
280 let found_candidate = candidates.next().is_some()
281 || fund_assoc(lang_items.i8_impl())
282 || fund_assoc(lang_items.i16_impl())
283 || fund_assoc(lang_items.i32_impl())
284 || fund_assoc(lang_items.i64_impl())
285 || fund_assoc(lang_items.i128_impl())
286 || fund_assoc(lang_items.u8_impl())
287 || fund_assoc(lang_items.u16_impl())
288 || fund_assoc(lang_items.u32_impl())
289 || fund_assoc(lang_items.u64_impl())
290 || fund_assoc(lang_items.u128_impl())
291 || fund_assoc(lang_items.f32_impl())
292 || fund_assoc(lang_items.f32_runtime_impl())
293 || fund_assoc(lang_items.f64_impl())
294 || fund_assoc(lang_items.f64_runtime_impl());
295 if let (true, false, SelfSource::MethodCall(expr), true) = (
297 actual.has_concrete_skeleton(),
301 let mut err = struct_span_err!(
305 "can't call {} `{}` on ambiguous numeric type `{}`",
310 let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
312 ExprKind::Lit(ref lit) => {
317 .span_to_snippet(lit.span)
318 .unwrap_or_else(|_| "<numeric literal>".to_owned());
323 "you must specify a concrete type for this numeric value, \
327 format!("{}_{}", snippet, concrete_type),
328 Applicability::MaybeIncorrect,
331 ExprKind::Path(QPath::Resolved(_, path)) => {
333 if let hir::def::Res::Local(hir_id) = path.res {
334 let span = tcx.hir().span(hir_id);
335 let snippet = tcx.sess.source_map().span_to_snippet(span);
336 let filename = tcx.sess.source_map().span_to_filename(span);
339 self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id));
341 "you must specify a type for this binding, like `{}`",
345 match (filename, parent_node, snippet) {
348 Node::Local(hir::Local {
349 source: hir::LocalSource::Normal,
356 // account for `let x: _ = 42;`
363 format!("{}: {}", snippet, concrete_type),
364 Applicability::MaybeIncorrect,
368 err.span_label(span, msg);
378 span = item_name.span;
380 // Don't show generic arguments when the method can't be found in any implementation (#81576).
381 let mut ty_str_reported = ty_str.clone();
382 if let ty::Adt(_, generics) = actual.kind() {
383 if generics.len() > 0 {
384 let mut autoderef = self.autoderef(span, actual);
385 let candidate_found = autoderef.any(|(ty, _)| {
386 if let ty::Adt(adt_deref, _) = ty.kind() {
388 .inherent_impls(adt_deref.did)
390 .filter_map(|def_id| {
391 self.associated_item(
403 let has_deref = autoderef.step_count() > 0;
406 && unsatisfied_predicates.is_empty()
408 if let Some((path_string, _)) = ty_str.split_once('<') {
409 ty_str_reported = path_string.to_string();
415 let mut err = struct_span_err!(
419 "no {} named `{}` found for {} `{}` in the current scope",
422 actual.prefix_string(self.tcx),
425 if let Mode::MethodCall = mode {
426 if let SelfSource::MethodCall(call) = source {
427 self.suggest_await_before_method(
428 &mut err, item_name, actual, call, span,
433 tcx.resolutions(()).confused_type_with_std_module.get(&span)
435 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
438 "you are looking for the module in `std`, \
439 not the primitive type",
440 format!("std::{}", snippet),
441 Applicability::MachineApplicable,
445 if let ty::RawPtr(_) = &actual.kind() {
447 "try using `<*const T>::as_ref()` to get a reference to the \
448 type behind the pointer: https://doc.rust-lang.org/std/\
449 primitive.pointer.html#method.as_ref",
452 "using `<*const T>::as_ref()` on a pointer \
453 which is unaligned or points to invalid \
454 or uninitialized memory is undefined behavior",
460 tcx.sess.diagnostic().struct_dummy()
463 if let Some(def) = actual.ty_adt_def() {
464 if let Some(full_sp) = tcx.hir().span_if_local(def.did) {
465 let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
469 "{} `{}` not found {}",
472 if def.is_enum() && !is_method { "here" } else { "for this" }
478 let mut label_span_not_found = || {
479 if unsatisfied_predicates.is_empty() {
480 err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
481 if let ty::Adt(adt, _) = rcvr_ty.kind() {
482 let mut inherent_impls_candidate = self
484 .inherent_impls(adt.did)
489 self.associated_item(*def_id, item_name, Namespace::ValueNS)
491 // Check for both mode is the same so we avoid suggesting
492 // incorrect associated item.
493 match (mode, assoc.fn_has_self_parameter, source) {
494 (Mode::MethodCall, true, SelfSource::MethodCall(_)) => {
495 // We check that the suggest type is actually
496 // different from the received one
497 // So we avoid suggestion method with Box<Self>
499 self.tcx.at(span).type_of(*def_id) != actual
500 && self.tcx.at(span).type_of(*def_id) != rcvr_ty
502 (Mode::Path, false, _) => true,
509 .collect::<Vec<_>>();
510 if !inherent_impls_candidate.is_empty() {
511 inherent_impls_candidate.sort();
512 inherent_impls_candidate.dedup();
514 // number of type to shows at most.
515 let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 };
516 let type_candidates = inherent_impls_candidate
520 format!("- `{}`", self.tcx.at(span).type_of(*impl_item))
524 let additional_types = if inherent_impls_candidate.len() > limit {
526 "\nand {} more types",
527 inherent_impls_candidate.len() - limit
533 "the {item_kind} was found for\n{}{}",
534 type_candidates, additional_types
539 err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
543 // If the method name is the name of a field with a function or closure type,
544 // give a helping note that it has to be called as `(x.f)(...)`.
545 if let SelfSource::MethodCall(expr) = source {
547 self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
548 ty::Adt(def, substs) if !def.is_enum() => {
549 let variant = &def.non_enum_variant();
550 self.tcx.find_field_index(item_name, variant).map(|index| {
551 let field = &variant.fields[index];
552 let field_ty = field.ty(tcx, substs);
559 if let Some((field, field_ty)) = field_receiver {
560 let scope = self.tcx.parent_module(self.body_id).to_def_id();
561 let is_accessible = field.vis.is_accessible_from(scope, self.tcx);
564 if self.is_fn_ty(field_ty, span) {
565 let expr_span = expr.span.to(item_name.span);
566 err.multipart_suggestion(
568 "to call the function stored in `{}`, \
569 surround the field access with parentheses",
573 (expr_span.shrink_to_lo(), '('.to_string()),
574 (expr_span.shrink_to_hi(), ')'.to_string()),
576 Applicability::MachineApplicable,
582 .expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
584 if let Some(span) = call_expr.span.trim_start(item_name.span) {
587 "remove the arguments",
589 Applicability::MaybeIncorrect,
595 let field_kind = if is_accessible { "field" } else { "private field" };
596 err.span_label(item_name.span, format!("{}, not a method", field_kind));
597 } else if lev_candidate.is_none() && static_sources.is_empty() {
598 label_span_not_found();
601 label_span_not_found();
604 if self.is_fn_ty(rcvr_ty, span) {
605 fn report_function<T: std::fmt::Display>(
606 err: &mut DiagnosticBuilder<'_>,
610 &format!("`{}` is a function, perhaps you wish to call it", name,),
614 if let SelfSource::MethodCall(expr) = source {
615 if let Ok(expr_string) = tcx.sess.source_map().span_to_snippet(expr.span) {
616 report_function(&mut err, expr_string);
617 } else if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
618 if let Some(segment) = path.segments.last() {
619 report_function(&mut err, segment.ident);
625 if !static_sources.is_empty() {
627 "found the following associated functions; to be used as methods, \
628 functions must have a `self` parameter",
630 err.span_label(span, "this is an associated function, not a method");
632 if static_sources.len() == 1 {
633 let ty_str = if let Some(CandidateSource::ImplSource(impl_did)) =
634 static_sources.get(0)
636 // When the "method" is resolved through dereferencing, we really want the
637 // original type that has the associated function for accurate suggestions.
639 let ty = tcx.at(span).type_of(*impl_did);
640 match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) {
641 (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
642 // Use `actual` as it will have more `substs` filled in.
643 self.ty_to_value_string(actual.peel_refs())
645 _ => self.ty_to_value_string(ty.peel_refs()),
648 self.ty_to_value_string(actual.peel_refs())
650 if let SelfSource::MethodCall(expr) = source {
653 "use associated function syntax instead",
654 format!("{}::{}", ty_str, item_name),
655 Applicability::MachineApplicable,
658 err.help(&format!("try with `{}::{}`", ty_str, item_name,));
661 report_candidates(span, &mut err, static_sources, sugg_span);
662 } else if static_sources.len() > 1 {
663 report_candidates(span, &mut err, static_sources, sugg_span);
666 let mut restrict_type_params = false;
667 let mut unsatisfied_bounds = false;
668 if !unsatisfied_predicates.is_empty() {
669 let def_span = |def_id| {
670 self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
672 let mut type_params = FxHashMap::default();
673 let mut bound_spans = vec![];
675 let mut collect_type_param_suggestions =
676 |self_ty: Ty<'tcx>, parent_pred: &ty::Predicate<'tcx>, obligation: &str| {
677 // We don't care about regions here, so it's fine to skip the binder here.
678 if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
679 (self_ty.kind(), parent_pred.kind().skip_binder())
681 if let ty::Adt(def, _) = p.trait_ref.self_ty().kind() {
682 let node = def.did.as_local().map(|def_id| {
685 .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
687 if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
688 if let Some(g) = kind.generics() {
689 let key = match g.where_clause.predicates {
690 [.., pred] => (pred.span().shrink_to_hi(), false),
693 .span_for_predicates_or_empty_place(),
699 .or_insert_with(FxHashSet::default)
700 .insert(obligation.to_owned());
706 let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
708 "doesn't satisfy `{}`",
709 if obligation.len() > 50 { quiet } else { obligation }
711 match &self_ty.kind() {
712 // Point at the type that couldn't satisfy the bound.
713 ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)),
714 // Point at the trait object that couldn't satisfy the bound.
715 ty::Dynamic(preds, _) => {
716 for pred in preds.iter() {
717 match pred.skip_binder() {
718 ty::ExistentialPredicate::Trait(tr) => {
719 bound_spans.push((def_span(tr.def_id), msg.clone()))
721 ty::ExistentialPredicate::Projection(_)
722 | ty::ExistentialPredicate::AutoTrait(_) => {}
726 // Point at the closure that couldn't satisfy the bound.
727 ty::Closure(def_id, _) => bound_spans
728 .push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
732 let mut format_pred = |pred: ty::Predicate<'tcx>| {
733 let bound_predicate = pred.kind();
734 match bound_predicate.skip_binder() {
735 ty::PredicateKind::Projection(pred) => {
736 let pred = bound_predicate.rebind(pred);
737 // `<Foo as Iterator>::Item = String`.
738 let projection_ty = pred.skip_binder().projection_ty;
740 let substs_with_infer_self = tcx.mk_substs(
741 iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
742 .chain(projection_ty.substs.iter().skip(1)),
745 let quiet_projection_ty = ty::ProjectionTy {
746 substs: substs_with_infer_self,
747 item_def_id: projection_ty.item_def_id,
750 let ty = pred.skip_binder().ty;
752 let obligation = format!("{} = {}", projection_ty, ty);
753 let quiet = format!("{} = {}", quiet_projection_ty, ty);
755 bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
756 Some((obligation, projection_ty.self_ty()))
758 ty::PredicateKind::Trait(poly_trait_ref) => {
759 let p = poly_trait_ref.trait_ref;
760 let self_ty = p.self_ty();
761 let path = p.print_only_trait_path();
762 let obligation = format!("{}: {}", self_ty, path);
763 let quiet = format!("_: {}", path);
764 bound_span_label(self_ty, &obligation, &quiet);
765 Some((obligation, self_ty))
770 let mut bound_list = unsatisfied_predicates
772 .filter_map(|(pred, parent_pred)| {
773 format_pred(*pred).map(|(p, self_ty)| match parent_pred {
774 None => format!("`{}`", &p),
775 Some(parent_pred) => match format_pred(*parent_pred) {
776 None => format!("`{}`", &p),
777 Some((parent_p, _)) => {
778 collect_type_param_suggestions(self_ty, parent_pred, &p);
779 format!("`{}`\nwhich is required by `{}`", p, parent_p)
785 .collect::<Vec<(usize, String)>>();
786 for ((span, empty_where), obligations) in type_params.into_iter() {
787 restrict_type_params = true;
788 // #74886: Sort here so that the output is always the same.
789 let mut obligations = obligations.into_iter().collect::<Vec<_>>();
791 err.span_suggestion_verbose(
794 "consider restricting the type parameter{s} to satisfy the \
796 s = pluralize!(obligations.len())
800 if empty_where { " where" } else { "," },
801 obligations.join(", ")
803 Applicability::MaybeIncorrect,
807 bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
808 bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677
809 bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order.
812 for (span, msg) in bound_spans.into_iter() {
813 err.span_label(span, &msg);
815 if !bound_list.is_empty() {
816 let bound_list = bound_list
818 .map(|(_, path)| path)
821 let actual_prefix = actual.prefix_string(self.tcx);
822 err.set_primary_message(&format!(
823 "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
826 "the following trait bounds were not satisfied:\n{bound_list}"
828 self.suggest_derive(&mut err, &unsatisfied_predicates);
830 unsatisfied_bounds = true;
834 if actual.is_numeric() && actual.is_fresh() || restrict_type_params {
836 self.suggest_traits_to_import(
843 &unsatisfied_predicates,
848 // Don't emit a suggestion if we found an actual method
849 // that had unsatisfied trait bounds
850 if unsatisfied_predicates.is_empty() && actual.is_enum() {
851 let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
852 if let Some(suggestion) = lev_distance::find_best_match_for_name(
853 &adt_def.variants.iter().map(|s| s.ident.name).collect::<Vec<_>>(),
859 "there is a variant with a similar name",
860 suggestion.to_string(),
861 Applicability::MaybeIncorrect,
866 let mut fallback_span = true;
867 let msg = "remove this method call";
868 if item_name.name == sym::as_str && actual.peel_refs().is_str() {
869 if let SelfSource::MethodCall(expr) = source {
871 self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
872 if let Some(span) = call_expr.span.trim_start(expr.span) {
877 Applicability::MachineApplicable,
879 fallback_span = false;
883 err.span_label(span, msg);
885 } else if let Some(lev_candidate) = lev_candidate {
886 // Don't emit a suggestion if we found an actual method
887 // that had unsatisfied trait bounds
888 if unsatisfied_predicates.is_empty() {
889 let def_kind = lev_candidate.kind.as_def_kind();
893 "there is {} {} with a similar name",
895 def_kind.descr(lev_candidate.def_id),
897 lev_candidate.ident.to_string(),
898 Applicability::MaybeIncorrect,
906 MethodError::Ambiguity(sources) => {
907 let mut err = struct_span_err!(
911 "multiple applicable items in scope"
913 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
915 report_candidates(span, &mut err, sources, sugg_span);
919 MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
920 let kind = kind.descr(def_id);
921 let mut err = struct_span_err!(
925 "{} `{}` is private",
929 err.span_label(item_name.span, &format!("private {}", kind));
933 .span_if_local(def_id)
934 .unwrap_or_else(|| self.tcx.def_span(def_id));
935 err.span_label(sp, &format!("private {} defined here", kind));
936 self.suggest_valid_traits(&mut err, out_of_scope_traits);
940 MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
941 let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
942 let mut err = self.sess().struct_span_err(span, &msg);
943 err.span_label(bound_span, "this has a `Sized` requirement");
944 if !candidates.is_empty() {
946 "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
947 add a `use` for {one_of_them}:",
948 an = if candidates.len() == 1 { "an" } else { "" },
949 s = pluralize!(candidates.len()),
950 were = if candidates.len() == 1 { "was" } else { "were" },
951 one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
953 self.suggest_use_candidates(&mut err, help, candidates);
955 if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
957 let trait_type = self.tcx.mk_ref(
959 ty::TypeAndMut { ty: t_type, mutbl: mutability.invert() },
961 err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
967 MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
972 crate fn note_unmet_impls_on_type(
974 err: &mut rustc_errors::DiagnosticBuilder<'_>,
975 errors: Vec<FulfillmentError<'tcx>>,
977 let all_local_types_needing_impls =
978 errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
979 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
980 ty::Adt(def, _) => def.did.is_local(),
985 let mut preds: Vec<_> = errors
987 .filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
988 ty::PredicateKind::Trait(pred) => Some(pred),
992 preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty()));
995 .filter_map(|pred| match pred.self_ty().kind() {
996 ty::Adt(def, _) => Some(def.did),
999 .collect::<FxHashSet<_>>();
1000 let sm = self.tcx.sess.source_map();
1001 let mut spans: MultiSpan = def_ids
1003 .filter_map(|def_id| {
1004 let span = self.tcx.def_span(*def_id);
1005 if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
1007 .collect::<Vec<_>>()
1010 for pred in &preds {
1011 match pred.self_ty().kind() {
1012 ty::Adt(def, _) => {
1013 spans.push_span_label(
1014 sm.guess_head_span(self.tcx.def_span(def.did)),
1015 format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
1022 if all_local_types_needing_impls && spans.primary_span().is_some() {
1023 let msg = if preds.len() == 1 {
1025 "an implementation of `{}` might be missing for `{}`",
1026 preds[0].trait_ref.print_only_trait_path(),
1031 "the following type{} would have to `impl` {} required trait{} for this \
1032 operation to be valid",
1033 pluralize!(def_ids.len()),
1034 if def_ids.len() == 1 { "its" } else { "their" },
1035 pluralize!(preds.len()),
1038 err.span_note(spans, &msg);
1041 let preds: Vec<_> = errors.iter().map(|e| (e.obligation.predicate, None)).collect();
1042 self.suggest_derive(err, &preds);
1047 err: &mut DiagnosticBuilder<'_>,
1048 unsatisfied_predicates: &Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>,
1050 let mut derives = Vec::<(String, Span, String)>::new();
1051 let mut traits = Vec::<Span>::new();
1052 for (pred, _) in unsatisfied_predicates {
1053 let trait_pred = match pred.kind().skip_binder() {
1054 ty::PredicateKind::Trait(trait_pred) => trait_pred,
1057 let adt = match trait_pred.self_ty().ty_adt_def() {
1058 Some(adt) if adt.did.is_local() => adt,
1061 let can_derive = match self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1062 Some(sym::Default) => !adt.is_enum(),
1077 format!("{}", trait_pred.self_ty()),
1078 self.tcx.def_span(adt.did),
1079 format!("{}", trait_pred.trait_ref.print_only_trait_name()),
1082 traits.push(self.tcx.def_span(trait_pred.def_id()));
1086 let derives_grouped = derives.into_iter().fold(
1087 Vec::<(String, Span, String)>::new(),
1088 |mut acc, (self_name, self_span, trait_name)| {
1089 if let Some((acc_self_name, _, ref mut traits)) = acc.last_mut() {
1090 if acc_self_name == &self_name {
1091 traits.push_str(format!(", {}", trait_name).as_str());
1095 acc.push((self_name, self_span, trait_name));
1102 let len = traits.len();
1104 let span: MultiSpan = traits.into();
1107 &format!("the following trait{} must be implemented", pluralize!(len),),
1111 for (self_name, self_span, traits) in &derives_grouped {
1112 err.span_suggestion_verbose(
1113 self_span.shrink_to_lo(),
1114 &format!("consider annotating `{}` with `#[derive({})]`", self_name, traits),
1115 format!("#[derive({})]\n", traits),
1116 Applicability::MaybeIncorrect,
1121 /// Print out the type for use in value namespace.
1122 fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
1124 ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did, substs)),
1125 _ => self.ty_to_string(ty),
1129 fn suggest_await_before_method(
1131 err: &mut DiagnosticBuilder<'_>,
1134 call: &hir::Expr<'_>,
1137 let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1138 Some(output_ty) => self.resolve_vars_if_possible(output_ty),
1141 let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);
1142 debug!("suggest_await_before_method: is_method_exist={}", method_exists);
1144 err.span_suggestion_verbose(
1145 span.shrink_to_lo(),
1146 "consider `await`ing on the `Future` and calling the method on its `Output`",
1147 "await.".to_string(),
1148 Applicability::MaybeIncorrect,
1153 fn suggest_use_candidates(
1155 err: &mut DiagnosticBuilder<'_>,
1157 candidates: Vec<DefId>,
1159 let module_did = self.tcx.parent_module(self.body_id);
1160 let (span, found_use) = find_use_placement(self.tcx, module_did);
1161 if let Some(span) = span {
1162 let path_strings = candidates.iter().map(|did| {
1163 // Produce an additional newline to separate the new use statement
1164 // from the directly following item.
1165 let additional_newline = if found_use { "" } else { "\n" };
1168 with_crate_prefix(|| self.tcx.def_path_str(*did)),
1173 err.span_suggestions(span, &msg, path_strings, Applicability::MaybeIncorrect);
1175 let limit = if candidates.len() == 5 { 5 } else { 4 };
1176 for (i, trait_did) in candidates.iter().take(limit).enumerate() {
1177 if candidates.len() > 1 {
1178 msg.push_str(&format!(
1179 "\ncandidate #{}: `use {};`",
1181 with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
1184 msg.push_str(&format!(
1186 with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
1190 if candidates.len() > limit {
1191 msg.push_str(&format!("\nand {} others", candidates.len() - limit));
1197 fn suggest_valid_traits(
1199 err: &mut DiagnosticBuilder<'_>,
1200 valid_out_of_scope_traits: Vec<DefId>,
1202 if !valid_out_of_scope_traits.is_empty() {
1203 let mut candidates = valid_out_of_scope_traits;
1207 // `TryFrom` and `FromIterator` have no methods
1208 let edition_fix = candidates
1210 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
1213 err.help("items from traits can only be used if the trait is in scope");
1215 "the following {traits_are} implemented but not in scope; \
1216 perhaps add a `use` for {one_of_them}:",
1217 traits_are = if candidates.len() == 1 { "trait is" } else { "traits are" },
1218 one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
1221 self.suggest_use_candidates(err, msg, candidates);
1222 if let Some(did) = edition_fix {
1224 "'{}' is included in the prelude starting in Edition 2021",
1225 with_crate_prefix(|| self.tcx.def_path_str(did))
1235 fn suggest_traits_to_import(
1237 err: &mut DiagnosticBuilder<'_>,
1241 source: SelfSource<'tcx>,
1242 valid_out_of_scope_traits: Vec<DefId>,
1243 unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
1244 unsatisfied_bounds: bool,
1246 let mut alt_rcvr_sugg = false;
1247 if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
1248 debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
1250 self.tcx.lang_items().clone_trait(),
1251 self.tcx.lang_items().deref_trait(),
1252 self.tcx.lang_items().deref_mut_trait(),
1253 self.tcx.lang_items().drop_trait(),
1255 // Try alternative arbitrary self types that could fulfill this call.
1256 // FIXME: probe for all types that *could* be arbitrary self-types, not
1258 for (rcvr_ty, post) in &[
1260 (self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "),
1261 (self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"),
1263 if let Ok(pick) = self.lookup_probe(
1268 crate::check::method::probe::ProbeScope::AllTraits,
1270 // If the method is defined for the receiver we have, it likely wasn't `use`d.
1271 // We point at the method, but we just skip the rest of the check for arbitrary
1272 // self types and rely on the suggestion to `use` the trait from
1273 // `suggest_valid_traits`.
1274 let did = Some(pick.item.container.id());
1275 let skip = skippable.contains(&did);
1276 if pick.autoderefs == 0 && !skip {
1278 pick.item.ident.span,
1279 &format!("the method is available for `{}` here", rcvr_ty),
1284 for (rcvr_ty, pre) in &[
1285 (self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"),
1286 (self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"),
1287 (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Arc), "Arc::new"),
1288 (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Rc), "Rc::new"),
1290 if let Some(new_rcvr_t) = *rcvr_ty {
1291 if let Ok(pick) = self.lookup_probe(
1296 crate::check::method::probe::ProbeScope::AllTraits,
1298 debug!("try_alt_rcvr: pick candidate {:?}", pick);
1299 let did = Some(pick.item.container.id());
1300 // We don't want to suggest a container type when the missing
1301 // method is `.clone()` or `.deref()` otherwise we'd suggest
1302 // `Arc::new(foo).clone()`, which is far from what the user wants.
1303 let skip = skippable.contains(&did);
1304 // Make sure the method is defined for the *actual* receiver: we don't
1305 // want to treat `Box<Self>` as a receiver if it only works because of
1306 // an autoderef to `&self`
1307 if pick.autoderefs == 0 && !skip {
1309 pick.item.ident.span,
1310 &format!("the method is available for `{}` here", new_rcvr_t),
1312 err.multipart_suggestion(
1313 "consider wrapping the receiver expression with the \
1316 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1317 (rcvr.span.shrink_to_hi(), ")".to_string()),
1319 Applicability::MaybeIncorrect,
1321 // We don't care about the other suggestions.
1322 alt_rcvr_sugg = true;
1329 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1333 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1335 let mut arbitrary_rcvr = vec![];
1336 // There are no traits implemented, so lets suggest some traits to
1337 // implement, by finding ones that have the item name, and are
1338 // legal to implement.
1339 let mut candidates = all_traits(self.tcx)
1341 // Don't issue suggestions for unstable traits since they're
1342 // unlikely to be implementable anyway
1343 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1344 Some(attr) => attr.level.is_stable(),
1348 // We approximate the coherence rules to only suggest
1349 // traits that are legal to implement by requiring that
1350 // either the type or trait is local. Multi-dispatch means
1351 // this isn't perfect (that is, there are cases when
1352 // implementing a trait would be legal but is rejected
1354 unsatisfied_predicates.iter().all(|(p, _)| {
1355 match p.kind().skip_binder() {
1356 // Hide traits if they are present in predicates as they can be fixed without
1357 // having to implement them.
1358 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1359 ty::PredicateKind::Projection(p) => {
1360 p.projection_ty.item_def_id == info.def_id
1364 }) && (type_is_local || info.def_id.is_local())
1366 .associated_item(info.def_id, item_name, Namespace::ValueNS)
1368 if let ty::AssocKind::Fn = item.kind {
1372 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1373 if let Some(hir::Node::TraitItem(hir::TraitItem {
1374 kind: hir::TraitItemKind::Fn(fn_sig, method),
1376 })) = id.map(|id| self.tcx.hir().get(id))
1378 let self_first_arg = match method {
1379 hir::TraitFn::Required([ident, ..]) => {
1380 ident.name == kw::SelfLower
1382 hir::TraitFn::Provided(body_id) => {
1383 self.tcx.hir().body(*body_id).params.first().map_or(
1388 hir::PatKind::Binding(_, _, ident, _)
1389 if ident.name == kw::SelfLower
1397 if !fn_sig.decl.implicit_self.has_implicit_self()
1400 if let Some(ty) = fn_sig.decl.inputs.get(0) {
1401 arbitrary_rcvr.push(ty.span);
1407 // We only want to suggest public or local traits (#45781).
1408 item.vis == ty::Visibility::Public || info.def_id.is_local()
1412 .collect::<Vec<_>>();
1413 for span in &arbitrary_rcvr {
1416 "the method might not be found because of this arbitrary self type",
1423 if !candidates.is_empty() {
1424 // Sort from most relevant to least relevant.
1425 candidates.sort_by(|a, b| a.cmp(b).reverse());
1428 let param_type = match rcvr_ty.kind() {
1429 ty::Param(param) => Some(param),
1430 ty::Ref(_, ty, _) => match ty.kind() {
1431 ty::Param(param) => Some(param),
1436 err.help(if param_type.is_some() {
1437 "items from traits can only be used if the type parameter is bounded by the trait"
1439 "items from traits can only be used if the trait is implemented and in scope"
1441 let candidates_len = candidates.len();
1442 let message = |action| {
1444 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1447 if candidates_len == 1 { "trait defines" } else { "traits define" },
1449 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1453 // Obtain the span for `param` and use it for a structured suggestion.
1454 if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1455 let table_owner = table.borrow().hir_owner;
1456 let generics = self.tcx.generics_of(table_owner.to_def_id());
1457 let type_param = generics.type_param(param, self.tcx);
1458 let hir = &self.tcx.hir();
1459 if let Some(def_id) = type_param.def_id.as_local() {
1460 let id = hir.local_def_id_to_hir_id(def_id);
1461 // Get the `hir::Param` to verify whether it already has any bounds.
1462 // We do this to avoid suggesting code that ends up as `T: FooBar`,
1463 // instead we suggest `T: Foo + Bar` in that case.
1465 Node::GenericParam(param) => {
1466 let mut impl_trait = false;
1468 if let hir::GenericParamKind::Type { synthetic: Some(_), .. } =
1471 // We've found `fn foo(x: impl Trait)` instead of
1472 // `fn foo<T>(x: T)`. We want to suggest the correct
1473 // `fn foo(x: impl Trait + TraitBound)` instead of
1474 // `fn foo<T: TraitBound>(x: T)`. (#63706)
1480 let sp = hir.span(id);
1481 let sp = if let Some(first_bound) = has_bounds {
1482 // `sp` only covers `T`, change it so that it covers
1483 // `T:` when appropriate
1484 sp.until(first_bound.span())
1488 let trait_def_ids: FxHashSet<DefId> = param
1491 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1493 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1494 err.span_suggestions(
1497 "restrict type parameter `{}` with",
1500 candidates.iter().map(|t| {
1504 if impl_trait { " +" } else { ":" },
1505 self.tcx.def_path_str(t.def_id),
1506 if has_bounds.is_some() { " + " } else { "" },
1509 Applicability::MaybeIncorrect,
1514 Node::Item(hir::Item {
1515 kind: hir::ItemKind::Trait(.., bounds, _),
1519 let (sp, sep, article) = if bounds.is_empty() {
1520 (ident.span.shrink_to_hi(), ":", "a")
1522 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1524 err.span_suggestions(
1526 &message(format!("add {} supertrait for", article)),
1527 candidates.iter().map(|t| {
1528 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1530 Applicability::MaybeIncorrect,
1539 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1540 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1541 // cases where a positive bound implies a negative impl.
1542 (candidates, Vec::new())
1543 } else if let Some(simp_rcvr_ty) = simplify_type(self.tcx, rcvr_ty, true) {
1544 let mut potential_candidates = Vec::new();
1545 let mut explicitly_negative = Vec::new();
1546 for candidate in candidates {
1547 // Check if there's a negative impl of `candidate` for `rcvr_ty`
1550 .all_impls(candidate.def_id)
1552 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1555 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1556 let imp_simp = simplify_type(self.tcx, imp.self_ty(), true);
1557 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1560 explicitly_negative.push(candidate);
1562 potential_candidates.push(candidate);
1565 (potential_candidates, explicitly_negative)
1567 // We don't know enough about `recv_ty` to make proper suggestions.
1568 (candidates, Vec::new())
1571 let action = if let Some(param) = param_type {
1572 format!("restrict type parameter `{}` with", param)
1574 // FIXME: it might only need to be imported into scope, not implemented.
1575 "implement".to_string()
1577 match &potential_candidates[..] {
1579 [trait_info] if trait_info.def_id.is_local() => {
1580 let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1582 self.tcx.sess.source_map().guess_head_span(span),
1584 "`{}` defines an item `{}`, perhaps you need to {} it",
1585 self.tcx.def_path_str(trait_info.def_id),
1592 let mut msg = message(action);
1593 for (i, trait_info) in trait_infos.iter().enumerate() {
1594 msg.push_str(&format!(
1595 "\ncandidate #{}: `{}`",
1597 self.tcx.def_path_str(trait_info.def_id),
1603 match &explicitly_negative[..] {
1607 "the trait `{}` defines an item `{}`, but is explicitely unimplemented",
1608 self.tcx.def_path_str(trait_info.def_id),
1614 let mut msg = format!(
1615 "the following traits define an item `{}`, but are explicitely unimplemented:",
1618 for trait_info in trait_infos {
1619 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
1627 /// Checks whether there is a local type somewhere in the chain of
1628 /// autoderefs of `rcvr_ty`.
1629 fn type_derefs_to_local(
1633 source: SelfSource<'tcx>,
1635 fn is_local(ty: Ty<'_>) -> bool {
1637 ty::Adt(def, _) => def.did.is_local(),
1638 ty::Foreign(did) => did.is_local(),
1639 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
1640 ty::Param(_) => true,
1642 // Everything else (primitive types, etc.) is effectively
1643 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
1644 // the noise from these sort of types is usually just really
1645 // annoying, rather than any sort of help).
1650 // This occurs for UFCS desugaring of `T::method`, where there is no
1651 // receiver expression for the method call, and thus no autoderef.
1652 if let SelfSource::QPath(_) = source {
1653 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
1656 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
1660 #[derive(Copy, Clone, Debug)]
1661 pub enum SelfSource<'a> {
1662 QPath(&'a hir::Ty<'a>),
1663 MethodCall(&'a hir::Expr<'a> /* rcvr */),
1666 #[derive(Copy, Clone)]
1667 pub struct TraitInfo {
1671 impl PartialEq for TraitInfo {
1672 fn eq(&self, other: &TraitInfo) -> bool {
1673 self.cmp(other) == Ordering::Equal
1676 impl Eq for TraitInfo {}
1677 impl PartialOrd for TraitInfo {
1678 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
1679 Some(self.cmp(other))
1682 impl Ord for TraitInfo {
1683 fn cmp(&self, other: &TraitInfo) -> Ordering {
1684 // Local crates are more important than remote ones (local:
1685 // `cnum == 0`), and otherwise we throw in the defid for totality.
1687 let lhs = (other.def_id.krate, other.def_id);
1688 let rhs = (self.def_id.krate, self.def_id);
1693 /// Retrieves all traits in this crate and any dependent crates.
1694 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
1695 tcx.all_traits(()).iter().map(|&def_id| TraitInfo { def_id }).collect()
1698 /// Computes all traits in this crate and any dependent crates.
1699 fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
1700 use hir::itemlikevisit;
1702 let mut traits = vec![];
1706 struct Visitor<'a> {
1707 traits: &'a mut Vec<DefId>,
1710 impl<'v, 'a> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a> {
1711 fn visit_item(&mut self, i: &'v hir::Item<'v>) {
1713 hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => {
1714 self.traits.push(i.def_id.to_def_id());
1720 fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
1722 fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
1724 fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
1727 tcx.hir().visit_all_item_likes(&mut Visitor { traits: &mut traits });
1731 let mut external_mods = FxHashSet::default();
1732 fn handle_external_res(
1734 traits: &mut Vec<DefId>,
1735 external_mods: &mut FxHashSet<DefId>,
1739 Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
1740 traits.push(def_id);
1742 Res::Def(DefKind::Mod, def_id) => {
1743 if !external_mods.insert(def_id) {
1746 for child in tcx.item_children(def_id).iter() {
1747 handle_external_res(tcx, traits, external_mods, child.res)
1753 for &cnum in tcx.crates(()).iter() {
1754 let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
1755 handle_external_res(tcx, &mut traits, &mut external_mods, Res::Def(DefKind::Mod, def_id));
1758 tcx.arena.alloc_from_iter(traits)
1761 pub fn provide(providers: &mut ty::query::Providers) {
1762 providers.all_traits = compute_all_traits;
1765 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
1766 let mut span = None;
1767 let mut found_use = false;
1768 let (module, _, _) = tcx.hir().get_module(target_module);
1770 // Find a `use` statement.
1771 for &item_id in module.item_ids {
1772 let item = tcx.hir().item(item_id);
1774 hir::ItemKind::Use(..) => {
1775 // Don't suggest placing a `use` before the prelude
1776 // import or other generated ones.
1777 if !item.span.from_expansion() {
1778 span = Some(item.span.shrink_to_lo());
1783 // Don't place `use` before `extern crate`...
1784 hir::ItemKind::ExternCrate(_) => {}
1785 // ...but do place them before the first other item.
1787 if span.map_or(true, |span| item.span < span) {
1788 if !item.span.from_expansion() {
1789 span = Some(item.span.shrink_to_lo());
1790 // Don't insert between attributes and an item.
1791 let attrs = tcx.hir().attrs(item.hir_id());
1792 // Find the first attribute on the item.
1793 // FIXME: This is broken for active attributes.
1795 if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
1796 span = Some(attr.span.shrink_to_lo());
1808 fn print_disambiguation_help(
1810 args: Option<&'tcx [hir::Expr<'tcx>]>,
1811 err: &mut DiagnosticBuilder<'_>,
1814 kind: ty::AssocKind,
1817 candidate: Option<usize>,
1818 source_map: &source_map::SourceMap,
1819 fn_has_self_parameter: bool,
1821 let mut applicability = Applicability::MachineApplicable;
1822 let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
1825 if rcvr_ty.is_region_ptr() {
1826 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
1831 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
1832 applicability = Applicability::HasPlaceholders;
1835 .collect::<Vec<_>>()
1838 let trait_name = if !fn_has_self_parameter {
1839 format!("<{} as {}>", rcvr_ty, trait_name)
1843 (span, format!("{}::{}{}", trait_name, item_name, args))
1845 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
1847 err.span_suggestion_verbose(
1850 "disambiguate the {} for {}",
1851 kind.as_def_kind().descr(def_id),
1852 if let Some(candidate) = candidate {
1853 format!("candidate #{}", candidate)
1855 "the candidate".to_string()