about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2022-11-15 17:38:39 -0800
committerEsteban Küber <esteban@kuber.com.ar>2022-11-18 08:42:59 -0800
commitd49c10ac62c6f781b05bb2136b63bdf7a4608439 (patch)
tree241d05c0a31daac1cc9eda82a1e8f4d7de486d5f
parentfd3bfb35511cbcff59ce1454d3db627b576d7e92 (diff)
downloadrust-d49c10ac62c6f781b05bb2136b63bdf7a4608439.tar.gz
rust-d49c10ac62c6f781b05bb2136b63bdf7a4608439.zip
Make "long type" printing type aware
Instead of simple string cutting, use a custom printer to hide parts of
long printed types.
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs57
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs19
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs23
-rw-r--r--src/test/ui/infinite/infinite-instantiation.stderr2
-rw-r--r--src/test/ui/issues/issue-22638.stderr1
-rw-r--r--src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr2
-rw-r--r--src/test/ui/issues/issue-67552.stderr2
-rw-r--r--src/test/ui/issues/issue-8727.stderr2
-rw-r--r--src/test/ui/recursion/recursion.stderr2
-rw-r--r--src/test/ui/type_length_limit.rs11
-rw-r--r--src/test/ui/type_length_limit.stderr15
12 files changed, 78 insertions, 60 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index ae0f158ede9..a792d2694b3 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -276,28 +276,45 @@ impl<'tcx> InstanceDef<'tcx> {
     }
 }
 
-impl<'tcx> fmt::Display for Instance<'tcx> {
+fn fmt_instance(
+    f: &mut fmt::Formatter<'_>,
+    instance: &Instance<'_>,
+    type_length: rustc_session::Limit,
+) -> fmt::Result {
+    ty::tls::with(|tcx| {
+        let substs = tcx.lift(instance.substs).expect("could not lift for printing");
+
+        let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
+            .print_def_path(instance.def_id(), substs)?
+            .into_buffer();
+        f.write_str(&s)
+    })?;
+
+    match instance.def {
+        InstanceDef::Item(_) => Ok(()),
+        InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
+        InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
+        InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
+        InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
+        InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
+        InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
+        InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
+        InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
+        InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
+    }
+}
+
+pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
+
+impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            let substs = tcx.lift(self.substs).expect("could not lift for printing");
-            let s = FmtPrinter::new(tcx, Namespace::ValueNS)
-                .print_def_path(self.def_id(), substs)?
-                .into_buffer();
-            f.write_str(&s)
-        })?;
+        fmt_instance(f, self.0, rustc_session::Limit(self.1))
+    }
+}
 
-        match self.def {
-            InstanceDef::Item(_) => Ok(()),
-            InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
-            InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
-            InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
-            InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
-            InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
-            InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
-            InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
-            InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
-            InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
-        }
+impl<'tcx> fmt::Display for Instance<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index f9a762261e2..a770c6a2e99 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -84,7 +84,7 @@ pub use self::context::{
     GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
     UserTypeAnnotationIndex,
 };
-pub use self::instance::{Instance, InstanceDef};
+pub use self::instance::{Instance, InstanceDef, ShortInstance};
 pub use self::list::List;
 pub use self::parameterized::ParameterizedOverTcx;
 pub use self::rvalue_scopes::RvalueScopes;
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 48e803597b0..faa57b437d9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
 use rustc_session::config::TrimmedDefPaths;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
+use rustc_session::Limit;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
@@ -1583,6 +1584,8 @@ pub struct FmtPrinterData<'a, 'tcx> {
     region_index: usize,
     binder_depth: usize,
     printed_type_count: usize,
+    type_length_limit: Limit,
+    truncated: bool,
 
     pub region_highlight_mode: RegionHighlightMode<'tcx>,
 
@@ -1605,6 +1608,10 @@ impl DerefMut for FmtPrinter<'_, '_> {
 
 impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
+        Self::new_with_limit(tcx, ns, tcx.type_length_limit())
+    }
+
+    pub fn new_with_limit(tcx: TyCtxt<'tcx>, ns: Namespace, type_length_limit: Limit) -> Self {
         FmtPrinter(Box::new(FmtPrinterData {
             tcx,
             // Estimated reasonable capacity to allocate upfront based on a few
@@ -1617,6 +1624,8 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
             region_index: 0,
             binder_depth: 0,
             printed_type_count: 0,
+            type_length_limit,
+            truncated: false,
             region_highlight_mode: RegionHighlightMode::new(tcx),
             ty_infer_name_resolver: None,
             const_infer_name_resolver: None,
@@ -1751,12 +1760,16 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
     }
 
     fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
-        let type_length_limit = self.tcx.type_length_limit();
-        if type_length_limit.value_within_limit(self.printed_type_count) {
+        if self.type_length_limit.value_within_limit(self.printed_type_count) {
             self.printed_type_count += 1;
             self.pretty_print_type(ty)
         } else {
-            write!(self, "...")?;
+            self.truncated = true;
+            if let ty::Adt(_, substs) = ty.kind() && substs.len() > 0 {
+                write!(self, "...")?;
+            } else {
+                write!(self, "_")?;
+            }
             Ok(self)
         }
     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index cdf8011d4f5..d74893bf0f0 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -197,7 +197,6 @@ use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
 use rustc_session::Limit;
 use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
 use rustc_target::abi::Size;
-use std::iter;
 use std::ops::Range;
 use std::path::PathBuf;
 
@@ -541,29 +540,23 @@ fn collect_items_rec<'tcx>(
 }
 
 /// Format instance name that is already known to be too long for rustc.
-/// Show only the first and last 32 characters to avoid blasting
+/// Show only the first 2 types if it is longer than 32 characters to avoid blasting
 /// the user's terminal with thousands of lines of type-name.
 ///
 /// If the type name is longer than before+after, it will be written to a file.
 fn shrunk_instance_name<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: &Instance<'tcx>,
-    before: usize,
-    after: usize,
 ) -> (String, Option<PathBuf>) {
     let s = instance.to_string();
 
     // Only use the shrunk version if it's really shorter.
     // This also avoids the case where before and after slices overlap.
-    if s.chars().nth(before + after + 1).is_some() {
-        // An iterator of all byte positions including the end of the string.
-        let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
-
-        let shrunk = format!(
-            "{before}...{after}",
-            before = &s[..positions().nth(before).unwrap_or(s.len())],
-            after = &s[positions().rev().nth(after).unwrap_or(0)..],
-        );
+    if s.chars().nth(33).is_some() {
+        let shrunk = format!("{}", ty::ShortInstance(instance, 4));
+        if shrunk == s {
+            return (s, None);
+        }
 
         let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
         let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
@@ -599,7 +592,7 @@ fn check_recursion_limit<'tcx>(
     if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
         let def_span = tcx.def_span(def_id);
         let def_path_str = tcx.def_path_str(def_id);
-        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
         let mut path = PathBuf::new();
         let was_written = if written_to_path.is_some() {
             path = written_to_path.unwrap();
@@ -641,7 +634,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
     //
     // Bail out in these cases to avoid that bad user experience.
     if !tcx.type_length_limit().value_within_limit(type_length) {
-        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
         let span = tcx.def_span(instance.def_id());
         let mut path = PathBuf::new();
         let was_written = if written_to_path.is_some() {
diff --git a/src/test/ui/infinite/infinite-instantiation.stderr b/src/test/ui/infinite/infinite-instantiation.stderr
index 52f5781349e..951e0f5870d 100644
--- a/src/test/ui/infinite/infinite-instantiation.stderr
+++ b/src/test/ui/infinite/infinite-instantiation.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
   --> $DIR/infinite-instantiation.rs:22:9
    |
 LL |         function(counter - 1, t.to_option());
diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr
index 1354ec8e899..1caa4221f25 100644
--- a/src/test/ui/issues/issue-22638.stderr
+++ b/src/test/ui/issues/issue-22638.stderr
@@ -9,7 +9,6 @@ note: `A::matches` defined here
    |
 LL |     pub fn matches<F: Fn()>(&self, f: &F) {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
index 93aeb89469d..6ce4c498f15 100644
--- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
+++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
+error: reached the recursion limit while instantiating `<(&(&(_, _), _), _) as Foo>::recurse`
   --> $DIR/issue-37311.rs:17:9
    |
 LL |         (self, self).recurse();
diff --git a/src/test/ui/issues/issue-67552.stderr b/src/test/ui/issues/issue-67552.stderr
index 2968be7c71f..c19c26587b9 100644
--- a/src/test/ui/issues/issue-67552.stderr
+++ b/src/test/ui/issues/issue-67552.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
+error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut _>`
   --> $DIR/issue-67552.rs:29:9
    |
 LL |         rec(identity(&mut it))
diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr
index 5e1fdad60cb..22332b35723 100644
--- a/src/test/ui/issues/issue-8727.stderr
+++ b/src/test/ui/issues/issue-8727.stderr
@@ -9,7 +9,7 @@ LL |     generic::<Option<T>>();
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
   --> $DIR/issue-8727.rs:8:5
    |
 LL |     generic::<Option<T>>();
diff --git a/src/test/ui/recursion/recursion.stderr b/src/test/ui/recursion/recursion.stderr
index d2844d0e6d9..cf08095372b 100644
--- a/src/test/ui/recursion/recursion.stderr
+++ b/src/test/ui/recursion/recursion.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
   --> $DIR/recursion.rs:18:11
    |
 LL |     _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index ce6fdf81121..b3c12747414 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -7,7 +7,7 @@
 // The exact type depends on optimizations, so disable them.
 
 #![allow(dead_code)]
-#![type_length_limit="4"]
+#![type_length_limit="8"]
 
 macro_rules! link {
     ($id:ident, $t:ty) => {
@@ -15,14 +15,19 @@ macro_rules! link {
     }
 }
 
+link! { A1, B1 }
+link! { B1, C1 }
+link! { C1, D1 }
+link! { D1, E1 }
+link! { E1, A }
 link! { A, B }
 link! { B, C }
 link! { C, D }
 link! { D, E }
 link! { E, F }
-link! { F, G }
+link! { F, G<Option<i32>, Option<i32>> }
 
-pub struct G;
+pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
 
 fn main() {
     drop::<Option<A>>(None);
diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr
index 84ac48b1e77..10ada6760eb 100644
--- a/src/test/ui/type_length_limit.stderr
+++ b/src/test/ui/type_length_limit.stderr
@@ -1,20 +1,11 @@
-error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
+error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((_, _, _), _, _), _, _), _, _)>>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
    |
 LL | pub fn drop<T>(_x: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+   = help: consider adding a `#![type_length_limit="10"]` attribute to your crate
    = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
 
-error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
-   = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error