Skip to content

Commit d49c10a

Browse files
committed
Make "long type" printing type aware
Instead of simple string cutting, use a custom printer to hide parts of long printed types.
1 parent fd3bfb3 commit d49c10a

File tree

12 files changed

+78
-60
lines changed

12 files changed

+78
-60
lines changed

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -276,28 +276,45 @@ impl<'tcx> InstanceDef<'tcx> {
276276
}
277277
}
278278

279-
impl<'tcx> fmt::Display for Instance<'tcx> {
279+
fn fmt_instance(
280+
f: &mut fmt::Formatter<'_>,
281+
instance: &Instance<'_>,
282+
type_length: rustc_session::Limit,
283+
) -> fmt::Result {
284+
ty::tls::with(|tcx| {
285+
let substs = tcx.lift(instance.substs).expect("could not lift for printing");
286+
287+
let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
288+
.print_def_path(instance.def_id(), substs)?
289+
.into_buffer();
290+
f.write_str(&s)
291+
})?;
292+
293+
match instance.def {
294+
InstanceDef::Item(_) => Ok(()),
295+
InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
296+
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
297+
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
298+
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
299+
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
300+
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
301+
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
302+
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
303+
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
304+
}
305+
}
306+
307+
pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
308+
309+
impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
280310
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281-
ty::tls::with(|tcx| {
282-
let substs = tcx.lift(self.substs).expect("could not lift for printing");
283-
let s = FmtPrinter::new(tcx, Namespace::ValueNS)
284-
.print_def_path(self.def_id(), substs)?
285-
.into_buffer();
286-
f.write_str(&s)
287-
})?;
311+
fmt_instance(f, self.0, rustc_session::Limit(self.1))
312+
}
313+
}
288314

289-
match self.def {
290-
InstanceDef::Item(_) => Ok(()),
291-
InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
292-
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
293-
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
294-
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
295-
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
296-
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
297-
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
298-
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
299-
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
300-
}
315+
impl<'tcx> fmt::Display for Instance<'tcx> {
316+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317+
ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
301318
}
302319
}
303320

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub use self::context::{
8484
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
8585
UserTypeAnnotationIndex,
8686
};
87-
pub use self::instance::{Instance, InstanceDef};
87+
pub use self::instance::{Instance, InstanceDef, ShortInstance};
8888
pub use self::list::List;
8989
pub use self::parameterized::ParameterizedOverTcx;
9090
pub use self::rvalue_scopes::RvalueScopes;

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE};
1313
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
1414
use rustc_session::config::TrimmedDefPaths;
1515
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
16+
use rustc_session::Limit;
1617
use rustc_span::symbol::{kw, Ident, Symbol};
1718
use rustc_target::abi::Size;
1819
use rustc_target::spec::abi::Abi;
@@ -1583,6 +1584,8 @@ pub struct FmtPrinterData<'a, 'tcx> {
15831584
region_index: usize,
15841585
binder_depth: usize,
15851586
printed_type_count: usize,
1587+
type_length_limit: Limit,
1588+
truncated: bool,
15861589

15871590
pub region_highlight_mode: RegionHighlightMode<'tcx>,
15881591

@@ -1605,6 +1608,10 @@ impl DerefMut for FmtPrinter<'_, '_> {
16051608

16061609
impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
16071610
pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
1611+
Self::new_with_limit(tcx, ns, tcx.type_length_limit())
1612+
}
1613+
1614+
pub fn new_with_limit(tcx: TyCtxt<'tcx>, ns: Namespace, type_length_limit: Limit) -> Self {
16081615
FmtPrinter(Box::new(FmtPrinterData {
16091616
tcx,
16101617
// Estimated reasonable capacity to allocate upfront based on a few
@@ -1617,6 +1624,8 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
16171624
region_index: 0,
16181625
binder_depth: 0,
16191626
printed_type_count: 0,
1627+
type_length_limit,
1628+
truncated: false,
16201629
region_highlight_mode: RegionHighlightMode::new(tcx),
16211630
ty_infer_name_resolver: None,
16221631
const_infer_name_resolver: None,
@@ -1751,12 +1760,16 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
17511760
}
17521761

17531762
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1754-
let type_length_limit = self.tcx.type_length_limit();
1755-
if type_length_limit.value_within_limit(self.printed_type_count) {
1763+
if self.type_length_limit.value_within_limit(self.printed_type_count) {
17561764
self.printed_type_count += 1;
17571765
self.pretty_print_type(ty)
17581766
} else {
1759-
write!(self, "...")?;
1767+
self.truncated = true;
1768+
if let ty::Adt(_, substs) = ty.kind() && substs.len() > 0 {
1769+
write!(self, "...")?;
1770+
} else {
1771+
write!(self, "_")?;
1772+
}
17601773
Ok(self)
17611774
}
17621775
}

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
197197
use rustc_session::Limit;
198198
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
199199
use rustc_target::abi::Size;
200-
use std::iter;
201200
use std::ops::Range;
202201
use std::path::PathBuf;
203202

@@ -541,29 +540,23 @@ fn collect_items_rec<'tcx>(
541540
}
542541

543542
/// Format instance name that is already known to be too long for rustc.
544-
/// Show only the first and last 32 characters to avoid blasting
543+
/// Show only the first 2 types if it is longer than 32 characters to avoid blasting
545544
/// the user's terminal with thousands of lines of type-name.
546545
///
547546
/// If the type name is longer than before+after, it will be written to a file.
548547
fn shrunk_instance_name<'tcx>(
549548
tcx: TyCtxt<'tcx>,
550549
instance: &Instance<'tcx>,
551-
before: usize,
552-
after: usize,
553550
) -> (String, Option<PathBuf>) {
554551
let s = instance.to_string();
555552

556553
// Only use the shrunk version if it's really shorter.
557554
// This also avoids the case where before and after slices overlap.
558-
if s.chars().nth(before + after + 1).is_some() {
559-
// An iterator of all byte positions including the end of the string.
560-
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
561-
562-
let shrunk = format!(
563-
"{before}...{after}",
564-
before = &s[..positions().nth(before).unwrap_or(s.len())],
565-
after = &s[positions().rev().nth(after).unwrap_or(0)..],
566-
);
555+
if s.chars().nth(33).is_some() {
556+
let shrunk = format!("{}", ty::ShortInstance(instance, 4));
557+
if shrunk == s {
558+
return (s, None);
559+
}
567560

568561
let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
569562
let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
@@ -599,7 +592,7 @@ fn check_recursion_limit<'tcx>(
599592
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
600593
let def_span = tcx.def_span(def_id);
601594
let def_path_str = tcx.def_path_str(def_id);
602-
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
595+
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
603596
let mut path = PathBuf::new();
604597
let was_written = if written_to_path.is_some() {
605598
path = written_to_path.unwrap();
@@ -641,7 +634,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
641634
//
642635
// Bail out in these cases to avoid that bad user experience.
643636
if !tcx.type_length_limit().value_within_limit(type_length) {
644-
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
637+
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
645638
let span = tcx.def_span(instance.def_id());
646639
let mut path = PathBuf::new();
647640
let was_written = if written_to_path.is_some() {

src/test/ui/infinite/infinite-instantiation.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
1+
error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
22
--> $DIR/infinite-instantiation.rs:22:9
33
|
44
LL | function(counter - 1, t.to_option());

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ note: `A::matches` defined here
99
|
1010
LL | pub fn matches<F: Fn()>(&self, f: &F) {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
= note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt'
1312

1413
error: aborting due to previous error
1514

src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
1+
error: reached the recursion limit while instantiating `<(&(&(_, _), _), _) as Foo>::recurse`
22
--> $DIR/issue-37311.rs:17:9
33
|
44
LL | (self, self).recurse();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
1+
error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut _>`
22
--> $DIR/issue-67552.rs:29:9
33
|
44
LL | rec(identity(&mut it))

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | generic::<Option<T>>();
99
= help: a `loop` may express intention better if this is on purpose
1010
= note: `#[warn(unconditional_recursion)]` on by default
1111

12-
error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
12+
error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
1313
--> $DIR/issue-8727.rs:8:5
1414
|
1515
LL | generic::<Option<T>>();

src/test/ui/recursion/recursion.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
1+
error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
22
--> $DIR/recursion.rs:18:11
33
|
44
LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}

src/test/ui/type_length_limit.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,27 @@
77
// The exact type depends on optimizations, so disable them.
88

99
#![allow(dead_code)]
10-
#![type_length_limit="4"]
10+
#![type_length_limit="8"]
1111

1212
macro_rules! link {
1313
($id:ident, $t:ty) => {
1414
pub type $id = ($t, $t, $t);
1515
}
1616
}
1717

18+
link! { A1, B1 }
19+
link! { B1, C1 }
20+
link! { C1, D1 }
21+
link! { D1, E1 }
22+
link! { E1, A }
1823
link! { A, B }
1924
link! { B, C }
2025
link! { C, D }
2126
link! { D, E }
2227
link! { E, F }
23-
link! { F, G }
28+
link! { F, G<Option<i32>, Option<i32>> }
2429

25-
pub struct G;
30+
pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
2631

2732
fn main() {
2833
drop::<Option<A>>(None);

src/test/ui/type_length_limit.stderr

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
1-
error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
1+
error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((_, _, _), _, _), _, _), _, _)>>`
22
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
33
|
44
LL | pub fn drop<T>(_x: T) {}
55
| ^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: consider adding a `#![type_length_limit="8"]` attribute to your crate
7+
= help: consider adding a `#![type_length_limit="10"]` attribute to your crate
88
= note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
99

10-
error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
11-
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
12-
|
13-
LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
|
16-
= help: consider adding a `#![type_length_limit="8"]` attribute to your crate
17-
= note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
18-
19-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
2011

0 commit comments

Comments
 (0)