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, Symbol};
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 // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
1305 // implement the `AsRef` trait.
1306 let skip = skippable.contains(&did)
1307 || (("Pin::new" == *pre)
1308 && (Symbol::intern("as_ref") == item_name.name));
1309 // Make sure the method is defined for the *actual* receiver: we don't
1310 // want to treat `Box<Self>` as a receiver if it only works because of
1311 // an autoderef to `&self`
1312 if pick.autoderefs == 0 && !skip {
1314 pick.item.ident.span,
1315 &format!("the method is available for `{}` here", new_rcvr_t),
1317 err.multipart_suggestion(
1318 "consider wrapping the receiver expression with the \
1321 (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)),
1322 (rcvr.span.shrink_to_hi(), ")".to_string()),
1324 Applicability::MaybeIncorrect,
1326 // We don't care about the other suggestions.
1327 alt_rcvr_sugg = true;
1334 if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
1338 let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);
1340 let mut arbitrary_rcvr = vec![];
1341 // There are no traits implemented, so lets suggest some traits to
1342 // implement, by finding ones that have the item name, and are
1343 // legal to implement.
1344 let mut candidates = all_traits(self.tcx)
1346 // Don't issue suggestions for unstable traits since they're
1347 // unlikely to be implementable anyway
1348 .filter(|info| match self.tcx.lookup_stability(info.def_id) {
1349 Some(attr) => attr.level.is_stable(),
1353 // We approximate the coherence rules to only suggest
1354 // traits that are legal to implement by requiring that
1355 // either the type or trait is local. Multi-dispatch means
1356 // this isn't perfect (that is, there are cases when
1357 // implementing a trait would be legal but is rejected
1359 unsatisfied_predicates.iter().all(|(p, _)| {
1360 match p.kind().skip_binder() {
1361 // Hide traits if they are present in predicates as they can be fixed without
1362 // having to implement them.
1363 ty::PredicateKind::Trait(t) => t.def_id() == info.def_id,
1364 ty::PredicateKind::Projection(p) => {
1365 p.projection_ty.item_def_id == info.def_id
1369 }) && (type_is_local || info.def_id.is_local())
1371 .associated_item(info.def_id, item_name, Namespace::ValueNS)
1373 if let ty::AssocKind::Fn = item.kind {
1377 .map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id));
1378 if let Some(hir::Node::TraitItem(hir::TraitItem {
1379 kind: hir::TraitItemKind::Fn(fn_sig, method),
1381 })) = id.map(|id| self.tcx.hir().get(id))
1383 let self_first_arg = match method {
1384 hir::TraitFn::Required([ident, ..]) => {
1385 ident.name == kw::SelfLower
1387 hir::TraitFn::Provided(body_id) => {
1388 self.tcx.hir().body(*body_id).params.first().map_or(
1393 hir::PatKind::Binding(_, _, ident, _)
1394 if ident.name == kw::SelfLower
1402 if !fn_sig.decl.implicit_self.has_implicit_self()
1405 if let Some(ty) = fn_sig.decl.inputs.get(0) {
1406 arbitrary_rcvr.push(ty.span);
1412 // We only want to suggest public or local traits (#45781).
1413 item.vis.is_public() || info.def_id.is_local()
1417 .collect::<Vec<_>>();
1418 for span in &arbitrary_rcvr {
1421 "the method might not be found because of this arbitrary self type",
1428 if !candidates.is_empty() {
1429 // Sort from most relevant to least relevant.
1430 candidates.sort_by(|a, b| a.cmp(b).reverse());
1433 let param_type = match rcvr_ty.kind() {
1434 ty::Param(param) => Some(param),
1435 ty::Ref(_, ty, _) => match ty.kind() {
1436 ty::Param(param) => Some(param),
1441 err.help(if param_type.is_some() {
1442 "items from traits can only be used if the type parameter is bounded by the trait"
1444 "items from traits can only be used if the trait is implemented and in scope"
1446 let candidates_len = candidates.len();
1447 let message = |action| {
1449 "the following {traits_define} an item `{name}`, perhaps you need to {action} \
1452 if candidates_len == 1 { "trait defines" } else { "traits define" },
1454 one_of_them = if candidates_len == 1 { "it" } else { "one of them" },
1458 // Obtain the span for `param` and use it for a structured suggestion.
1459 if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
1460 let table_owner = table.borrow().hir_owner;
1461 let generics = self.tcx.generics_of(table_owner.to_def_id());
1462 let type_param = generics.type_param(param, self.tcx);
1463 let hir = &self.tcx.hir();
1464 if let Some(def_id) = type_param.def_id.as_local() {
1465 let id = hir.local_def_id_to_hir_id(def_id);
1466 // Get the `hir::Param` to verify whether it already has any bounds.
1467 // We do this to avoid suggesting code that ends up as `T: FooBar`,
1468 // instead we suggest `T: Foo + Bar` in that case.
1470 Node::GenericParam(param) => {
1471 let mut impl_trait = false;
1473 if let hir::GenericParamKind::Type { synthetic: Some(_), .. } =
1476 // We've found `fn foo(x: impl Trait)` instead of
1477 // `fn foo<T>(x: T)`. We want to suggest the correct
1478 // `fn foo(x: impl Trait + TraitBound)` instead of
1479 // `fn foo<T: TraitBound>(x: T)`. (#63706)
1485 let sp = hir.span(id);
1486 let sp = if let Some(first_bound) = has_bounds {
1487 // `sp` only covers `T`, change it so that it covers
1488 // `T:` when appropriate
1489 sp.until(first_bound.span())
1493 let trait_def_ids: FxHashSet<DefId> = param
1496 .filter_map(|bound| bound.trait_ref()?.trait_def_id())
1498 if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
1499 err.span_suggestions(
1502 "restrict type parameter `{}` with",
1505 candidates.iter().map(|t| {
1509 if impl_trait { " +" } else { ":" },
1510 self.tcx.def_path_str(t.def_id),
1511 if has_bounds.is_some() { " + " } else { "" },
1514 Applicability::MaybeIncorrect,
1519 Node::Item(hir::Item {
1520 kind: hir::ItemKind::Trait(.., bounds, _),
1524 let (sp, sep, article) = if bounds.is_empty() {
1525 (ident.span.shrink_to_hi(), ":", "a")
1527 (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
1529 err.span_suggestions(
1531 &message(format!("add {} supertrait for", article)),
1532 candidates.iter().map(|t| {
1533 format!("{} {}", sep, self.tcx.def_path_str(t.def_id),)
1535 Applicability::MaybeIncorrect,
1544 let (potential_candidates, explicitly_negative) = if param_type.is_some() {
1545 // FIXME: Even though negative bounds are not implemented, we could maybe handle
1546 // cases where a positive bound implies a negative impl.
1547 (candidates, Vec::new())
1548 } else if let Some(simp_rcvr_ty) = simplify_type(self.tcx, rcvr_ty, true) {
1549 let mut potential_candidates = Vec::new();
1550 let mut explicitly_negative = Vec::new();
1551 for candidate in candidates {
1552 // Check if there's a negative impl of `candidate` for `rcvr_ty`
1555 .all_impls(candidate.def_id)
1557 self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
1560 let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
1561 let imp_simp = simplify_type(self.tcx, imp.self_ty(), true);
1562 imp_simp.map_or(false, |s| s == simp_rcvr_ty)
1565 explicitly_negative.push(candidate);
1567 potential_candidates.push(candidate);
1570 (potential_candidates, explicitly_negative)
1572 // We don't know enough about `recv_ty` to make proper suggestions.
1573 (candidates, Vec::new())
1576 let action = if let Some(param) = param_type {
1577 format!("restrict type parameter `{}` with", param)
1579 // FIXME: it might only need to be imported into scope, not implemented.
1580 "implement".to_string()
1582 match &potential_candidates[..] {
1584 [trait_info] if trait_info.def_id.is_local() => {
1585 let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
1587 self.tcx.sess.source_map().guess_head_span(span),
1589 "`{}` defines an item `{}`, perhaps you need to {} it",
1590 self.tcx.def_path_str(trait_info.def_id),
1597 let mut msg = message(action);
1598 for (i, trait_info) in trait_infos.iter().enumerate() {
1599 msg.push_str(&format!(
1600 "\ncandidate #{}: `{}`",
1602 self.tcx.def_path_str(trait_info.def_id),
1608 match &explicitly_negative[..] {
1612 "the trait `{}` defines an item `{}`, but is explicitely unimplemented",
1613 self.tcx.def_path_str(trait_info.def_id),
1619 let mut msg = format!(
1620 "the following traits define an item `{}`, but are explicitely unimplemented:",
1623 for trait_info in trait_infos {
1624 msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id)));
1632 /// Checks whether there is a local type somewhere in the chain of
1633 /// autoderefs of `rcvr_ty`.
1634 fn type_derefs_to_local(
1638 source: SelfSource<'tcx>,
1640 fn is_local(ty: Ty<'_>) -> bool {
1642 ty::Adt(def, _) => def.did.is_local(),
1643 ty::Foreign(did) => did.is_local(),
1644 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
1645 ty::Param(_) => true,
1647 // Everything else (primitive types, etc.) is effectively
1648 // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
1649 // the noise from these sort of types is usually just really
1650 // annoying, rather than any sort of help).
1655 // This occurs for UFCS desugaring of `T::method`, where there is no
1656 // receiver expression for the method call, and thus no autoderef.
1657 if let SelfSource::QPath(_) = source {
1658 return is_local(self.resolve_vars_with_obligations(rcvr_ty));
1661 self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
1665 #[derive(Copy, Clone, Debug)]
1666 pub enum SelfSource<'a> {
1667 QPath(&'a hir::Ty<'a>),
1668 MethodCall(&'a hir::Expr<'a> /* rcvr */),
1671 #[derive(Copy, Clone)]
1672 pub struct TraitInfo {
1676 impl PartialEq for TraitInfo {
1677 fn eq(&self, other: &TraitInfo) -> bool {
1678 self.cmp(other) == Ordering::Equal
1681 impl Eq for TraitInfo {}
1682 impl PartialOrd for TraitInfo {
1683 fn partial_cmp(&self, other: &TraitInfo) -> Option<Ordering> {
1684 Some(self.cmp(other))
1687 impl Ord for TraitInfo {
1688 fn cmp(&self, other: &TraitInfo) -> Ordering {
1689 // Local crates are more important than remote ones (local:
1690 // `cnum == 0`), and otherwise we throw in the defid for totality.
1692 let lhs = (other.def_id.krate, other.def_id);
1693 let rhs = (self.def_id.krate, self.def_id);
1698 /// Retrieves all traits in this crate and any dependent crates.
1699 pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
1700 tcx.all_traits(()).iter().map(|&def_id| TraitInfo { def_id }).collect()
1703 /// Computes all traits in this crate and any dependent crates.
1704 fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
1705 use hir::itemlikevisit;
1707 let mut traits = vec![];
1711 struct Visitor<'a> {
1712 traits: &'a mut Vec<DefId>,
1715 impl<'v, 'a> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a> {
1716 fn visit_item(&mut self, i: &'v hir::Item<'v>) {
1718 hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => {
1719 self.traits.push(i.def_id.to_def_id());
1725 fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
1727 fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
1729 fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
1732 tcx.hir().visit_all_item_likes(&mut Visitor { traits: &mut traits });
1736 let mut external_mods = FxHashSet::default();
1737 fn handle_external_res(
1739 traits: &mut Vec<DefId>,
1740 external_mods: &mut FxHashSet<DefId>,
1744 Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
1745 traits.push(def_id);
1747 Res::Def(DefKind::Mod, def_id) => {
1748 if !external_mods.insert(def_id) {
1751 for child in tcx.item_children(def_id).iter() {
1752 handle_external_res(tcx, traits, external_mods, child.res)
1758 for &cnum in tcx.crates(()).iter() {
1759 let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
1760 handle_external_res(tcx, &mut traits, &mut external_mods, Res::Def(DefKind::Mod, def_id));
1763 tcx.arena.alloc_from_iter(traits)
1766 pub fn provide(providers: &mut ty::query::Providers) {
1767 providers.all_traits = compute_all_traits;
1770 fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
1771 let mut span = None;
1772 let mut found_use = false;
1773 let (module, _, _) = tcx.hir().get_module(target_module);
1775 // Find a `use` statement.
1776 for &item_id in module.item_ids {
1777 let item = tcx.hir().item(item_id);
1779 hir::ItemKind::Use(..) => {
1780 // Don't suggest placing a `use` before the prelude
1781 // import or other generated ones.
1782 if !item.span.from_expansion() {
1783 span = Some(item.span.shrink_to_lo());
1788 // Don't place `use` before `extern crate`...
1789 hir::ItemKind::ExternCrate(_) => {}
1790 // ...but do place them before the first other item.
1792 if span.map_or(true, |span| item.span < span) {
1793 if !item.span.from_expansion() {
1794 span = Some(item.span.shrink_to_lo());
1795 // Don't insert between attributes and an item.
1796 let attrs = tcx.hir().attrs(item.hir_id());
1797 // Find the first attribute on the item.
1798 // FIXME: This is broken for active attributes.
1800 if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
1801 span = Some(attr.span.shrink_to_lo());
1813 fn print_disambiguation_help(
1815 args: Option<&'tcx [hir::Expr<'tcx>]>,
1816 err: &mut DiagnosticBuilder<'_>,
1819 kind: ty::AssocKind,
1822 candidate: Option<usize>,
1823 source_map: &source_map::SourceMap,
1824 fn_has_self_parameter: bool,
1826 let mut applicability = Applicability::MachineApplicable;
1827 let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
1830 if rcvr_ty.is_region_ptr() {
1831 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
1836 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
1837 applicability = Applicability::HasPlaceholders;
1840 .collect::<Vec<_>>()
1843 let trait_name = if !fn_has_self_parameter {
1844 format!("<{} as {}>", rcvr_ty, trait_name)
1848 (span, format!("{}::{}{}", trait_name, item_name, args))
1850 (span.with_hi(item_name.span.lo()), format!("<{} as {}>::", rcvr_ty, trait_name))
1852 err.span_suggestion_verbose(
1855 "disambiguate the {} for {}",
1856 kind.as_def_kind().descr(def_id),
1857 if let Some(candidate) = candidate {
1858 format!("candidate #{}", candidate)
1860 "the candidate".to_string()