Skip to content

Commit d7a8bfd

Browse files
committed
Tweak use of short_string in method errors
1 parent 560185a commit d7a8bfd

28 files changed

+137
-150
lines changed

compiler/rustc_hir_typeck/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ hir_typeck_lossy_provenance_ptr2int =
159159
.suggestion = use `.addr()` to obtain the address of a pointer
160160
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
161161
162-
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
162+
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty}`
163163
164164
hir_typeck_naked_asm_outside_naked_fn =
165165
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
@@ -184,7 +184,7 @@ hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback af
184184
hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access
185185
.help = specify the type explicitly
186186
187-
hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
187+
hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty}`{$trait_missing_method ->
188188
[true] {""}
189189
*[other] {" "}in the current scope
190190
}

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,11 @@ pub(crate) enum ExplicitDestructorCallSugg {
200200

201201
#[derive(Diagnostic)]
202202
#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
203-
pub(crate) struct MissingParenthesesInRange {
203+
pub(crate) struct MissingParenthesesInRange<'tcx> {
204204
#[primary_span]
205205
#[label(hir_typeck_missing_parentheses_in_range)]
206206
pub span: Span,
207-
pub ty_str: String,
207+
pub ty: Ty<'tcx>,
208208
pub method_name: String,
209209
#[subdiagnostic]
210210
pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
@@ -828,13 +828,13 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> {
828828

829829
#[derive(Diagnostic)]
830830
#[diag(hir_typeck_no_associated_item, code = E0599)]
831-
pub(crate) struct NoAssociatedItem {
831+
pub(crate) struct NoAssociatedItem<'tcx> {
832832
#[primary_span]
833833
pub span: Span,
834834
pub item_kind: &'static str,
835835
pub item_ident: Ident,
836836
pub ty_prefix: Cow<'static, str>,
837-
pub ty_str: String,
837+
pub ty: Ty<'tcx>,
838838
pub trait_missing_method: bool,
839839
}
840840

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
406406
&self,
407407
self_source: SelfSource<'tcx>,
408408
method_name: Ident,
409-
ty_str_reported: &str,
409+
unsatisfied_predicates: &[(
410+
ty::Predicate<'tcx>,
411+
Option<ty::Predicate<'tcx>>,
412+
Option<ObligationCause<'tcx>>,
413+
)],
414+
ty: Ty<'tcx>,
410415
err: &mut Diag<'_>,
411416
) {
412417
#[derive(Debug)]
@@ -569,17 +574,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
569574
let mut span = MultiSpan::from_span(sugg_let.span);
570575
span.push_span_label(sugg_let.span,
571576
format!("`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here"));
577+
578+
// Don't show generic arguments when the method can't be found in any implementation (#81576).
579+
let mut ty_str = None;
580+
if let ty::Adt(_, generics) = ty.kind() {
581+
if generics.len() > 0 {
582+
let mut autoderef = self.autoderef(DUMMY_SP, ty).silence_errors();
583+
let candidate_found = autoderef.any(|(ty, _)| {
584+
if let ty::Adt(adt_def, _) = ty.kind() {
585+
self.tcx.inherent_impls(adt_def.did()).into_iter().any(
586+
|def_id| {
587+
self.associated_value(*def_id, method_name).is_some()
588+
},
589+
)
590+
} else {
591+
false
592+
}
593+
});
594+
let has_deref = autoderef.step_count() > 0;
595+
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
596+
let t = with_forced_trimmed_paths!(ty.to_string());
597+
if let Some((path_string, _)) = t.split_once('<') {
598+
ty_str = Some(path_string.to_string());
599+
}
600+
}
601+
}
602+
}
603+
604+
let ty =
605+
ty_str.unwrap_or_else(|| self.tcx.short_string(ty, err.long_ty_path()));
572606
span.push_span_label(
573607
self.tcx.hir_span(recv_id),
574-
format!(
575-
"earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
576-
),
608+
format!("earlier `{rcvr_name}` shadowed here with type `{ty}`"),
577609
);
578610
err.span_note(
579611
span,
580612
format!(
581613
"there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \
582-
that has method `{method_name}` available"
614+
that has method `{method_name}` available"
583615
),
584616
);
585617
}
@@ -605,15 +637,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605637
let tcx = self.tcx;
606638
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
607639
let mut ty_file = None;
608-
let (ty_str, short_ty_str) =
609-
if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
610-
(predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
611-
} else {
612-
(
613-
tcx.short_string(rcvr_ty, &mut ty_file),
614-
with_forced_trimmed_paths!(rcvr_ty.to_string()),
615-
)
616-
};
617640
let is_method = mode == Mode::MethodCall;
618641
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
619642
let similar_candidate = no_match_data.similar_candidate;
@@ -632,15 +655,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
632655

633656
// We could pass the file for long types into these two, but it isn't strictly necessary
634657
// given how targeted they are.
635-
if let Err(guar) = self.report_failed_method_call_on_range_end(
636-
tcx,
637-
rcvr_ty,
638-
source,
639-
span,
640-
item_ident,
641-
&short_ty_str,
642-
&mut ty_file,
643-
) {
658+
if let Err(guar) =
659+
self.report_failed_method_call_on_range_end(tcx, rcvr_ty, source, span, item_ident)
660+
{
644661
return guar;
645662
}
646663
if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var(
@@ -650,37 +667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
650667
span,
651668
item_kind,
652669
item_ident,
653-
&short_ty_str,
654670
&mut ty_file,
655671
) {
656672
return guar;
657673
}
658674
span = item_ident.span;
659675

660-
// Don't show generic arguments when the method can't be found in any implementation (#81576).
661-
let mut ty_str_reported = ty_str.clone();
662-
if let ty::Adt(_, generics) = rcvr_ty.kind() {
663-
if generics.len() > 0 {
664-
let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors();
665-
let candidate_found = autoderef.any(|(ty, _)| {
666-
if let ty::Adt(adt_def, _) = ty.kind() {
667-
self.tcx
668-
.inherent_impls(adt_def.did())
669-
.into_iter()
670-
.any(|def_id| self.associated_value(*def_id, item_ident).is_some())
671-
} else {
672-
false
673-
}
674-
});
675-
let has_deref = autoderef.step_count() > 0;
676-
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
677-
if let Some((path_string, _)) = ty_str.split_once('<') {
678-
ty_str_reported = path_string.to_string();
679-
}
680-
}
681-
}
682-
}
683-
684676
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
685677
tcx.is_diagnostic_item(sym::write_macro, def_id)
686678
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
@@ -698,16 +690,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
698690
} else {
699691
rcvr_ty.prefix_string(self.tcx)
700692
},
701-
ty_str: ty_str_reported.clone(),
693+
ty: rcvr_ty,
702694
trait_missing_method,
703695
});
704-
*err.long_ty_path() = ty_file;
705696

706697
if is_method {
707698
self.suggest_use_shadowed_binding_with_method(
708699
source,
709700
item_ident,
710-
&ty_str_reported,
701+
&unsatisfied_predicates,
702+
rcvr_ty,
711703
&mut err,
712704
);
713705
}
@@ -738,6 +730,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
738730

739731
err
740732
};
733+
741734
if tcx.sess.source_map().is_multiline(sugg_span) {
742735
err.span_label(sugg_span.with_hi(span.lo()), "");
743736
}
@@ -754,6 +747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
754747
}
755748

756749
if tcx.ty_is_opaque_future(rcvr_ty) && item_ident.name == sym::poll {
750+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
757751
err.help(format!(
758752
"method `poll` found on `Pin<&mut {ty_str}>`, \
759753
see documentation for `std::pin::Pin`"
@@ -1351,6 +1345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13511345
(None, None, Vec::new())
13521346
};
13531347
let primary_message = primary_message.unwrap_or_else(|| {
1348+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
13541349
format!(
13551350
"the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
13561351
but its trait bounds were not satisfied"
@@ -1413,6 +1408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14131408
let mut find_candidate_for_method = false;
14141409

14151410
let mut label_span_not_found = |err: &mut Diag<'_>| {
1411+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
14161412
if unsatisfied_predicates.is_empty() {
14171413
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
14181414
let is_string_or_ref_str = match rcvr_ty.kind() {
@@ -2524,8 +2520,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25242520
source: SelfSource<'tcx>,
25252521
span: Span,
25262522
item_name: Ident,
2527-
ty_str: &str,
2528-
long_ty_path: &mut Option<PathBuf>,
25292523
) -> Result<(), ErrorGuaranteed> {
25302524
if let SelfSource::MethodCall(expr) = source {
25312525
for (_, parent) in tcx.hir_parent_iter(expr.hir_id).take(5) {
@@ -2587,18 +2581,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25872581
);
25882582
if pick.is_ok() {
25892583
let range_span = parent_expr.span.with_hi(expr.span.hi());
2590-
let mut err = self.dcx().create_err(errors::MissingParenthesesInRange {
2584+
return Err(self.dcx().emit_err(errors::MissingParenthesesInRange {
25912585
span,
2592-
ty_str: ty_str.to_string(),
2586+
ty: actual,
25932587
method_name: item_name.as_str().to_string(),
25942588
add_missing_parentheses: Some(errors::AddMissingParenthesesInRange {
25952589
func_name: item_name.name.as_str().to_string(),
25962590
left: range_span.shrink_to_lo(),
25972591
right: range_span.shrink_to_hi(),
25982592
}),
2599-
});
2600-
*err.long_ty_path() = long_ty_path.take();
2601-
return Err(err.emit());
2593+
}));
26022594
}
26032595
}
26042596
}
@@ -2614,7 +2606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26142606
span: Span,
26152607
item_kind: &str,
26162608
item_name: Ident,
2617-
ty_str: &str,
26182609
long_ty_path: &mut Option<PathBuf>,
26192610
) -> Result<(), ErrorGuaranteed> {
26202611
let found_candidate = all_traits(self.tcx)
@@ -2647,14 +2638,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26472638
&& !actual.has_concrete_skeleton()
26482639
&& let SelfSource::MethodCall(expr) = source
26492640
{
2641+
let ty_str = self.tcx.short_string(actual, long_ty_path);
26502642
let mut err = struct_span_code_err!(
26512643
self.dcx(),
26522644
span,
26532645
E0689,
2654-
"can't call {} `{}` on ambiguous numeric type `{}`",
2655-
item_kind,
2656-
item_name,
2657-
ty_str
2646+
"can't call {item_kind} `{item_name}` on ambiguous numeric type `{ty_str}`"
26582647
);
26592648
*err.long_ty_path() = long_ty_path.take();
26602649
let concrete_type = if actual.is_integral() { "i32" } else { "f32" };

tests/ui/attributes/rustc_confusables_std_cases.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `push` found for struct `BTreeSet` in the current scope
1+
error[E0599]: no method named `push` found for struct `BTreeSet<_>` in the current scope
22
--> $DIR/rustc_confusables_std_cases.rs:6:7
33
|
44
LL | x.push(1);
@@ -22,7 +22,7 @@ LL - x.push_back(1);
2222
LL + x.push(1);
2323
|
2424

25-
error[E0599]: no method named `push` found for struct `VecDeque` in the current scope
25+
error[E0599]: no method named `push` found for struct `VecDeque<_>` in the current scope
2626
--> $DIR/rustc_confusables_std_cases.rs:12:7
2727
|
2828
LL | x.push(1);

tests/ui/confuse-field-and-method/issue-18343.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `closure` found for struct `Obj` in the current scope
1+
error[E0599]: no method named `closure` found for struct `Obj<{closure@$DIR/issue-18343.rs:6:28: 6:30}>` in the current scope
22
--> $DIR/issue-18343.rs:7:7
33
|
44
LL | struct Obj<F> where F: FnMut() -> u32 {

tests/ui/confuse-field-and-method/issue-2392.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// FIXME(estebank): diagnostics with long type paths that don't print out the full path anywhere
2-
// still prints the note explaining where the type was written to.
31
//@ compile-flags: -Zwrite-long-types-to-disk=yes
42

53
struct FuncContainer {

0 commit comments

Comments
 (0)