Skip to content

Commit 4e280d9

Browse files
committed
rustc_mir: adjust the type_length_limit diagnostic to be more useful.
1 parent e2ac949 commit 4e280d9

File tree

4 files changed

+35
-17
lines changed

4 files changed

+35
-17
lines changed

src/librustc_mir/monomorphize/collector.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode};
198198
use rustc_data_structures::bit_set::GrowableBitSet;
199199
use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter};
200200

201+
use std::iter;
202+
201203
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
202204
pub enum MonoItemCollectionMode {
203205
Eager,
@@ -476,21 +478,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
476478
// Bail out in these cases to avoid that bad user experience.
477479
let type_length_limit = *tcx.sess.type_length_limit.get();
478480
if type_length > type_length_limit {
479-
// The instance name is already known to be too long for rustc. Use
480-
// `{:.64}` to avoid blasting the user's terminal with thousands of
481-
// lines of type-name.
482-
let instance_name = instance.to_string();
483-
let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
484-
instance_name);
485-
let mut diag = if let Some(node_id) = tcx.hir().as_local_node_id(instance.def_id()) {
486-
tcx.sess.struct_span_fatal(tcx.hir().span(node_id), &msg)
487-
} else {
488-
tcx.sess.struct_fatal(&msg)
481+
// The instance name is already known to be too long for rustc.
482+
// Show only the first and last 32 characters to avoid blasting
483+
// the user's terminal with thousands of lines of type-name.
484+
let shrink = |s: String, before: usize, after: usize| {
485+
// An iterator of all byte positions including the end of the string.
486+
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
487+
488+
let shrunk = format!(
489+
"{before}...{after}",
490+
before = &s[..positions().nth(before).unwrap_or(s.len())],
491+
after = &s[positions().rev().nth(after).unwrap_or(0)..],
492+
);
493+
494+
// Only use the shrunk version if it's really shorter.
495+
// This also avoids the case where before and after slices overlap.
496+
if shrunk.len() < s.len() {
497+
shrunk
498+
} else {
499+
s
500+
}
489501
};
490-
502+
let msg = format!("reached the type-length limit while instantiating `{}`",
503+
shrink(instance.to_string(), 32, 32));
504+
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
491505
diag.note(&format!(
492506
"consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
493-
type_length_limit*2));
507+
type_length));
494508
diag.emit();
495509
tcx.sess.abort_if_errors();
496510
}

src/test/ui/issues/issue-22638.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | | a.matches(f)
88
LL | | }
99
| |_____^
1010
|
11-
= note: consider adding a `#![type_length_limit="40000000"]` attribute to your crate
11+
= note: consider adding a `#![type_length_limit="26214380"]` attribute to your crate
1212

1313
error: aborting due to previous error
1414

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&(), &())), &...`
1+
error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse`
22
--> $DIR/issue-37311.rs:13:5
33
|
44
LL | / fn recurse(&self) { //~ ERROR reached the type-length limit
55
LL | | (self, self).recurse();
66
LL | | }
77
| |_____^
88
|
9-
= note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate
9+
= note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate
1010

1111
error: aborting due to previous error
1212

src/test/ui/type_length_limit.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Option<((((((G, G, G), (G, G, G), ...`
1+
error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Op... G), (G, G, G), (G, G, G))))))>>`
2+
--> $SRC_DIR/libcore/mem.rs:LL:COL
23
|
3-
= note: consider adding a `#![type_length_limit="512"]` attribute to your crate
4+
LL | pub fn drop<T>(_x: T) { }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: consider adding a `#![type_length_limit="1094"]` attribute to your crate
48

59
error: aborting due to previous error
610

0 commit comments

Comments
 (0)