Skip to content

Commit 6ca6c1a

Browse files
committed
rustc_mir: adjust the type_length_limit diagnostic to be more useful.
1 parent 3e1cef7 commit 6ca6c1a

File tree

6 files changed

+45
-25
lines changed

6 files changed

+45
-25
lines changed

src/librustc/ty/item_path.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::hir::map::DefPathData;
33
use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
44
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
55
use crate::ty::print::PrintCx;
6-
use crate::ty::subst::{Subst, Substs};
6+
use crate::ty::subst::{Subst, SubstsRef};
77
use crate::middle::cstore::{ExternCrate, ExternCrateSource};
88
use syntax::ast;
99
use syntax::symbol::{keywords, Symbol};
@@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
7979
pub fn item_path_str_with_substs_and_ns(
8080
self,
8181
def_id: DefId,
82-
substs: Option<&Substs<'tcx>>,
82+
substs: Option<SubstsRef<'tcx>>,
8383
ns: Namespace,
8484
) -> String {
8585
debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns);
@@ -116,7 +116,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
116116
pub fn default_print_item_path(
117117
&mut self,
118118
def_id: DefId,
119-
substs: Option<&Substs<'tcx>>,
119+
substs: Option<SubstsRef<'tcx>>,
120120
ns: Namespace,
121121
) -> P::Path {
122122
debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns);
@@ -169,7 +169,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
169169
fn default_print_impl_path(
170170
&mut self,
171171
impl_def_id: DefId,
172-
substs: Option<&Substs<'tcx>>,
172+
substs: Option<SubstsRef<'tcx>>,
173173
ns: Namespace,
174174
) -> P::Path {
175175
debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id);
@@ -314,15 +314,15 @@ pub trait ItemPathPrinter: Sized {
314314
fn print_item_path(
315315
self: &mut PrintCx<'_, '_, 'tcx, Self>,
316316
def_id: DefId,
317-
substs: Option<&Substs<'tcx>>,
317+
substs: Option<SubstsRef<'tcx>>,
318318
ns: Namespace,
319319
) -> Self::Path {
320320
self.default_print_item_path(def_id, substs, ns)
321321
}
322322
fn print_impl_path(
323323
self: &mut PrintCx<'_, '_, 'tcx, Self>,
324324
impl_def_id: DefId,
325-
substs: Option<&Substs<'tcx>>,
325+
substs: Option<SubstsRef<'tcx>>,
326326
ns: Namespace,
327327
) -> Self::Path {
328328
self.default_print_impl_path(impl_def_id, substs, ns)
@@ -506,7 +506,7 @@ impl ItemPathPrinter for LocalPathPrinter {
506506
fn print_item_path(
507507
self: &mut PrintCx<'_, '_, 'tcx, Self>,
508508
def_id: DefId,
509-
substs: Option<&Substs<'tcx>>,
509+
substs: Option<SubstsRef<'tcx>>,
510510
ns: Namespace,
511511
) -> Self::Path {
512512
self.try_print_visible_item_path(def_id, ns)
@@ -515,7 +515,7 @@ impl ItemPathPrinter for LocalPathPrinter {
515515
fn print_impl_path(
516516
self: &mut PrintCx<'_, '_, 'tcx, Self>,
517517
impl_def_id: DefId,
518-
substs: Option<&Substs<'tcx>>,
518+
substs: Option<SubstsRef<'tcx>>,
519519
ns: Namespace,
520520
) -> Self::Path {
521521
// Always use types for non-local impls, where types are always

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 crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod
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,
@@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
487489
// We include the const length in the type length, as it's better
488490
// to be overly conservative.
489491
if type_length + const_length > type_length_limit {
490-
// The instance name is already known to be too long for rustc. Use
491-
// `{:.64}` to avoid blasting the user's terminal with thousands of
492-
// lines of type-name.
493-
let instance_name = instance.to_string();
494-
let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
495-
instance_name);
496-
let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) {
497-
tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg)
498-
} else {
499-
tcx.sess.struct_fatal(&msg)
492+
// The instance name is already known to be too long for rustc.
493+
// Show only the first and last 32 characters to avoid blasting
494+
// the user's terminal with thousands of lines of type-name.
495+
let shrink = |s: String, before: usize, after: usize| {
496+
// An iterator of all byte positions including the end of the string.
497+
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
498+
499+
let shrunk = format!(
500+
"{before}...{after}",
501+
before = &s[..positions().nth(before).unwrap_or(s.len())],
502+
after = &s[positions().rev().nth(after).unwrap_or(0)..],
503+
);
504+
505+
// Only use the shrunk version if it's really shorter.
506+
// This also avoids the case where before and after slices overlap.
507+
if shrunk.len() < s.len() {
508+
shrunk
509+
} else {
510+
s
511+
}
500512
};
501-
513+
let msg = format!("reached the type-length limit while instantiating `{}`",
514+
shrink(instance.to_string(), 32, 32));
515+
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
502516
diag.note(&format!(
503517
"consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
504-
type_length_limit * 2));
518+
type_length));
505519
diag.emit();
506520
tcx.sess.abort_if_errors();
507521
}

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) {
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.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-musl
2+
// ignore-x86
13
// error-pattern: reached the type-length limit while instantiating
24

35
// Test that the type length limit can be changed.

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)