Skip to content

Commit 77ad0d8

Browse files
authored
Unrolled build for rust-lang#121739
Rollup merge of rust-lang#121739 - jieyouxu:loooong-typename, r=estebank Display short types for unimplemented trait Shortens unimplemented trait diagnostics. Now shows: ``` error[E0277]: `Option<Option<Option<...>>>` doesn't implement `std::fmt::Display` --> $DIR/on_unimplemented_long_types.rs:4:17 | LL | pub fn foo() -> impl std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^ `Option<Option<Option<...>>>` cannot be formatted with the default formatter LL | LL | / Some(Some(Some(Some(Some(Some(Some(Some(Some(S... LL | | Some(Some(Some(Some(Some(Some(Some(Some(So... LL | | Some(Some(Some(Some(Some(Some(Some(Som... LL | | Some(Some(Some(Some(Some(Some(Some... ... | LL | | ))))))))))), LL | | ))))))))))) | |_______________- return type was inferred to be `Option<Option<Option<...>>>` here | = help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. ``` I'm not 100% sure if this is desirable, or if we should just let the long types remain long. This is also kinda a short-term bandaid solution. The real long term solution is to properly migrate `rustc_trait_selection`'s error reporting to use translatable diagnostics and then properly handle type name printing. Fixes rust-lang#121687.
2 parents 2e3581b + 62baa67 commit 77ad0d8

File tree

6 files changed

+117
-50
lines changed

6 files changed

+117
-50
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10491049
bound_list.into_iter().map(|(_, path)| path).collect::<Vec<_>>().join("\n");
10501050
let actual_prefix = rcvr_ty.prefix_string(self.tcx);
10511051
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
1052+
let mut long_ty_file = None;
10521053
let (primary_message, label) = if unimplemented_traits.len() == 1
10531054
&& unimplemented_traits_only
10541055
{
@@ -1061,8 +1062,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10611062
// Avoid crashing.
10621063
return (None, None);
10631064
}
1064-
let OnUnimplementedNote { message, label, .. } =
1065-
self.err_ctxt().on_unimplemented_note(trait_ref, &obligation);
1065+
let OnUnimplementedNote { message, label, .. } = self
1066+
.err_ctxt()
1067+
.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
10661068
(message, label)
10671069
})
10681070
.unwrap()
@@ -1076,6 +1078,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10761078
)
10771079
});
10781080
err.primary_message(primary_message);
1081+
if let Some(file) = long_ty_file {
1082+
err.note(format!(
1083+
"the full name for the type has been written to '{}'",
1084+
file.display(),
1085+
));
1086+
err.note(
1087+
"consider using `--verbose` to print the full type name to the console",
1088+
);
1089+
}
10791090
if let Some(label) = label {
10801091
custom_span_label = true;
10811092
err.span_label(span, label);

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
1616
use rustc_span::symbol::{kw, sym, Symbol};
1717
use rustc_span::Span;
1818
use std::iter;
19+
use std::path::PathBuf;
1920

2021
use crate::errors::{
2122
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
@@ -110,6 +111,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
110111
&self,
111112
trait_ref: ty::PolyTraitRef<'tcx>,
112113
obligation: &PredicateObligation<'tcx>,
114+
long_ty_file: &mut Option<PathBuf>,
113115
) -> OnUnimplementedNote {
114116
let (def_id, args) = self
115117
.impl_similar_to(trait_ref, obligation)
@@ -265,7 +267,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
265267
}));
266268

267269
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
268-
command.evaluate(self.tcx, trait_ref, &flags)
270+
command.evaluate(self.tcx, trait_ref, &flags, long_ty_file)
269271
} else {
270272
OnUnimplementedNote::default()
271273
}
@@ -657,6 +659,7 @@ impl<'tcx> OnUnimplementedDirective {
657659
tcx: TyCtxt<'tcx>,
658660
trait_ref: ty::TraitRef<'tcx>,
659661
options: &[(Symbol, Option<String>)],
662+
long_ty_file: &mut Option<PathBuf>,
660663
) -> OnUnimplementedNote {
661664
let mut message = None;
662665
let mut label = None;
@@ -669,6 +672,7 @@ impl<'tcx> OnUnimplementedDirective {
669672
options.iter().filter_map(|(k, v)| v.clone().map(|v| (*k, v))).collect();
670673

671674
for command in self.subcommands.iter().chain(Some(self)).rev() {
675+
debug!(?command);
672676
if let Some(ref condition) = command.condition
673677
&& !attr::eval_condition(condition, &tcx.sess, Some(tcx.features()), &mut |cfg| {
674678
let value = cfg.value.map(|v| {
@@ -680,7 +684,12 @@ impl<'tcx> OnUnimplementedDirective {
680684
span: cfg.span,
681685
is_diagnostic_namespace_variant: false
682686
}
683-
.format(tcx, trait_ref, &options_map)
687+
.format(
688+
tcx,
689+
trait_ref,
690+
&options_map,
691+
long_ty_file
692+
)
684693
)
685694
});
686695

@@ -709,10 +718,14 @@ impl<'tcx> OnUnimplementedDirective {
709718
}
710719

711720
OnUnimplementedNote {
712-
label: label.map(|l| l.format(tcx, trait_ref, &options_map)),
713-
message: message.map(|m| m.format(tcx, trait_ref, &options_map)),
714-
notes: notes.into_iter().map(|n| n.format(tcx, trait_ref, &options_map)).collect(),
715-
parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)),
721+
label: label.map(|l| l.format(tcx, trait_ref, &options_map, long_ty_file)),
722+
message: message.map(|m| m.format(tcx, trait_ref, &options_map, long_ty_file)),
723+
notes: notes
724+
.into_iter()
725+
.map(|n| n.format(tcx, trait_ref, &options_map, long_ty_file))
726+
.collect(),
727+
parent_label: parent_label
728+
.map(|e_s| e_s.format(tcx, trait_ref, &options_map, long_ty_file)),
716729
append_const_msg,
717730
}
718731
}
@@ -814,6 +827,7 @@ impl<'tcx> OnUnimplementedFormatString {
814827
tcx: TyCtxt<'tcx>,
815828
trait_ref: ty::TraitRef<'tcx>,
816829
options: &FxHashMap<Symbol, String>,
830+
long_ty_file: &mut Option<PathBuf>,
817831
) -> String {
818832
let name = tcx.item_name(trait_ref.def_id);
819833
let trait_str = tcx.def_path_str(trait_ref.def_id);
@@ -824,7 +838,11 @@ impl<'tcx> OnUnimplementedFormatString {
824838
.filter_map(|param| {
825839
let value = match param.kind {
826840
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
827-
trait_ref.args[param.index as usize].to_string()
841+
if let Some(ty) = trait_ref.args[param.index as usize].as_type() {
842+
tcx.short_ty_string(ty, long_ty_file)
843+
} else {
844+
trait_ref.args[param.index as usize].to_string()
845+
}
828846
}
829847
GenericParamDefKind::Lifetime => return None,
830848
};

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+22-39
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26712671
) where
26722672
T: ToPredicate<'tcx>,
26732673
{
2674+
let mut long_ty_file = None;
2675+
26742676
let tcx = self.tcx;
26752677
let predicate = predicate.to_predicate(tcx);
26762678
match *cause_code {
@@ -2853,21 +2855,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
28532855
}
28542856
}
28552857
ObligationCauseCode::Coercion { source, target } => {
2856-
let mut file = None;
2857-
let source = tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut file);
2858-
let target = tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut file);
2858+
let source =
2859+
tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file);
2860+
let target =
2861+
tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut long_ty_file);
28592862
err.note(with_forced_trimmed_paths!(format!(
28602863
"required for the cast from `{source}` to `{target}`",
28612864
)));
2862-
if let Some(file) = file {
2863-
err.note(format!(
2864-
"the full name for the type has been written to '{}'",
2865-
file.display(),
2866-
));
2867-
err.note(
2868-
"consider using `--verbose` to print the full type name to the console",
2869-
);
2870-
}
28712865
}
28722866
ObligationCauseCode::RepeatElementCopy {
28732867
is_constable,
@@ -3170,8 +3164,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
31703164
// Don't print the tuple of capture types
31713165
'print: {
31723166
if !is_upvar_tys_infer_tuple {
3173-
let mut file = None;
3174-
let ty_str = tcx.short_ty_string(ty, &mut file);
3167+
let ty_str = tcx.short_ty_string(ty, &mut long_ty_file);
31753168
let msg = format!("required because it appears within the type `{ty_str}`");
31763169
match ty.kind() {
31773170
ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) {
@@ -3269,9 +3262,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
32693262
let mut parent_trait_pred =
32703263
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
32713264
let parent_def_id = parent_trait_pred.def_id();
3272-
let mut file = None;
3273-
let self_ty_str =
3274-
tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file);
3265+
let self_ty_str = tcx
3266+
.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut long_ty_file);
32753267
let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
32763268
let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`");
32773269
let mut is_auto_trait = false;
@@ -3329,15 +3321,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
33293321
}
33303322
};
33313323

3332-
if let Some(file) = file {
3333-
err.note(format!(
3334-
"the full type name has been written to '{}'",
3335-
file.display(),
3336-
));
3337-
err.note(
3338-
"consider using `--verbose` to print the full type name to the console",
3339-
);
3340-
}
33413324
let mut parent_predicate = parent_trait_pred;
33423325
let mut data = &data.derived;
33433326
let mut count = 0;
@@ -3378,22 +3361,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
33783361
count,
33793362
pluralize!(count)
33803363
));
3381-
let mut file = None;
3382-
let self_ty =
3383-
tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file);
3364+
let self_ty = tcx.short_ty_string(
3365+
parent_trait_pred.skip_binder().self_ty(),
3366+
&mut long_ty_file,
3367+
);
33843368
err.note(format!(
33853369
"required for `{self_ty}` to implement `{}`",
33863370
parent_trait_pred.print_modifiers_and_trait_path()
33873371
));
3388-
if let Some(file) = file {
3389-
err.note(format!(
3390-
"the full type name has been written to '{}'",
3391-
file.display(),
3392-
));
3393-
err.note(
3394-
"consider using `--verbose` to print the full type name to the console",
3395-
);
3396-
}
33973372
}
33983373
// #74711: avoid a stack overflow
33993374
ensure_sufficient_stack(|| {
@@ -3502,7 +3477,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
35023477
}
35033478
ObligationCauseCode::OpaqueReturnType(expr_info) => {
35043479
if let Some((expr_ty, expr_span)) = expr_info {
3505-
let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr_ty));
3480+
let expr_ty = self.tcx.short_ty_string(expr_ty, &mut long_ty_file);
35063481
err.span_label(
35073482
expr_span,
35083483
with_forced_trimmed_paths!(format!(
@@ -3512,6 +3487,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
35123487
}
35133488
}
35143489
}
3490+
3491+
if let Some(file) = long_ty_file {
3492+
err.note(format!(
3493+
"the full name for the type has been written to '{}'",
3494+
file.display(),
3495+
));
3496+
err.note("consider using `--verbose` to print the full type name to the console");
3497+
}
35153498
}
35163499

35173500
#[instrument(

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
395395
kind: _,
396396
} = *obligation.cause.code()
397397
{
398+
debug!("ObligationCauseCode::CompareImplItemObligation");
398399
return self.report_extra_impl_obligation(
399400
span,
400401
impl_item_def_id,
@@ -445,18 +446,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
445446
)
446447
})
447448
.unwrap_or_default();
448-
let file_note = file.map(|file| format!(
449+
let file_note = file.as_ref().map(|file| format!(
449450
"the full trait has been written to '{}'",
450451
file.display(),
451452
));
452453

454+
let mut long_ty_file = None;
455+
453456
let OnUnimplementedNote {
454457
message,
455458
label,
456459
notes,
457460
parent_label,
458461
append_const_msg,
459-
} = self.on_unimplemented_note(trait_ref, &obligation);
462+
} = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
463+
460464
let have_alt_message = message.is_some() || label.is_some();
461465
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
462466
let is_unsize =
@@ -511,6 +515,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
511515

512516
let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
513517

518+
if let Some(long_ty_file) = long_ty_file {
519+
err.note(format!(
520+
"the full name for the type has been written to '{}'",
521+
long_ty_file.display(),
522+
));
523+
err.note("consider using `--verbose` to print the full type name to the console");
524+
}
514525
let mut suggested = false;
515526
if is_try_conversion {
516527
suggested = self.try_conversion_context(&obligation, trait_ref.skip_binder(), &mut err);
@@ -758,6 +769,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
758769
return err.emit();
759770
}
760771

772+
773+
761774
err
762775
}
763776

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes
2+
//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
3+
4+
pub fn foo() -> impl std::fmt::Display {
5+
//~^ ERROR doesn't implement `std::fmt::Display`
6+
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
7+
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
8+
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
9+
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
10+
Some(Some(Some(Some(Some(Some(Some(Some(())))))))),
11+
))))))))))),
12+
))))))))))),
13+
))))))))))),
14+
)))))))))))
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0277]: `Option<Option<Option<...>>>` doesn't implement `std::fmt::Display`
2+
--> $DIR/on_unimplemented_long_types.rs:4:17
3+
|
4+
LL | pub fn foo() -> impl std::fmt::Display {
5+
| ^^^^^^^^^^^^^^^^^^^^^^ `Option<Option<Option<...>>>` cannot be formatted with the default formatter
6+
LL |
7+
LL | / Some(Some(Some(Some(Some(Some(Some(Some(Some(S...
8+
LL | | Some(Some(Some(Some(Some(Some(Some(Some(So...
9+
LL | | Some(Some(Some(Some(Some(Some(Some(Som...
10+
LL | | Some(Some(Some(Some(Some(Some(Some...
11+
... |
12+
LL | | ))))))))))),
13+
LL | | )))))))))))
14+
| |_______________- return type was inferred to be `Option<Option<Option<...>>>` here
15+
|
16+
= note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt'
17+
= note: consider using `--verbose` to print the full type name to the console
18+
= help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>`
19+
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
20+
= note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt'
21+
= note: consider using `--verbose` to print the full type name to the console
22+
23+
error: aborting due to 1 previous error
24+
25+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)