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(),
1254 self.tcx.get_diagnostic_item(sym::AsRef),
1256 // Try alternative arbitrary self types that could fulfill this call.
1257 // FIXME: probe for all types that *could* be arbitrary self-types, not
1259 for (rcvr_ty, post) in &[
1261 (self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "),
1262 (self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"),
1264 if let Ok(pick) = self.lookup_probe(
1269 crate::check::method::probe::ProbeScope::AllTraits,
1271 // If the method is defined for the receiver we have, it likely wasn't `use`d.
1272 // We point at the method, but we just skip the rest of the check for arbitrary
1273 // self types and rely on the suggestion to `use` the trait from
1274 // `suggest_valid_traits`.
1275 let did = Some(pick.item.container.id());
1276 let skip = skippable.contains(&did);
1277 if pick.autoderefs == 0 && !skip {
1279 pick.item.ident.span,
1280 &format!("the method is available for `{}` here", rcvr_ty),
1285 for (rcvr_ty, pre) in &[
1286 (self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"),
1287 (self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"),
1288 (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Arc), "Arc::new"),
1289 (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Rc), "Rc::new"),
1291 if let Some(new_rcvr_t) = *rcvr_ty {
1292 if let Ok(pick) = self.lookup_probe(
1297 crate::check::method::probe::ProbeScope::AllTraits,
1299 debug!("try_alt_rcvr: pick candidate {:?}", pick);
1300 let did = Some(pick.item.container.id());
1301 // We don't want to suggest a container type when the missing
1302 // method is `.clone()` or `.deref()` otherwise we'd suggest
1303 // `Arc::new(foo).clone()`, which is far from what the user wants.
1304 let skip = skippable.contains(&did);
1305 // Make sure the method is defined for the *actual* receiver: we don't
1306 // want to treat `Box<Self>` as a receiver if it only works because of
1307 // an autoderef to `&self`
1308 if pick.autoderefs == 0 && !skip {
1310 pick.item.ident.span,
1311 &format!("the method is available for `{}` here", new_rcvr_t),
1313 err.multipart_suggestion(
1314 "consider wrapping the receiver expression with the \
1317 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1318 (rcvr.span.shrink_to_hi(), ")".to_string()),
1320 Applicability::MaybeIncorrect,
1322 // We don't care about the other suggestions.
1323 alt_rcvr_sugg = true;
1330 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1334 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1336 let mut arbitrary_rcvr = vec![];
1337 // There are no traits implemented, so lets suggest some traits to
1338 // implement, by finding ones that have the item name, and are
1339 // legal to implement.
1340 let mut candidates = all_traits(self.tcx)
1342 // Don't issue suggestions for unstable traits since they're
1343 // unlikely to be implementable anyway
1344 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1345 Some(attr) => attr.level.is_stable(),
1349 // We approximate the coherence rules to only suggest
1350 // traits that are legal to implement by requiring that
1351 // either the type or trait is local. Multi-dispatch means
1352 // this isn't perfect (that is, there are cases when
1353 // implementing a trait would be legal but is rejected
1355 unsatisfied_predicates.iter().all(|(p, _)| {
1356 match p.kind().skip_binder() {
1357 // Hide traits if they are present in predicates as they can be fixed without
1358 // having to implement them.
1359 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1360 ty::PredicateKind::Projection(p) => {
1361 p.projection_ty.item_def_id == info.def_id
1365 }) && (type_is_local || info.def_id.is_local())
1367 .associated_item(info.def_id, item_name, Namespace::ValueNS)
1369 if let ty::AssocKind::Fn = item.kind {
1373 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1374 if let Some(hir::Node::TraitItem(hir::TraitItem {
1375 kind: hir::TraitItemKind::Fn(fn_sig, method),
1377 })) = id.map(|id| self.tcx.hir().get(id))
1379 let self_first_arg = match method {
1380 hir::TraitFn::Required([ident, ..]) => {
1381 ident.name == kw::SelfLower
1383 hir::TraitFn::Provided(body_id) => {
1384 self.tcx.hir().body(*body_id).params.first().map_or(
1389 hir::PatKind::Binding(_, _, ident, _)
1390 if ident.name == kw::SelfLower
1398 if !fn_sig.decl.implicit_self.has_implicit_self()
1401 if let Some(ty) = fn_sig.decl.inputs.get(0) {
1402 arbitrary_rcvr.push(ty.span);
1408 // We only want to suggest public or local traits (#45781).
1409 item.vis == ty::Visibility::Public || info.def_id.is_local()
1413 .collect::<Vec<_>>();
1414 for span in &arbitrary_rcvr {
1417 "the method might not be found because of this arbitrary self type",
1424 if !candidates.is_empty() {
1425 // Sort from most relevant to least relevant.
1426 candidates.sort_by(|a, b| a.cmp(b).reverse());
1429 let param_type = match rcvr_ty.kind() {
1430 ty::Param(param) => Some(param),
1431 ty::Ref(_, ty, _) => match ty.kind() {
1432 ty::Param(param) => Some(param),
1437 err.help(if param_type.is_some() {
1438 "items from traits can only be used if the type parameter is bounded by the trait"
1440 "items from traits can only be used if the trait is implemented and in scope"
1442 let candidates_len = candidates.len();
1443 let message = |action| {
1445 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1448 if candidates_len == 1 { "trait defines" } else { "traits define" },
1450 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1454 // Obtain the span for `param` and use it for a structured suggestion.
1455 if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1456 let table_owner = table.borrow().hir_owner;
1457 let generics = self.tcx.generics_of(table_owner.to_def_id());
1458 let type_param = generics.type_param(param, self.tcx);
1459 let hir = &self.tcx.hir();
1460 if let Some(def_id) = type_param.def_id.as_local() {
1461 let id = hir.local_def_id_to_hir_id(def_id);
1462 // Get the `hir::Param` to verify whether it already has any bounds.
1463 // We do this to avoid suggesting code that ends up as `T: FooBar`,
1464 // instead we suggest `T: Foo + Bar` in that case.
1466 Node::GenericParam(param) => {
1467 let mut impl_trait = false;
1469 if let hir::GenericParamKind::Type { synthetic: Some(_), .. } =
1472 // We've found `fn foo(x: impl Trait)` instead of
1473 // `fn foo<T>(x: T)`. We want to suggest the correct
1474 // `fn foo(x: impl Trait + TraitBound)` instead of
1475 // `fn foo<T: TraitBound>(x: T)`. (#63706)
1481 let sp = hir.span(id);
1482 let sp = if let Some(first_bound) = has_bounds {
1483 // `sp` only covers `T`, change it so that it covers
1484 // `T:` when appropriate
1485 sp.until(first_bound.span())
1489 let trait_def_ids: FxHashSet<DefId> = param
1492 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1494 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1495 err.span_suggestions(
1498 "restrict type parameter `{}` with",
1501 candidates.iter().map(|t| {
1505 if impl_trait { " +" } else { ":" },
1506 self.tcx.def_path_str(t.def_id),
1507 if has_bounds.is_some() { " + " } else { "" },
1510 Applicability::MaybeIncorrect,
1515 Node::Item(hir::Item {
1516 kind: hir::ItemKind::Trait(.., bounds, _),
1520 let (sp, sep, article) = if bounds.is_empty() {
1521 (ident.span.shrink_to_hi(), ":", "a")
1523 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1525 err.span_suggestions(
1527 &message(format!("add {} supertrait for", article)),
1528 candidates.iter().map(|t| {
1529 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1531 Applicability::MaybeIncorrect,
1540 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1541 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1542 // cases where a positive bound implies a negative impl.
1543 (candidates, Vec::new())
1544 } else if let Some(simp_rcvr_ty) = simplify_type(self.tcx, rcvr_ty, true) {
1545 let mut potential_candidates = Vec::new();
1546 let mut explicitly_negative = Vec::new();
1547 for candidate in candidates {
1548 // Check if there's a negative impl of `candidate` for `rcvr_ty`
1551 .all_impls(candidate.def_id)
1553 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1556 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1557 let imp_simp = simplify_type(self.tcx, imp.self_ty(), true);
1558 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1561 explicitly_negative.push(candidate);
1563 potential_candidates.push(candidate);
1566 (potential_candidates, explicitly_negative)
1568 // We don't know enough about `recv_ty` to make proper suggestions.
1569 (candidates, Vec::new())
1572 let action = if let Some(param) = param_type {
1573 format!("restrict type parameter `{}` with", param)
1575 // FIXME: it might only need to be imported into scope, not implemented.
1576 "implement".to_string()
1578 match &potential_candidates[..] {
1580 [trait_info] if trait_info.def_id.is_local() => {
1581 let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1583 self.tcx.sess.source_map().guess_head_span(span),
1585 "`{}` defines an item `{}`, perhaps you need to {} it",
1586 self.tcx.def_path_str(trait_info.def_id),
1593 let mut msg = message(action);
1594 for (i, trait_info) in trait_infos.iter().enumerate() {
1595 msg.push_str(&format!(
1596 "\ncandidate #{}: `{}`",
1598 self.tcx.def_path_str(trait_info.def_id),
1604 match &explicitly_negative[..] {
1608 "the trait `{}` defines an item `{}`, but is explicitely unimplemented",
1609 self.tcx.def_path_str(trait_info.def_id),
1615 let mut msg = format!(
1616 "the following traits define an item `{}`, but are explicitely unimplemented:",
1619 for trait_info in trait_infos {
1620 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
1628 /// Checks whether there is a local type somewhere in the chain of
1629 /// autoderefs of `rcvr_ty`.
1630 fn type_derefs_to_local(
1634 source: SelfSource<'tcx>,
1636 fn is_local(ty: Ty<'_>) -> bool {
1638 ty::Adt(def, _) => def.did.is_local(),
1639 ty::Foreign(did) => did.is_local(),
1640 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
1641 ty::Param(_) => true,
1643 // Everything else (primitive types, etc.) is effectively
1644 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
1645 // the noise from these sort of types is usually just really
1646 // annoying, rather than any sort of help).
1651 // This occurs for UFCS desugaring of `T::method`, where there is no
1652 // receiver expression for the method call, and thus no autoderef.
1653 if let SelfSource::QPath(_) = source {
1654 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
1657 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
1661 #[derive(Copy, Clone, Debug)]
1662 pub enum SelfSource<'a> {
1663 QPath(&'a hir::Ty<'a>),
1664 MethodCall(&'a hir::Expr<'a> /* rcvr */),
1667 #[derive(Copy, Clone)]
1668 pub struct TraitInfo {
1672 impl PartialEq for TraitInfo {
1673 fn eq(&self, other: &TraitInfo) -> bool {
1674 self.cmp(other) == Ordering::Equal
1677 impl Eq for TraitInfo {}
1678 impl PartialOrd for TraitInfo {
1679 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
1680 Some(self.cmp(other))
1683 impl Ord for TraitInfo {
1684 fn cmp(&self, other: &TraitInfo) -> Ordering {
1685 // Local crates are more important than remote ones (local:
1686 // `cnum == 0`), and otherwise we throw in the defid for totality.
1688 let lhs = (other.def_id.krate, other.def_id);
1689 let rhs = (self.def_id.krate, self.def_id);
1694 /// Retrieves all traits in this crate and any dependent crates.
1695 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
1696 tcx.all_traits(()).iter().map(|&def_id| TraitInfo { def_id }).collect()
1699 /// Computes all traits in this crate and any dependent crates.
1700 fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
1701 use hir::itemlikevisit;
1703 let mut traits = vec![];
1707 struct Visitor<'a> {
1708 traits: &'a mut Vec<DefId>,
1711 impl<'v, 'a> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a> {
1712 fn visit_item(&mut self, i: &'v hir::Item<'v>) {
1714 hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => {
1715 self.traits.push(i.def_id.to_def_id());
1721 fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
1723 fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
1725 fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
1728 tcx.hir().visit_all_item_likes(&mut Visitor { traits: &mut traits });
1732 let mut external_mods = FxHashSet::default();
1733 fn handle_external_res(
1735 traits: &mut Vec<DefId>,
1736 external_mods: &mut FxHashSet<DefId>,
1740 Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
1741 traits.push(def_id);
1743 Res::Def(DefKind::Mod, def_id) => {
1744 if !external_mods.insert(def_id) {
1747 for child in tcx.item_children(def_id).iter() {
1748 handle_external_res(tcx, traits, external_mods, child.res)
1754 for &cnum in tcx.crates(()).iter() {
1755 let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
1756 handle_external_res(tcx, &mut traits, &mut external_mods, Res::Def(DefKind::Mod, def_id));
1759 tcx.arena.alloc_from_iter(traits)
1762 pub fn provide(providers: &mut ty::query::Providers) {
1763 providers.all_traits = compute_all_traits;
1766 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
1767 let mut span = None;
1768 let mut found_use = false;
1769 let (module, _, _) = tcx.hir().get_module(target_module);
1771 // Find a `use` statement.
1772 for &item_id in module.item_ids {
1773 let item = tcx.hir().item(item_id);
1775 hir::ItemKind::Use(..) => {
1776 // Don't suggest placing a `use` before the prelude
1777 // import or other generated ones.
1778 if !item.span.from_expansion() {
1779 span = Some(item.span.shrink_to_lo());
1784 // Don't place `use` before `extern crate`...
1785 hir::ItemKind::ExternCrate(_) => {}
1786 // ...but do place them before the first other item.
1788 if span.map_or(true, |span| item.span < span) {
1789 if !item.span.from_expansion() {
1790 span = Some(item.span.shrink_to_lo());
1791 // Don't insert between attributes and an item.
1792 let attrs = tcx.hir().attrs(item.hir_id());
1793 // Find the first attribute on the item.
1794 // FIXME: This is broken for active attributes.
1796 if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
1797 span = Some(attr.span.shrink_to_lo());
1809 fn print_disambiguation_help(
1811 args: Option<&'tcx [hir::Expr<'tcx>]>,
1812 err: &mut DiagnosticBuilder<'_>,
1815 kind: ty::AssocKind,
1818 candidate: Option<usize>,
1819 source_map: &source_map::SourceMap,
1820 fn_has_self_parameter: bool,
1822 let mut applicability = Applicability::MachineApplicable;
1823 let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
1826 if rcvr_ty.is_region_ptr() {
1827 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
1832 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
1833 applicability = Applicability::HasPlaceholders;
1836 .collect::<Vec<_>>()
1839 let trait_name = if !fn_has_self_parameter {
1840 format!("<{} as {}>", rcvr_ty, trait_name)
1844 (span, format!("{}::{}{}", trait_name, item_name, args))
1846 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
1848 err.span_suggestion_verbose(
1851 "disambiguate the {} for {}",
1852 kind.as_def_kind().descr(def_id),
1853 if let Some(candidate) = candidate {
1854 format!("candidate #{}", candidate)
1856 "the candidate".to_string()