diff options
| author | bors <bors@rust-lang.org> | 2020-09-21 08:20:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-09-21 08:20:38 +0000 |
| commit | 0433fdf93b0346e136c03ed49c0e90346035f191 (patch) | |
| tree | 7b4a9c6fc8b3e17d0cab3e2dc4e2aff81b5669ec | |
| parent | a409a233e02b1864d1b76495a1f946bb56c7aeb2 (diff) | |
| parent | 34d3c7df80dc687e184d8bfa456e851cad9839de (diff) | |
| download | rust-0433fdf93b0346e136c03ed49c0e90346035f191.tar.gz rust-0433fdf93b0346e136c03ed49c0e90346035f191.zip | |
Auto merge of #76843 - kornelski:longtypetofile, r=ecstatic-morse
Let user see the full type of type-length limit error Seeing the full type of the error is sometimes essential to diagnosing the problem, but the type itself is too long to be displayed in the terminal in a useful fashion. This change solves this dilemma by writing the full offending type name to a file, and displays this filename as a note. > note: the full type name been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt' Closes #76777
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/collector.rs | 66 | ||||
| -rw-r--r-- | src/test/ui/infinite/infinite-instantiation.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/infinite/infinite-instantiation.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-22638.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-22638.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-67552.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-67552.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-8727.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-8727.stderr | 7 | ||||
| -rw-r--r-- | src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr | 1 | ||||
| -rw-r--r-- | src/test/ui/recursion/recursion.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/recursion/recursion.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/type_length_limit.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/type_length_limit.stderr | 3 |
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 |
