Skip to content

Commit 787e633

Browse files
committed
On overflow errors, do not print out long types
1 parent d49c10a commit 787e633

File tree

10 files changed

+96
-27
lines changed

10 files changed

+96
-27
lines changed

compiler/rustc_middle/src/ty/error.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ use rustc_span::{BytePos, Span};
1212
use rustc_target::spec::abi;
1313

1414
use std::borrow::Cow;
15+
use std::collections::hash_map::DefaultHasher;
1516
use std::fmt;
17+
use std::hash::{Hash, Hasher};
18+
use std::path::PathBuf;
19+
20+
use super::print::PrettyPrinter;
1621

1722
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)]
1823
pub struct ExpectedFound<T> {
@@ -985,6 +990,38 @@ fn foo(&self) -> Self::T { String::new() }
985990
false
986991
}
987992

993+
pub fn short_ty_string(self, ty: Ty<'tcx>) -> Result<String, (String, PathBuf)> {
994+
let length_limit = 50;
995+
let type_limit = 4;
996+
let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS)
997+
.pretty_print_type(ty)
998+
.expect("could not write to `String`")
999+
.into_buffer();
1000+
if regular.len() <= length_limit {
1001+
return Ok(regular);
1002+
}
1003+
let short = FmtPrinter::new_with_limit(
1004+
self,
1005+
hir::def::Namespace::TypeNS,
1006+
rustc_session::Limit(type_limit),
1007+
)
1008+
.pretty_print_type(ty)
1009+
.expect("could not write to `String`")
1010+
.into_buffer();
1011+
if regular == short {
1012+
return Ok(regular);
1013+
}
1014+
// Multiple types might be shortened in a single error, ensure we create a file for each.
1015+
let mut s = DefaultHasher::new();
1016+
ty.hash(&mut s);
1017+
let hash = s.finish();
1018+
let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
1019+
match std::fs::write(&path, &regular) {
1020+
Ok(_) => Err((short, path)),
1021+
Err(_) => Ok(regular),
1022+
}
1023+
}
1024+
9881025
fn format_generic_args(self, args: &[ty::GenericArg<'tcx>]) -> String {
9891026
FmtPrinter::new(self, hir::def::Namespace::TypeNS)
9901027
.path_generic_args(Ok, args)

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,9 +2733,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
27332733
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
27342734
parent_trait_pred.remap_constness_diag(param_env);
27352735
let parent_def_id = parent_trait_pred.def_id();
2736+
let (self_ty, file) =
2737+
match self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()) {
2738+
Ok(self_ty) => (self_ty, None),
2739+
Err((self_ty, file)) => (self_ty, Some(file)),
2740+
};
27362741
let msg = format!(
2737-
"required for `{}` to implement `{}`",
2738-
parent_trait_pred.skip_binder().self_ty(),
2742+
"required for `{self_ty}` to implement `{}`",
27392743
parent_trait_pred.print_modifiers_and_trait_path()
27402744
);
27412745
let mut is_auto_trait = false;
@@ -2764,6 +2768,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
27642768
_ => err.note(&msg),
27652769
};
27662770

2771+
if let Some(file) = file {
2772+
err.note(&format!(
2773+
"the full type name has been written to '{}'",
2774+
file.display(),
2775+
));
2776+
}
27672777
let mut parent_predicate = parent_trait_pred;
27682778
let mut data = &data.derived;
27692779
let mut count = 0;
@@ -2804,11 +2814,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
28042814
count,
28052815
pluralize!(count)
28062816
));
2817+
let (self_ty, file) =
2818+
match self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()) {
2819+
Ok(self_ty) => (self_ty, None),
2820+
Err((self_ty, file)) => (self_ty, Some(file)),
2821+
};
28072822
err.note(&format!(
2808-
"required for `{}` to implement `{}`",
2809-
parent_trait_pred.skip_binder().self_ty(),
2823+
"required for `{self_ty}` to implement `{}`",
28102824
parent_trait_pred.print_modifiers_and_trait_path()
28112825
));
2826+
if let Some(file) = file {
2827+
err.note(&format!(
2828+
"the full type name has been written to '{}'",
2829+
file.display(),
2830+
));
2831+
}
28122832
}
28132833
// #74711: avoid a stack overflow
28142834
ensure_sufficient_stack(|| {

src/test/ui/error-codes/E0275.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
12
trait Foo {}
23

34
struct Bar<T>(T);

src/test/ui/error-codes/E0275.stderr

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
2-
--> $DIR/E0275.rs:5:33
2+
--> $DIR/E0275.rs:6:33
33
|
44
LL | impl<T> Foo for T where Bar<T>: Foo {}
55
| ^^^
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
8-
note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
9-
--> $DIR/E0275.rs:5:9
8+
note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo`
9+
--> $DIR/E0275.rs:6:9
1010
|
1111
LL | impl<T> Foo for T where Bar<T>: Foo {}
1212
| ^^^ ^
13+
= note: the full type name has been written to '$TEST_BUILD_DIR/error-codes/E0275/E0275.long-type-hash.txt'
1314
= note: 127 redundant requirements hidden
1415
= note: required for `Bar<T>` to implement `Foo`
1516

src/test/ui/issues/issue-20413.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
12
trait Foo {
23
fn answer(self);
34
}

0 commit comments

Comments
 (0)