Skip to content

Commit 6d97180

Browse files
authored
Unrolled build for #144039
Rollup merge of #144039 - estebank:short-paths, r=fee1-dead Use `tcx.short_string()` in more diagnostics `TyCtxt::short_string` ensures that user visible type paths aren't overwhelming on the terminal output, and properly saves the long name to disk as a side-channel. We already use these throughout the compiler and have been using them as needed when users find cases where the output is verbose. This is a proactive search of some cases to use `short_string`. We add support for shortening the path of "trait path only". Every manual use of `short_string` is a bright marker that that error should be using structured diagnostics instead (as they have proper handling of long types without the maintainer having to think abou tthem).
2 parents de3efa7 + 9919665 commit 6d97180

File tree

68 files changed

+397
-339
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+397
-339
lines changed

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
13821382
&mut self.long_ty_path
13831383
}
13841384

1385+
pub fn with_long_ty_path(mut self, long_ty_path: Option<PathBuf>) -> Self {
1386+
self.long_ty_path = long_ty_path;
1387+
self
1388+
}
1389+
13851390
/// Most `emit_producing_guarantee` functions use this as a starting point.
13861391
fn emit_producing_nothing(mut self) {
13871392
let diag = self.take_diag();

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,9 +1135,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11351135
);
11361136
}
11371137
} else {
1138+
let trait_ =
1139+
tcx.short_string(bound.print_only_trait_path(), err.long_ty_path());
11381140
err.note(format!(
1139-
"associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`",
1140-
bound.print_only_trait_path(),
1141+
"associated {assoc_kind_str} `{assoc_ident}` could derive from `{trait_}`",
11411142
));
11421143
}
11431144
}

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: 53 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -376,16 +376,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376376
}
377377
}
378378

379-
fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
380-
let mut file = None;
379+
fn suggest_missing_writer(
380+
&self,
381+
rcvr_ty: Ty<'tcx>,
382+
rcvr_expr: &hir::Expr<'tcx>,
383+
mut long_ty_path: Option<PathBuf>,
384+
) -> Diag<'_> {
381385
let mut err = struct_span_code_err!(
382386
self.dcx(),
383387
rcvr_expr.span,
384388
E0599,
385389
"cannot write into `{}`",
386-
self.tcx.short_string(rcvr_ty, &mut file),
390+
self.tcx.short_string(rcvr_ty, &mut long_ty_path),
387391
);
388-
*err.long_ty_path() = file;
392+
*err.long_ty_path() = long_ty_path;
389393
err.span_note(
390394
rcvr_expr.span,
391395
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
@@ -403,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403407
&self,
404408
self_source: SelfSource<'tcx>,
405409
method_name: Ident,
406-
ty_str_reported: &str,
410+
ty: Ty<'tcx>,
407411
err: &mut Diag<'_>,
408412
) {
409413
#[derive(Debug)]
@@ -478,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478482
}
479483

480484
// If the shadowed binding has an itializer expression,
481-
// use the initializer expression'ty to try to find the method again.
485+
// use the initializer expression's ty to try to find the method again.
482486
// For example like: `let mut x = Vec::new();`,
483487
// `Vec::new()` is the itializer expression.
484488
if let Some(self_ty) = self.fcx.node_ty_opt(binding.init_hir_id)
@@ -566,17 +570,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
566570
let mut span = MultiSpan::from_span(sugg_let.span);
567571
span.push_span_label(sugg_let.span,
568572
format!("`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here"));
573+
574+
let ty = self.tcx.short_string(ty, err.long_ty_path());
569575
span.push_span_label(
570576
self.tcx.hir_span(recv_id),
571-
format!(
572-
"earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
573-
),
577+
format!("earlier `{rcvr_name}` shadowed here with type `{ty}`"),
574578
);
575579
err.span_note(
576580
span,
577581
format!(
578582
"there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \
579-
that has method `{method_name}` available"
583+
that has method `{method_name}` available"
580584
),
581585
);
582586
}
@@ -602,15 +606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
602606
let tcx = self.tcx;
603607
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
604608
let mut ty_file = None;
605-
let (ty_str, short_ty_str) =
606-
if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
607-
(predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
608-
} else {
609-
(
610-
tcx.short_string(rcvr_ty, &mut ty_file),
611-
with_forced_trimmed_paths!(rcvr_ty.to_string()),
612-
)
613-
};
614609
let is_method = mode == Mode::MethodCall;
615610
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
616611
let similar_candidate = no_match_data.similar_candidate;
@@ -629,15 +624,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
629624

630625
// We could pass the file for long types into these two, but it isn't strictly necessary
631626
// given how targeted they are.
632-
if let Err(guar) = self.report_failed_method_call_on_range_end(
633-
tcx,
634-
rcvr_ty,
635-
source,
636-
span,
637-
item_ident,
638-
&short_ty_str,
639-
&mut ty_file,
640-
) {
627+
if let Err(guar) =
628+
self.report_failed_method_call_on_range_end(tcx, rcvr_ty, source, span, item_ident)
629+
{
641630
return guar;
642631
}
643632
if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var(
@@ -647,44 +636,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647636
span,
648637
item_kind,
649638
item_ident,
650-
&short_ty_str,
651639
&mut ty_file,
652640
) {
653641
return guar;
654642
}
655643
span = item_ident.span;
656644

657-
// Don't show generic arguments when the method can't be found in any implementation (#81576).
658-
let mut ty_str_reported = ty_str.clone();
659-
if let ty::Adt(_, generics) = rcvr_ty.kind() {
660-
if generics.len() > 0 {
661-
let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors();
662-
let candidate_found = autoderef.any(|(ty, _)| {
663-
if let ty::Adt(adt_def, _) = ty.kind() {
664-
self.tcx
665-
.inherent_impls(adt_def.did())
666-
.into_iter()
667-
.any(|def_id| self.associated_value(*def_id, item_ident).is_some())
668-
} else {
669-
false
670-
}
671-
});
672-
let has_deref = autoderef.step_count() > 0;
673-
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
674-
if let Some((path_string, _)) = ty_str.split_once('<') {
675-
ty_str_reported = path_string.to_string();
676-
}
677-
}
678-
}
679-
}
680-
681645
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
682646
tcx.is_diagnostic_item(sym::write_macro, def_id)
683647
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
684648
}) && item_ident.name == sym::write_fmt;
685649
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
686-
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
650+
self.suggest_missing_writer(rcvr_ty, rcvr_expr, ty_file)
687651
} else {
652+
// Don't show expanded generic arguments when the method can't be found in any
653+
// implementation (#81576).
654+
let mut ty = rcvr_ty;
655+
if let ty::Adt(def, generics) = rcvr_ty.kind() {
656+
if generics.len() > 0 {
657+
let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors();
658+
let candidate_found = autoderef.any(|(ty, _)| {
659+
if let ty::Adt(adt_def, _) = ty.kind() {
660+
self.tcx
661+
.inherent_impls(adt_def.did())
662+
.into_iter()
663+
.any(|def_id| self.associated_value(*def_id, item_ident).is_some())
664+
} else {
665+
false
666+
}
667+
});
668+
let has_deref = autoderef.step_count() > 0;
669+
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
670+
ty = self.tcx.at(span).type_of(def.did()).instantiate_identity();
671+
}
672+
}
673+
}
674+
688675
let mut err = self.dcx().create_err(NoAssociatedItem {
689676
span,
690677
item_kind,
@@ -695,16 +682,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695682
} else {
696683
rcvr_ty.prefix_string(self.tcx)
697684
},
698-
ty_str: ty_str_reported.clone(),
685+
ty,
699686
trait_missing_method,
700687
});
701688

702689
if is_method {
703690
self.suggest_use_shadowed_binding_with_method(
704-
source,
705-
item_ident,
706-
&ty_str_reported,
707-
&mut err,
691+
source, item_ident, rcvr_ty, &mut err,
708692
);
709693
}
710694

@@ -734,6 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734718

735719
err
736720
};
721+
737722
if tcx.sess.source_map().is_multiline(sugg_span) {
738723
err.span_label(sugg_span.with_hi(span.lo()), "");
739724
}
@@ -750,6 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
750735
}
751736

752737
if tcx.ty_is_opaque_future(rcvr_ty) && item_ident.name == sym::poll {
738+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
753739
err.help(format!(
754740
"method `poll` found on `Pin<&mut {ty_str}>`, \
755741
see documentation for `std::pin::Pin`"
@@ -1339,14 +1325,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13391325
}
13401326
let OnUnimplementedNote { message, label, notes, .. } = self
13411327
.err_ctxt()
1342-
.on_unimplemented_note(trait_ref, &obligation, &mut ty_file);
1328+
.on_unimplemented_note(trait_ref, &obligation, err.long_ty_path());
13431329
(message, label, notes)
13441330
})
13451331
.unwrap()
13461332
} else {
13471333
(None, None, Vec::new())
13481334
};
13491335
let primary_message = primary_message.unwrap_or_else(|| {
1336+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
13501337
format!(
13511338
"the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
13521339
but its trait bounds were not satisfied"
@@ -1409,6 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091396
let mut find_candidate_for_method = false;
14101397

14111398
let mut label_span_not_found = |err: &mut Diag<'_>| {
1399+
let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path());
14121400
if unsatisfied_predicates.is_empty() {
14131401
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
14141402
let is_string_or_ref_str = match rcvr_ty.kind() {
@@ -2520,8 +2508,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25202508
source: SelfSource<'tcx>,
25212509
span: Span,
25222510
item_name: Ident,
2523-
ty_str: &str,
2524-
long_ty_path: &mut Option<PathBuf>,
25252511
) -> Result<(), ErrorGuaranteed> {
25262512
if let SelfSource::MethodCall(expr) = source {
25272513
for (_, parent) in tcx.hir_parent_iter(expr.hir_id).take(5) {
@@ -2583,18 +2569,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25832569
);
25842570
if pick.is_ok() {
25852571
let range_span = parent_expr.span.with_hi(expr.span.hi());
2586-
let mut err = self.dcx().create_err(errors::MissingParenthesesInRange {
2572+
return Err(self.dcx().emit_err(errors::MissingParenthesesInRange {
25872573
span,
2588-
ty_str: ty_str.to_string(),
2574+
ty: actual,
25892575
method_name: item_name.as_str().to_string(),
25902576
add_missing_parentheses: Some(errors::AddMissingParenthesesInRange {
25912577
func_name: item_name.name.as_str().to_string(),
25922578
left: range_span.shrink_to_lo(),
25932579
right: range_span.shrink_to_hi(),
25942580
}),
2595-
});
2596-
*err.long_ty_path() = long_ty_path.take();
2597-
return Err(err.emit());
2581+
}));
25982582
}
25992583
}
26002584
}
@@ -2610,7 +2594,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26102594
span: Span,
26112595
item_kind: &str,
26122596
item_name: Ident,
2613-
ty_str: &str,
26142597
long_ty_path: &mut Option<PathBuf>,
26152598
) -> Result<(), ErrorGuaranteed> {
26162599
let found_candidate = all_traits(self.tcx)
@@ -2643,14 +2626,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26432626
&& !actual.has_concrete_skeleton()
26442627
&& let SelfSource::MethodCall(expr) = source
26452628
{
2629+
let ty_str = self.tcx.short_string(actual, long_ty_path);
26462630
let mut err = struct_span_code_err!(
26472631
self.dcx(),
26482632
span,
26492633
E0689,
2650-
"can't call {} `{}` on ambiguous numeric type `{}`",
2651-
item_kind,
2652-
item_name,
2653-
ty_str
2634+
"can't call {item_kind} `{item_name}` on ambiguous numeric type `{ty_str}`"
26542635
);
26552636
*err.long_ty_path() = long_ty_path.take();
26562637
let concrete_type = if actual.is_integral() { "i32" } else { "f32" };

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2987,7 +2987,7 @@ impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> {
29872987
}
29882988
}
29892989

2990-
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
2990+
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)]
29912991
pub struct TraitPredPrintModifiersAndPath<'tcx>(ty::TraitPredicate<'tcx>);
29922992

29932993
impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> {

compiler/rustc_trait_selection/messages.ftl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,6 @@ trait_selection_fps_remove_ref = consider removing the reference
171171
trait_selection_fps_use_ref = consider using a reference
172172
trait_selection_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
173173
174-
trait_selection_full_type_written = the full type name has been written to '{$path}'
175-
176174
trait_selection_ignored_diagnostic_option = `{$option_name}` is ignored due to previous definition of `{$option_name}`
177175
.other_label = `{$option_name}` is first declared here
178176
.label = `{$option_name}` is already declared here

0 commit comments

Comments
 (0)