about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKornel Lesiński <kornel@geekhood.net>2020-09-16 03:45:58 +0100
committerKornel Lesiński <kornel@geekhood.net>2020-09-21 00:39:58 +0100
commit34d3c7df80dc687e184d8bfa456e851cad9839de (patch)
tree1b259a384b93394274c9e078f345ad23ddf29a29
parent1fd5b9d516c035a898dcb437b2f982bea5d4bc88 (diff)
downloadrust-34d3c7df80dc687e184d8bfa456e851cad9839de.tar.gz
rust-34d3c7df80dc687e184d8bfa456e851cad9839de.zip
Let user see the full type of type-length limit error
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs66
-rw-r--r--src/test/ui/infinite/infinite-instantiation.rs1
-rw-r--r--src/test/ui/infinite/infinite-instantiation.stderr5
-rw-r--r--src/test/ui/issues/issue-22638.rs1
-rw-r--r--src/test/ui/issues/issue-22638.stderr5
-rw-r--r--src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs1
-rw-r--r--src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr5
-rw-r--r--src/test/ui/issues/issue-67552.rs1
-rw-r--r--src/test/ui/issues/issue-67552.stderr5
-rw-r--r--src/test/ui/issues/issue-8727.rs1
-rw-r--r--src/test/ui/issues/issue-8727.stderr7
-rw-r--r--src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs2
-rw-r--r--src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr1
-rw-r--r--src/test/ui/recursion/recursion.rs1
-rw-r--r--src/test/ui/recursion/recursion.stderr5
-rw-r--r--src/test/ui/type_length_limit.rs1
-rw-r--r--src/test/ui/type_length_limit.stderr3
17 files changed, 71 insertions, 40 deletions
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index 4ef871b05f4..7e12cc9176e 100644
--- a/compiler/rustc_mir/src/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -197,6 +197,7 @@ use rustc_session::config::EntryFnType;
 use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
 use smallvec::SmallVec;
 use std::iter;
+use std::path::PathBuf;
 
 #[derive(PartialEq)]
 pub enum MonoItemCollectionMode {
@@ -420,27 +421,38 @@ fn record_accesses<'a, 'tcx: 'a>(
     inlining_map.lock_mut().record_accesses(caller, &accesses);
 }
 
-// Shrinks string by keeping prefix and suffix of given sizes.
-fn shrink(s: String, before: usize, after: usize) -> String {
-    // 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)..],
-    );
+/// Format instance name that is already known to be too long for rustc.
+/// Show only the first and last 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: 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 shrunk.len() < s.len() { shrunk } else { s }
-}
+    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)..],
+        );
+
+        let path = tcx.output_filenames(LOCAL_CRATE).temp_path_ext("long-type.txt", None);
+        let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
 
-// Format instance name that is already known to be too long for rustc.
-// Show only the first and last 32 characters to avoid blasting
-// the user's terminal with thousands of lines of type-name.
-fn shrunk_instance_name(instance: &Instance<'tcx>) -> String {
-    shrink(instance.to_string(), 32, 32)
+        (shrunk, written_to_path)
+    } else {
+        (s, None)
+    }
 }
 
 fn check_recursion_limit<'tcx>(
@@ -465,15 +477,16 @@ fn check_recursion_limit<'tcx>(
     // more than the recursion limit is assumed to be causing an
     // infinite expansion.
     if !tcx.sess.recursion_limit().value_within_limit(adjusted_recursion_depth) {
-        let error = format!(
-            "reached the recursion limit while instantiating `{}`",
-            shrunk_instance_name(&instance),
-        );
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let error = format!("reached the recursion limit while instantiating `{}`", shrunk);
         let mut err = tcx.sess.struct_span_fatal(span, &error);
         err.span_note(
             tcx.def_span(def_id),
             &format!("`{}` defined here", tcx.def_path_str(def_id)),
         );
+        if let Some(path) = written_to_path {
+            err.note(&format!("the full type name has been written to '{}'", path.display()));
+        }
         err.emit();
         FatalError.raise();
     }
@@ -502,12 +515,13 @@ 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.sess.type_length_limit().value_within_limit(type_length) {
-        let msg = format!(
-            "reached the type-length limit while instantiating `{}`",
-            shrunk_instance_name(&instance),
-        );
+        let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+        let msg = format!("reached the type-length limit while instantiating `{}`", shrunk);
         let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
-        diag.note(&format!(
+        if let Some(path) = written_to_path {
+            diag.note(&format!("the full type name has been written to '{}'", path.display()));
+        }
+        diag.help(&format!(
             "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
             type_length
         ));
diff --git a/src/test/ui/infinite/infinite-instantiation.rs b/src/test/ui/infinite/infinite-instantiation.rs
index cb3550cf66b..9b9f332ca86 100644
--- a/src/test/ui/infinite/infinite-instantiation.rs
+++ b/src/test/ui/infinite/infinite-instantiation.rs
@@ -1,4 +1,5 @@
 // build-fail
+// normalize-stderr-test: ".nll/" -> "/"
 
 trait ToOpt: Sized {
     fn to_option(&self) -> Option<Self>;
diff --git a/src/test/ui/infinite/infinite-instantiation.stderr b/src/test/ui/infinite/infinite-instantiation.stderr
index d27d14842ce..52f5781349e 100644
--- a/src/test/ui/infinite/infinite-instantiation.stderr
+++ b/src/test/ui/infinite/infinite-instantiation.stderr
@@ -1,14 +1,15 @@
 error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/infinite-instantiation.rs:21:9
+  --> $DIR/infinite-instantiation.rs:22:9
    |
 LL |         function(counter - 1, t.to_option());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `function` defined here
-  --> $DIR/infinite-instantiation.rs:19:1
+  --> $DIR/infinite-instantiation.rs:20:1
    |
 LL | fn function<T:ToOpt + Clone>(counter: usize, t: T) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation/infinite-instantiation.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-22638.rs b/src/test/ui/issues/issue-22638.rs
index 89137538425..198ceccc2c3 100644
--- a/src/test/ui/issues/issue-22638.rs
+++ b/src/test/ui/issues/issue-22638.rs
@@ -1,5 +1,6 @@
 // build-fail
 // normalize-stderr-test: "<\[closure@.+`" -> "$$CLOSURE`"
+// normalize-stderr-test: ".nll/" -> "/"
 
 #![allow(unused)]
 
diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr
index c4255b95b70..1354ec8e899 100644
--- a/src/test/ui/issues/issue-22638.stderr
+++ b/src/test/ui/issues/issue-22638.stderr
@@ -1,14 +1,15 @@
 error: reached the recursion limit while instantiating `A::matches::$CLOSURE`
-  --> $DIR/issue-22638.rs:55:9
+  --> $DIR/issue-22638.rs:56:9
    |
 LL |         a.matches(f)
    |         ^^^^^^^^^^^^
    |
 note: `A::matches` defined here
-  --> $DIR/issue-22638.rs:14:5
+  --> $DIR/issue-22638.rs:15:5
    |
 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.rs b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs
index d3d5863ddb3..50d1f166c98 100644
--- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs
+++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs
@@ -1,4 +1,5 @@
 // build-fail
+// normalize-stderr-test: ".nll/" -> "/"
 
 trait Mirror {
     type Image;
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 a94f190d6b2..93aeb89469d 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,14 +1,15 @@
 error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
-  --> $DIR/issue-37311.rs:16:9
+  --> $DIR/issue-37311.rs:17:9
    |
 LL |         (self, self).recurse();
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `<T as Foo>::recurse` defined here
-  --> $DIR/issue-37311.rs:15:5
+  --> $DIR/issue-37311.rs:16:5
    |
 LL |     fn recurse(&self) {
    |     ^^^^^^^^^^^^^^^^^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-37311-type-length-limit/issue-37311/issue-37311.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-67552.rs b/src/test/ui/issues/issue-67552.rs
index b0fcb74764b..98192dae20d 100644
--- a/src/test/ui/issues/issue-67552.rs
+++ b/src/test/ui/issues/issue-67552.rs
@@ -1,4 +1,5 @@
 // build-fail
+// normalize-stderr-test: ".nll/" -> "/"
 
 fn main() {
     rec(Empty);
diff --git a/src/test/ui/issues/issue-67552.stderr b/src/test/ui/issues/issue-67552.stderr
index f3e73399b57..cf05a72e921 100644
--- a/src/test/ui/issues/issue-67552.stderr
+++ b/src/test/ui/issues/issue-67552.stderr
@@ -1,16 +1,17 @@
 error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
-  --> $DIR/issue-67552.rs:27:9
+  --> $DIR/issue-67552.rs:28:9
    |
 LL |         rec(identity(&mut it))
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `rec` defined here
-  --> $DIR/issue-67552.rs:20:1
+  --> $DIR/issue-67552.rs:21:1
    |
 LL | / fn rec<T>(mut it: T)
 LL | | where
 LL | |     T: Iterator,
    | |________________^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-67552/issue-67552.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-8727.rs b/src/test/ui/issues/issue-8727.rs
index 01b3bc582f7..a9b8126618f 100644
--- a/src/test/ui/issues/issue-8727.rs
+++ b/src/test/ui/issues/issue-8727.rs
@@ -2,6 +2,7 @@
 // recursions.
 
 // build-fail
+// normalize-stderr-test: ".nll/" -> "/"
 
 fn generic<T>() { //~ WARN function cannot return without recursing
     generic::<Option<T>>();
diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr
index 279e3ffbb4a..10daba5ef3d 100644
--- a/src/test/ui/issues/issue-8727.stderr
+++ b/src/test/ui/issues/issue-8727.stderr
@@ -1,5 +1,5 @@
 warning: function cannot return without recursing
-  --> $DIR/issue-8727.rs:6:1
+  --> $DIR/issue-8727.rs:7:1
    |
 LL | fn generic<T>() {
    | ^^^^^^^^^^^^^^^ cannot return without recursing
@@ -10,16 +10,17 @@ LL |     generic::<Option<T>>();
    = help: a `loop` may express intention better if this is on purpose
 
 error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/issue-8727.rs:7:5
+  --> $DIR/issue-8727.rs:8:5
    |
 LL |     generic::<Option<T>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `generic` defined here
-  --> $DIR/issue-8727.rs:6:1
+  --> $DIR/issue-8727.rs:7:1
    |
 LL | fn generic<T>() {
    | ^^^^^^^^^^^^^^^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-8727/issue-8727.long-type.txt'
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
index d9996b80ac0..658def0ad5a 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
@@ -2,7 +2,9 @@
 // no free regions or type parameters.
 // Codegen however, has to error for the infinitely many `drop_in_place`
 // functions it has been asked to create.
+
 // build-fail
+// normalize-stderr-test: ".nll/" -> "/"
 
 struct S<T> {
     t: T,
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
index 4d77b3d295c..3efe13b3de3 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
@@ -21,6 +21,7 @@ LL | |     // SAFETY: see comment above
 LL | |     unsafe { drop_in_place(to_drop) }
 LL | | }
    | |_^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-38591-non-regular-dropck-recursion/issue-38591-non-regular-dropck-recursion.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion/recursion.rs b/src/test/ui/recursion/recursion.rs
index 373cc17d0e0..b3ba0ec3a2a 100644
--- a/src/test/ui/recursion/recursion.rs
+++ b/src/test/ui/recursion/recursion.rs
@@ -1,5 +1,6 @@
 // build-fail
 // compile-flags:-C overflow-checks=off
+// normalize-stderr-test: ".nll/" -> "/"
 
 enum Nil {NilValue}
 struct Cons<T> {head:isize, tail:T}
diff --git a/src/test/ui/recursion/recursion.stderr b/src/test/ui/recursion/recursion.stderr
index 085bf82ef8b..d2844d0e6d9 100644
--- a/src/test/ui/recursion/recursion.stderr
+++ b/src/test/ui/recursion/recursion.stderr
@@ -1,14 +1,15 @@
 error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/recursion.rs:17:11
+  --> $DIR/recursion.rs:18:11
    |
 LL |     _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `test` defined here
-  --> $DIR/recursion.rs:15:1
+  --> $DIR/recursion.rs:16:1
    |
 LL | fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/recursion/recursion.long-type.txt'
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index 921cded5037..c1f3acbecf9 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -1,5 +1,6 @@
 // build-fail
 // error-pattern: reached the type-length limit while instantiating
+// normalize-stderr-test: ".nll/" -> "/"
 
 // Test that the type length limit can be changed.
 
diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr
index cf3d64d734b..1c0a596a64c 100644
--- a/src/test/ui/type_length_limit.stderr
+++ b/src/test/ui/type_length_limit.stderr
@@ -4,7 +4,8 @@ error: reached the type-length limit while instantiating `std::mem::drop::<Optio
 LL | pub fn drop<T>(_x: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: 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'
+   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
 
 error: aborting due to previous error