Skip to content

Commit f7ed72d

Browse files
authored
Rollup merge of rust-lang#103937 - BoxyUwU:misc_cleanups, r=compiler-errors
minor changes to make method lookup diagnostic code easier to read The end result of around 4 days of trying to understand this 1000+ line long function- a bunch of tiny nitpicks r? `@compiler-errors`
2 parents 2aa8ad6 + 3583f27 commit f7ed72d

File tree

6 files changed

+56
-101
lines changed

6 files changed

+56
-101
lines changed

compiler/rustc_hir_typeck/src/method/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ pub enum MethodError<'tcx> {
5555
// not-in-scope traits which may work.
5656
PrivateMatch(DefKind, DefId, Vec<DefId>),
5757

58-
// Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have
59-
// forgotten to import a trait.
58+
// Found a `Self: Sized` bound where `Self` is a trait object.
6059
IllegalSizedBound(Vec<DefId>, bool, Span),
6160

6261
// Found a match, but the return type is wrong

compiler/rustc_hir_typeck/src/method/probe.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10191019

10201020
let out_of_scope_traits = match self.pick_core() {
10211021
Some(Ok(p)) => vec![p.item.container_id(self.tcx)],
1022-
//Some(Ok(p)) => p.iter().map(|p| p.item.container().id()).collect(),
10231022
Some(Err(MethodError::Ambiguity(v))) => v
10241023
.into_iter()
10251024
.map(|source| match source {

compiler/rustc_hir_typeck/src/method/suggest.rs

+39-97
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248248

249249
match error {
250250
MethodError::NoMatch(NoMatchData {
251-
static_candidates: mut static_sources,
251+
mut static_candidates,
252252
unsatisfied_predicates,
253253
out_of_scope_traits,
254254
lev_candidate,
@@ -288,9 +288,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
288288
if generics.len() > 0 {
289289
let mut autoderef = self.autoderef(span, actual);
290290
let candidate_found = autoderef.any(|(ty, _)| {
291-
if let ty::Adt(adt_deref, _) = ty.kind() {
291+
if let ty::Adt(adt_def, _) = ty.kind() {
292292
self.tcx
293-
.inherent_impls(adt_deref.did())
293+
.inherent_impls(adt_def.did())
294294
.iter()
295295
.filter_map(|def_id| self.associated_value(*def_id, item_name))
296296
.count()
@@ -348,15 +348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348348
}
349349

350350
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+
),
356354
ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
357355
_ => None,
358356
};
359-
360357
if let Some(span) = ty_span {
361358
err.span_label(
362359
span,
@@ -386,17 +383,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386383

387384
let mut custom_span_label = false;
388385

389-
if !static_sources.is_empty() {
386+
if !static_candidates.is_empty() {
390387
err.note(
391388
"found the following associated functions; to be used as methods, \
392389
functions must have a `self` parameter",
393390
);
394391
err.span_label(span, "this is an associated function, not a method");
395392
custom_span_label = true;
396393
}
397-
if static_sources.len() == 1 {
394+
if static_candidates.len() == 1 {
398395
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) {
400397
// When the "method" is resolved through dereferencing, we really want the
401398
// original type that has the associated function for accurate suggestions.
402399
// (#61411)
@@ -422,9 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
422419
err.help(&format!("try with `{}::{}`", ty_str, item_name,));
423420
}
424421

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);
428425
}
429426

430427
let mut bound_spans = vec![];
@@ -496,24 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496493
if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
497494
(self_ty.kind(), parent_pred.kind().skip_binder())
498495
{
496+
let hir = self.tcx.hir();
499497
let node = match p.trait_ref.self_ty().kind() {
500498
ty::Param(_) => {
501499
// Account for `fn` items like in `issue-35677.rs` to
502500
// 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))
511507
}
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-
}),
517508
_ => None,
518509
};
519510
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
@@ -605,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605596
.iter()
606597
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
607598
.filter_map(|(p, parent, c)| match c.code() {
608-
ObligationCauseCode::ImplDerivedObligation(ref data) => {
599+
ObligationCauseCode::ImplDerivedObligation(data) => {
609600
Some((&data.derived, p, parent, data.impl_def_id, data))
610601
}
611602
_ => None,
@@ -620,22 +611,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
620611
match self.tcx.hir().get_if_local(impl_def_id) {
621612
// Unmet obligation comes from a `derive` macro, point at it once to
622613
// 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-
639614
Some(Node::Item(hir::Item {
640615
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
641616
..
@@ -659,34 +634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659634
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
660635
}
661636

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-
690637
// Unmet obligation coming from an `impl`.
691638
Some(Node::Item(hir::Item {
692639
kind:
@@ -695,19 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695642
}),
696643
span: item_span,
697644
..
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+
})) => {
711646
let sized_pred =
712647
unsatisfied_predicates.iter().any(|(pred, _, _)| {
713648
match pred.kind().skip_binder() {
@@ -759,7 +694,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
759694
let entry = spanned_predicates.entry(spans);
760695
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
761696
}
762-
_ => {}
697+
Some(_) => unreachable!(),
698+
None => (),
763699
}
764700
}
765701
let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
@@ -863,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
863799
.on_unimplemented_note(trait_ref, &obligation);
864800
(message, label)
865801
})
866-
.unwrap_or((None, None))
802+
.unwrap()
867803
} else {
868804
(None, None)
869805
};
@@ -972,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972908
// If the method name is the name of a field with a function or closure type,
973909
// give a helping note that it has to be called as `(x.f)(...)`.
974910
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)
976912
&& lev_candidate.is_none()
977913
&& !custom_span_label
978914
{
@@ -982,10 +918,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
982918
label_span_not_found(&mut err);
983919
}
984920

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.
987923
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);
989925
}
990926

991927
self.check_for_inner_self(&mut err, source, span, actual, item_name);
@@ -1007,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1007943
source,
1008944
out_of_scope_traits,
1009945
&unsatisfied_predicates,
1010-
&static_sources,
946+
&static_candidates,
1011947
unsatisfied_bounds,
1012948
);
1013949
}
@@ -1146,7 +1082,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11461082
None
11471083
}
11481084

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(
11501088
&self,
11511089
span: Span,
11521090
rcvr_ty: Ty<'tcx>,
@@ -1408,7 +1346,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14081346
false
14091347
}
14101348

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(
14121351
&self,
14131352
err: &mut Diagnostic,
14141353
source: SelfSource<'tcx>,
@@ -2021,7 +1960,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20211960
) {
20221961
let mut alt_rcvr_sugg = false;
20231962
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+
);
20251967
let skippable = [
20261968
self.tcx.lang_items().clone_trait(),
20271969
self.tcx.lang_items().deref_trait(),
@@ -2060,7 +2002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20602002
// suggestions are generally misleading (see #94218).
20612003
break;
20622004
}
2063-
_ => {}
2005+
Err(_) => (),
20642006
}
20652007

20662008
for (rcvr_ty, pre) in &[

compiler/rustc_middle/src/traits/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,20 @@ pub struct UnifyReceiverContext<'tcx> {
203203
pub substs: SubstsRef<'tcx>,
204204
}
205205

206-
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, Default)]
206+
#[derive(Clone, PartialEq, Eq, Hash, Lift, Default)]
207207
pub struct InternedObligationCauseCode<'tcx> {
208208
/// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of
209209
/// the time). `Some` otherwise.
210210
code: Option<Lrc<ObligationCauseCode<'tcx>>>,
211211
}
212212

213+
impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
214+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215+
let cause: &ObligationCauseCode<'_> = self;
216+
cause.fmt(f)
217+
}
218+
}
219+
213220
impl<'tcx> ObligationCauseCode<'tcx> {
214221
#[inline(always)]
215222
fn into(self) -> InternedObligationCauseCode<'tcx> {

compiler/rustc_middle/src/ty/sty.rs

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_hir::def_id::DefId;
2020
use rustc_index::vec::Idx;
2121
use rustc_macros::HashStable;
2222
use rustc_span::symbol::{kw, sym, Symbol};
23+
use rustc_span::Span;
2324
use rustc_target::abi::VariantIdx;
2425
use rustc_target::spec::abi;
2526
use std::borrow::Cow;
@@ -1282,6 +1283,12 @@ impl<'tcx> ParamTy {
12821283
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
12831284
tcx.mk_ty_param(self.index, self.name)
12841285
}
1286+
1287+
pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
1288+
let generics = tcx.generics_of(item_with_generics);
1289+
let type_param = generics.type_param(self, tcx);
1290+
tcx.def_span(type_param.def_id)
1291+
}
12851292
}
12861293

12871294
#[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]

compiler/rustc_trait_selection/src/traits/on_unimplemented.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct OnUnimplementedDirective {
2727
}
2828

2929
#[derive(Default)]
30+
/// For the `#[rustc_on_unimplemented]` attribute
3031
pub struct OnUnimplementedNote {
3132
pub message: Option<String>,
3233
pub label: Option<String>,

0 commit comments

Comments
 (0)