@@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248
248
249
249
match error {
250
250
MethodError::NoMatch(NoMatchData {
251
- static_candidates: mut static_sources ,
251
+ mut static_candidates ,
252
252
unsatisfied_predicates,
253
253
out_of_scope_traits,
254
254
lev_candidate,
@@ -288,9 +288,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
288
288
if generics.len() > 0 {
289
289
let mut autoderef = self.autoderef(span, actual);
290
290
let candidate_found = autoderef.any(|(ty, _)| {
291
- if let ty::Adt(adt_deref , _) = ty.kind() {
291
+ if let ty::Adt(adt_def , _) = ty.kind() {
292
292
self.tcx
293
- .inherent_impls(adt_deref .did())
293
+ .inherent_impls(adt_def .did())
294
294
.iter()
295
295
.filter_map(|def_id| self.associated_value(*def_id, item_name))
296
296
.count()
@@ -348,15 +348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348
348
}
349
349
350
350
let ty_span = match actual.kind() {
351
- ty::Param(param_type) => {
352
- let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
353
- let type_param = generics.type_param(param_type, self.tcx);
354
- Some(self.tcx.def_span(type_param.def_id))
355
- }
351
+ ty::Param(param_type) => Some(
352
+ param_type.span_from_generics(self.tcx, self.body_id.owner.to_def_id()),
353
+ ),
356
354
ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
357
355
_ => None,
358
356
};
359
-
360
357
if let Some(span) = ty_span {
361
358
err.span_label(
362
359
span,
@@ -386,17 +383,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386
383
387
384
let mut custom_span_label = false;
388
385
389
- if !static_sources .is_empty() {
386
+ if !static_candidates .is_empty() {
390
387
err.note(
391
388
"found the following associated functions; to be used as methods, \
392
389
functions must have a `self` parameter",
393
390
);
394
391
err.span_label(span, "this is an associated function, not a method");
395
392
custom_span_label = true;
396
393
}
397
- if static_sources .len() == 1 {
394
+ if static_candidates .len() == 1 {
398
395
let ty_str =
399
- if let Some(CandidateSource::Impl(impl_did)) = static_sources .get(0) {
396
+ if let Some(CandidateSource::Impl(impl_did)) = static_candidates .get(0) {
400
397
// When the "method" is resolved through dereferencing, we really want the
401
398
// original type that has the associated function for accurate suggestions.
402
399
// (#61411)
@@ -422,9 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
422
419
err.help(&format!("try with `{}::{}`", ty_str, item_name,));
423
420
}
424
421
425
- report_candidates(span, &mut err, &mut static_sources , sugg_span);
426
- } else if static_sources .len() > 1 {
427
- report_candidates(span, &mut err, &mut static_sources , sugg_span);
422
+ report_candidates(span, &mut err, &mut static_candidates , sugg_span);
423
+ } else if static_candidates .len() > 1 {
424
+ report_candidates(span, &mut err, &mut static_candidates , sugg_span);
428
425
}
429
426
430
427
let mut bound_spans = vec![];
@@ -496,24 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496
493
if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
497
494
(self_ty.kind(), parent_pred.kind().skip_binder())
498
495
{
496
+ let hir = self.tcx.hir();
499
497
let node = match p.trait_ref.self_ty().kind() {
500
498
ty::Param(_) => {
501
499
// Account for `fn` items like in `issue-35677.rs` to
502
500
// suggest restricting its type params.
503
- let did = self.tcx.hir().body_owner_def_id(hir::BodyId {
504
- hir_id: self.body_id,
505
- });
506
- Some(
507
- self.tcx
508
- .hir()
509
- .get(self.tcx.hir().local_def_id_to_hir_id(did)),
510
- )
501
+ let parent_body =
502
+ hir.body_owner(hir::BodyId { hir_id: self.body_id });
503
+ Some(hir.get(parent_body))
504
+ }
505
+ ty::Adt(def, _) => {
506
+ def.did().as_local().map(|def_id| hir.get_by_def_id(def_id))
511
507
}
512
- ty::Adt(def, _) => def.did().as_local().map(|def_id| {
513
- self.tcx
514
- .hir()
515
- .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
516
- }),
517
508
_ => None,
518
509
};
519
510
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
@@ -605,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605
596
.iter()
606
597
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
607
598
.filter_map(|(p, parent, c)| match c.code() {
608
- ObligationCauseCode::ImplDerivedObligation(ref data) => {
599
+ ObligationCauseCode::ImplDerivedObligation(data) => {
609
600
Some((&data.derived, p, parent, data.impl_def_id, data))
610
601
}
611
602
_ => None,
@@ -620,22 +611,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
620
611
match self.tcx.hir().get_if_local(impl_def_id) {
621
612
// Unmet obligation comes from a `derive` macro, point at it once to
622
613
// avoid multiple span labels pointing at the same place.
623
- Some(Node::Item(hir::Item {
624
- kind: hir::ItemKind::Trait(..),
625
- ident,
626
- ..
627
- })) if matches!(
628
- ident.span.ctxt().outer_expn_data().kind,
629
- ExpnKind::Macro(MacroKind::Derive, _)
630
- ) =>
631
- {
632
- let span = ident.span.ctxt().outer_expn_data().call_site;
633
- let mut spans: MultiSpan = span.into();
634
- spans.push_span_label(span, derive_msg);
635
- let entry = spanned_predicates.entry(spans);
636
- entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
637
- }
638
-
639
614
Some(Node::Item(hir::Item {
640
615
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
641
616
..
@@ -659,34 +634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659
634
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
660
635
}
661
636
662
- // Unmet obligation coming from a `trait`.
663
- Some(Node::Item(hir::Item {
664
- kind: hir::ItemKind::Trait(..),
665
- ident,
666
- span: item_span,
667
- ..
668
- })) if !matches!(
669
- ident.span.ctxt().outer_expn_data().kind,
670
- ExpnKind::Macro(MacroKind::Derive, _)
671
- ) =>
672
- {
673
- if let Some(pred) = parent_p {
674
- // Done to add the "doesn't satisfy" `span_label`.
675
- let _ = format_pred(*pred);
676
- }
677
- skip_list.insert(p);
678
- let mut spans = if cause.span != *item_span {
679
- let mut spans: MultiSpan = cause.span.into();
680
- spans.push_span_label(cause.span, unsatisfied_msg);
681
- spans
682
- } else {
683
- ident.span.into()
684
- };
685
- spans.push_span_label(ident.span, "in this trait");
686
- let entry = spanned_predicates.entry(spans);
687
- entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
688
- }
689
-
690
637
// Unmet obligation coming from an `impl`.
691
638
Some(Node::Item(hir::Item {
692
639
kind:
@@ -695,19 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695
642
}),
696
643
span: item_span,
697
644
..
698
- })) if !matches!(
699
- self_ty.span.ctxt().outer_expn_data().kind,
700
- ExpnKind::Macro(MacroKind::Derive, _)
701
- ) && !matches!(
702
- of_trait.as_ref().map(|t| t
703
- .path
704
- .span
705
- .ctxt()
706
- .outer_expn_data()
707
- .kind),
708
- Some(ExpnKind::Macro(MacroKind::Derive, _))
709
- ) =>
710
- {
645
+ })) => {
711
646
let sized_pred =
712
647
unsatisfied_predicates.iter().any(|(pred, _, _)| {
713
648
match pred.kind().skip_binder() {
@@ -759,7 +694,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
759
694
let entry = spanned_predicates.entry(spans);
760
695
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
761
696
}
762
- _ => {}
697
+ Some(_) => unreachable!(),
698
+ None => (),
763
699
}
764
700
}
765
701
let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
@@ -863,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
863
799
.on_unimplemented_note(trait_ref, &obligation);
864
800
(message, label)
865
801
})
866
- .unwrap_or((None, None) )
802
+ .unwrap( )
867
803
} else {
868
804
(None, None)
869
805
};
@@ -972,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972
908
// If the method name is the name of a field with a function or closure type,
973
909
// give a helping note that it has to be called as `(x.f)(...)`.
974
910
if let SelfSource::MethodCall(expr) = source {
975
- if !self.suggest_field_call (span, rcvr_ty, expr, item_name, &mut err)
911
+ if !self.suggest_calling_field_as_fn (span, rcvr_ty, expr, item_name, &mut err)
976
912
&& lev_candidate.is_none()
977
913
&& !custom_span_label
978
914
{
@@ -982,10 +918,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
982
918
label_span_not_found(&mut err);
983
919
}
984
920
985
- // Don't suggest (for example) `expr.field.method ()` if `expr.method ()`
986
- // doesn 't exist due to unsatisfied predicates .
921
+ // Don't suggest (for example) `expr.field.clone ()` if `expr.clone ()`
922
+ // can 't be called due to `typeof(expr): Clone` not holding .
987
923
if unsatisfied_predicates.is_empty() {
988
- self.check_for_field_method (&mut err, source, span, actual, item_name);
924
+ self.suggest_calling_method_on_field (&mut err, source, span, actual, item_name);
989
925
}
990
926
991
927
self.check_for_inner_self(&mut err, source, span, actual, item_name);
@@ -1007,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1007
943
source,
1008
944
out_of_scope_traits,
1009
945
&unsatisfied_predicates,
1010
- &static_sources ,
946
+ &static_candidates ,
1011
947
unsatisfied_bounds,
1012
948
);
1013
949
}
@@ -1146,7 +1082,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1146
1082
None
1147
1083
}
1148
1084
1149
- fn suggest_field_call(
1085
+ /// Suggest calling a field with a type that implements the `Fn*` traits instead of a method with
1086
+ /// the same name as the field i.e. `(a.my_fn_ptr)(10)` instead of `a.my_fn_ptr(10)`.
1087
+ fn suggest_calling_field_as_fn(
1150
1088
&self,
1151
1089
span: Span,
1152
1090
rcvr_ty: Ty<'tcx>,
@@ -1408,7 +1346,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1408
1346
false
1409
1347
}
1410
1348
1411
- fn check_for_field_method(
1349
+ /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()`
1350
+ fn suggest_calling_method_on_field(
1412
1351
&self,
1413
1352
err: &mut Diagnostic,
1414
1353
source: SelfSource<'tcx>,
@@ -2021,7 +1960,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2021
1960
) {
2022
1961
let mut alt_rcvr_sugg = false;
2023
1962
if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
2024
- debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
1963
+ debug!(
1964
+ "suggest_traits_to_import: span={:?}, item_name={:?}, rcvr_ty={:?}, rcvr={:?}",
1965
+ span, item_name, rcvr_ty, rcvr
1966
+ );
2025
1967
let skippable = [
2026
1968
self.tcx.lang_items().clone_trait(),
2027
1969
self.tcx.lang_items().deref_trait(),
@@ -2060,7 +2002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2060
2002
// suggestions are generally misleading (see #94218).
2061
2003
break;
2062
2004
}
2063
- _ => {}
2005
+ Err(_) => (),
2064
2006
}
2065
2007
2066
2008
for (rcvr_ty, pre) in &[
0 commit comments