1
Fork 0

Rollup merge of #104922 - estebank:fur-elize, r=oli-obk

Detect long types in E0308 and write them to disk

On type error with long types, print an abridged type and write the full type to disk.

Print the widest possible short type while still fitting in the terminal.
This commit is contained in:
Matthias Krüger 2022-12-08 12:57:28 +01:00 committed by GitHub
commit 086bdbbd73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 316 additions and 101 deletions

View file

@ -4348,6 +4348,7 @@ dependencies = [
"rustc_span", "rustc_span",
"rustc_target", "rustc_target",
"smallvec", "smallvec",
"termize",
"tracing", "tracing",
"winapi", "winapi",
] ]

View file

@ -80,6 +80,7 @@ use rustc_middle::ty::{
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi; use rustc_target::spec::abi;
use std::ops::{ControlFlow, Deref}; use std::ops::{ControlFlow, Deref};
use std::path::PathBuf;
use std::{cmp, fmt, iter}; use std::{cmp, fmt, iter};
mod note; mod note;
@ -1352,10 +1353,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.map(|(mod_str, _)| mod_str.len() + separator_len) .map(|(mod_str, _)| mod_str.len() + separator_len)
.sum(); .sum();
debug!( debug!(?separator_len, ?split_idx, ?min_len, "cmp");
"cmp: separator_len={}, split_idx={}, min_len={}",
separator_len, split_idx, min_len
);
if split_idx >= min_len { if split_idx >= min_len {
// paths are identical, highlight everything // paths are identical, highlight everything
@ -1366,7 +1364,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} else { } else {
let (common, uniq1) = t1_str.split_at(split_idx); let (common, uniq1) = t1_str.split_at(split_idx);
let (_, uniq2) = t2_str.split_at(split_idx); let (_, uniq2) = t2_str.split_at(split_idx);
debug!("cmp: common={}, uniq1={}, uniq2={}", common, uniq1, uniq2); debug!(?common, ?uniq1, ?uniq2, "cmp");
values.0.push_normal(common); values.0.push_normal(common);
values.0.push_highlighted(uniq1); values.0.push_highlighted(uniq1);
@ -1659,17 +1657,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")), ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
}; };
let vals = match self.values_str(values) { let Some(vals) = self.values_str(values) else {
Some((expected, found)) => Some((expected, found)),
None => {
// Derived error. Cancel the emitter. // Derived error. Cancel the emitter.
// NOTE(eddyb) this was `.cancel()`, but `diag` // NOTE(eddyb) this was `.cancel()`, but `diag`
// is borrowed, so we can't fully defuse it. // is borrowed, so we can't fully defuse it.
diag.downgrade_to_delayed_bug(); diag.downgrade_to_delayed_bug();
return; return;
}
}; };
(vals, exp_found, is_simple_error, Some(values)) (Some(vals), exp_found, is_simple_error, Some(values))
} }
}; };
@ -1701,7 +1696,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
label_or_note(span, &terr.to_string()); label_or_note(span, &terr.to_string());
} }
if let Some((expected, found)) = expected_found { if let Some((expected, found, exp_p, found_p)) = expected_found {
let (expected_label, found_label, exp_found) = match exp_found { let (expected_label, found_label, exp_found) = match exp_found {
Mismatch::Variable(ef) => ( Mismatch::Variable(ef) => (
ef.expected.prefix_string(self.tcx), ef.expected.prefix_string(self.tcx),
@ -1818,7 +1813,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
TypeError::Sorts(values) => { TypeError::Sorts(values) => {
let extra = expected == found; let extra = expected == found;
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) { let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
let mut s = match (extra, ty.kind()) {
(true, ty::Opaque(def_id, _)) => { (true, ty::Opaque(def_id, _)) => {
let sm = self.tcx.sess.source_map(); let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
@ -1845,6 +1841,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(true, _) => format!(" ({})", ty.sort_string(self.tcx)), (true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(), (false, _) => "".to_string(),
}; };
if let Some(path) = path {
s.push_str(&format!(
"\nthe full type name has been written to '{}'",
path.display(),
));
}
s
};
if !(values.expected.is_simple_text() && values.found.is_simple_text()) if !(values.expected.is_simple_text() && values.found.is_simple_text())
|| (exp_found.map_or(false, |ef| { || (exp_found.map_or(false, |ef| {
// This happens when the type error is a subset of the expectation, // This happens when the type error is a subset of the expectation,
@ -1865,8 +1869,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected, expected,
&found_label, &found_label,
found, found,
&sort_string(values.expected), &sort_string(values.expected, exp_p),
&sort_string(values.found), &sort_string(values.found, found_p),
); );
} }
} }
@ -2339,7 +2343,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let code = trace.cause.code(); let code = trace.cause.code();
if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code
&& let hir::MatchSource::TryDesugar = source && let hir::MatchSource::TryDesugar = source
&& let Some((expected_ty, found_ty)) = self.values_str(trace.values) && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
{ {
err.note(&format!( err.note(&format!(
"`?` operator cannot convert from `{}` to `{}`", "`?` operator cannot convert from `{}` to `{}`",
@ -2455,7 +2459,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn values_str( fn values_str(
&self, &self,
values: ValuePairs<'tcx>, values: ValuePairs<'tcx>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
match values { match values {
infer::Regions(exp_found) => self.expected_found_str(exp_found), infer::Regions(exp_found) => self.expected_found_str(exp_found),
infer::Terms(exp_found) => self.expected_found_str_term(exp_found), infer::Terms(exp_found) => self.expected_found_str_term(exp_found),
@ -2465,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found: exp_found.found.print_only_trait_path(), found: exp_found.found.print_only_trait_path(),
}; };
match self.expected_found_str(pretty_exp_found) { match self.expected_found_str(pretty_exp_found) {
Some((expected, found)) if expected == found => { Some((expected, found, _, _)) if expected == found => {
self.expected_found_str(exp_found) self.expected_found_str(exp_found)
} }
ret => ret, ret => ret,
@ -2477,7 +2482,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found: exp_found.found.print_only_trait_path(), found: exp_found.found.print_only_trait_path(),
}; };
match self.expected_found_str(pretty_exp_found) { match self.expected_found_str(pretty_exp_found) {
Some((expected, found)) if expected == found => { Some((expected, found, _, _)) if expected == found => {
self.expected_found_str(exp_found) self.expected_found_str(exp_found)
} }
ret => ret, ret => ret,
@ -2489,17 +2494,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn expected_found_str_term( fn expected_found_str_term(
&self, &self,
exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>, exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
let exp_found = self.resolve_vars_if_possible(exp_found); let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() { if exp_found.references_error() {
return None; return None;
} }
Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) { Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found), (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
let (mut exp, mut fnd) = self.cmp(expected, found);
// Use the terminal width as the basis to determine when to compress the printed
// out type, but give ourselves some leeway to avoid ending up creating a file for
// a type that is somewhat shorter than the path we'd write to.
let len = self.tcx.sess().diagnostic_width() + 40;
let exp_s = exp.content();
let fnd_s = fnd.content();
let mut exp_p = None;
let mut fnd_p = None;
if exp_s.len() > len {
let (exp_s, exp_path) = self.tcx.short_ty_string(expected);
exp = DiagnosticStyledString::highlighted(exp_s);
exp_p = exp_path;
}
if fnd_s.len() > len {
let (fnd_s, fnd_path) = self.tcx.short_ty_string(found);
fnd = DiagnosticStyledString::highlighted(fnd_s);
fnd_p = fnd_path;
}
(exp, fnd, exp_p, fnd_p)
}
_ => ( _ => (
DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
), ),
}) })
} }
@ -2508,7 +2537,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>( fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>(
&self, &self,
exp_found: ty::error::ExpectedFound<T>, exp_found: ty::error::ExpectedFound<T>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
let exp_found = self.resolve_vars_if_possible(exp_found); let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() { if exp_found.references_error() {
return None; return None;
@ -2517,6 +2547,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
Some(( Some((
DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
)) ))
} }
@ -2850,18 +2882,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
debug!("report_sub_sup_conflict: sup_region={:?}", sup_region); debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin); debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) = if let infer::Subtype(ref sup_trace) = sup_origin
(&sup_origin, &sub_origin) && let infer::Subtype(ref sub_trace) = sub_origin
&& let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values)
&& let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values)
&& sub_expected == sup_expected
&& sub_found == sup_found
{ {
debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
debug!("report_sub_sup_conflict: sub_trace.values={:?}", sub_trace.values);
if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) =
(self.values_str(sup_trace.values), self.values_str(sub_trace.values))
{
if sub_expected == sup_expected && sub_found == sup_found {
note_and_explain_region( note_and_explain_region(
self.tcx, self.tcx,
&mut err, &mut err,
@ -2879,8 +2906,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.emit(); err.emit();
return; return;
} }
}
}
self.note_region_origin(&mut err, &sup_origin); self.note_region_origin(&mut err, &sup_origin);

View file

@ -16,7 +16,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
span: trace.cause.span, span: trace.cause.span,
requirement: ObligationCauseAsDiagArg(trace.cause.clone()), requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
expected_found: self.values_str(trace.values), expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)),
} }
.add_to_diagnostic(err), .add_to_diagnostic(err),
infer::Reborrow(span) => { infer::Reborrow(span) => {

View file

@ -986,16 +986,20 @@ fn foo(&self) -> Self::T { String::new() }
} }
pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
let length_limit = 50; let width = self.sess.diagnostic_width();
let type_limit = 4; let length_limit = width.saturating_sub(30);
let mut type_limit = 50;
let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS)
.pretty_print_type(ty) .pretty_print_type(ty)
.expect("could not write to `String`") .expect("could not write to `String`")
.into_buffer(); .into_buffer();
if regular.len() <= length_limit { if regular.len() <= width {
return (regular, None); return (regular, None);
} }
let short = FmtPrinter::new_with_limit( let mut short;
loop {
// Look for the longest properly trimmed path that still fits in lenght_limit.
short = FmtPrinter::new_with_limit(
self, self,
hir::def::Namespace::TypeNS, hir::def::Namespace::TypeNS,
rustc_session::Limit(type_limit), rustc_session::Limit(type_limit),
@ -1003,6 +1007,11 @@ fn foo(&self) -> Self::T { String::new() }
.pretty_print_type(ty) .pretty_print_type(ty)
.expect("could not write to `String`") .expect("could not write to `String`")
.into_buffer(); .into_buffer();
if short.len() <= length_limit || type_limit == 0 {
break;
}
type_limit -= 1;
}
if regular == short { if regular == short {
return (regular, None); return (regular, None);
} }

View file

@ -18,6 +18,7 @@ rustc_fs_util = { path = "../rustc_fs_util" }
rustc_ast = { path = "../rustc_ast" } rustc_ast = { path = "../rustc_ast" }
rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_lint_defs = { path = "../rustc_lint_defs" }
smallvec = "1.8.1" smallvec = "1.8.1"
termize = "0.1.1"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2" libc = "0.2"

View file

@ -952,6 +952,17 @@ impl Session {
) -> Option<Symbol> { ) -> Option<Symbol> {
attrs.iter().find(|at| at.has_name(name)).and_then(|at| at.value_str()) attrs.iter().find(|at| at.has_name(name)).and_then(|at| at.value_str())
} }
pub fn diagnostic_width(&self) -> usize {
let default_column_width = 140;
if let Some(width) = self.opts.diagnostic_width {
width
} else if self.opts.unstable_opts.ui_testing {
default_column_width
} else {
termize::dimensions().map_or(default_column_width, |(w, _)| w)
}
}
} }
// JUSTIFICATION: defn of the suggested wrapper fns // JUSTIFICATION: defn of the suggested wrapper fns

View file

@ -0,0 +1,86 @@
// compile-flags: --diagnostic-width=60
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
struct Atype<T, K>(T, K);
struct Btype<T, K>(T, K);
struct Ctype<T, K>(T, K);
fn main() {
let x: Atype<
Btype<
Ctype<
Atype<
Btype<
Ctype<
Atype<
Btype<
Ctype<i32, i32>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
> = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok("")
))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))));
//~^^^^^ ERROR E0308
let _ = Some(Ok(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
Some(Some(Some(Some(Some(Some(Some(Some(Some("")))))))))
)))))))))))))))))
))))))))))))))))))
))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
))))))))))))))))))))))))))))))
))))))))))))))))))))))));
//~^^^^^ ERROR E0308
let x: Atype<
Btype<
Ctype<
Atype<
Btype<
Ctype<
Atype<
Btype<
Ctype<i32, i32>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
>,
i32
> = ();
//~^ ERROR E0308
let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
))))))))))))))))))))))))))))))
))))))))))))))))))))))));
//~^^^^^ ERROR E0308
}

View file

@ -0,0 +1,80 @@
error[E0308]: mismatched types
--> $DIR/long-E0308.rs:33:9
|
LL | let x: Atype<
| _____________-
LL | | Btype<
LL | | Ctype<
LL | | Atype<
... |
LL | | i32
LL | | > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
| | _____-___^
| ||_____|
| | expected due to this
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
LL | | Ok("")
LL | | ))))))))))))))))))))))))))))))
LL | | ))))))))))))))))))))))))))))));
| |__________________________________^ expected struct `Atype`, found enum `Result`
|
= note: expected struct `Atype<Btype<..., ...>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
found enum `Result<Result<..., ...>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
error[E0308]: mismatched types
--> $DIR/long-E0308.rs:46:26
|
LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
| __________________________^
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
LL | | ))))))))))))))))))))))))))))))
LL | | ))))))))))))))))))))))));
| |____________________________^ expected enum `Option`, found enum `Result`
|
= note: expected enum `Option<Result<..., ...>>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
found enum `Result<Result<..., ...>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
error[E0308]: mismatched types
--> $DIR/long-E0308.rs:77:9
|
LL | let x: Atype<
| ____________-
LL | | Btype<
LL | | Ctype<
LL | | Atype<
... |
LL | | i32
LL | | > = ();
| | - ^^ expected struct `Atype`, found `()`
| |_____|
| expected due to this
|
= note: expected struct `Atype<Btype<..., ...>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
found unit type `()`
error[E0308]: mismatched types
--> $DIR/long-E0308.rs:80:17
|
LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
| ____________--___^
| | |
| | expected due to this
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
LL | | ))))))))))))))))))))))))))))))
LL | | ))))))))))))))))))))))));
| |____________________________^ expected `()`, found enum `Result`
|
= note: expected unit type `()`
found enum `Result<Result<..., ...>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -5,7 +5,7 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^ | ^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo` note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
--> $DIR/E0275.rs:6:9 --> $DIR/E0275.rs:6:9
| |
LL | impl<T> Foo for T where Bar<T>: Foo {} LL | impl<T> Foo for T where Bar<T>: Foo {}

View file

@ -14,7 +14,7 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^ | ^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
note: required for `NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>` to implement `Foo` note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>>>>>>>` to implement `Foo`
--> $DIR/issue-20413.rs:9:9 --> $DIR/issue-20413.rs:9:9
| |
LL | impl<T> Foo for T where NoData<T>: Foo { LL | impl<T> Foo for T where NoData<T>: Foo {
@ -30,13 +30,13 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ | ^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar` note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
--> $DIR/issue-20413.rs:28:9 --> $DIR/issue-20413.rs:28:9
| |
LL | impl<T> Bar for T where EvenLessData<T>: Baz { LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^ | ^^^ ^
= note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt' = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz` note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
--> $DIR/issue-20413.rs:35:9 --> $DIR/issue-20413.rs:35:9
| |
LL | impl<T> Baz for T where AlmostNoData<T>: Bar { LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
@ -52,13 +52,13 @@ LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ | ^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz` note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
--> $DIR/issue-20413.rs:35:9 --> $DIR/issue-20413.rs:35:9
| |
LL | impl<T> Baz for T where AlmostNoData<T>: Bar { LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^ | ^^^ ^
= note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt' = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar` note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
--> $DIR/issue-20413.rs:28:9 --> $DIR/issue-20413.rs:28:9
| |
LL | impl<T> Bar for T where EvenLessData<T>: Baz { LL | impl<T> Bar for T where EvenLessData<T>: Baz {

View file

@ -5,7 +5,7 @@ LL | type Next = <GetNext<T::Next> as Next>::Next;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
note: required for `GetNext<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` note: required for `GetNext<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
--> $DIR/issue-23122-2.rs:10:15 --> $DIR/issue-23122-2.rs:10:15
| |
LL | impl<T: Next> Next for GetNext<T> { LL | impl<T: Next> Next for GetNext<T> {

View file

@ -12,7 +12,7 @@ LL | func(&mut iter.map(|x| x + 1))
error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>: Iterator` error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>: Iterator`
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
= note: required for `&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>` to implement `Iterator` = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` to implement `Iterator`
= note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt' = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted error: aborting due to previous error; 1 warning emitted

View file

@ -1,3 +1,4 @@
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
use std::cell::Cell; use std::cell::Cell;
#[rustfmt::skip] #[rustfmt::skip]

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-102374.rs:16:5 --> $DIR/issue-102374.rs:17:5
| |
LL | ) -> i32 { LL | ) -> i32 {
| --- expected `i32` because of return type | --- expected `i32` because of return type
@ -7,7 +7,8 @@ LL | f
| ^ expected `i32`, found fn pointer | ^ expected `i32`, found fn pointer
| |
= note: expected type `i32` = note: expected type `i32`
found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)` found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<...>)`
the full type name has been written to '$TEST_BUILD_DIR/regions/issue-102374/issue-102374.long-type-hash.txt'
error: aborting due to previous error error: aborting due to previous error

View file

@ -17,7 +17,7 @@ error[E0275]: overflow evaluating the requirement `(): Sized`
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`) = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
= note: required for `std::iter::Empty<()>` to implement `Iterator` = note: required for `std::iter::Empty<()>` to implement `Iterator`
= note: 171 redundant requirements hidden = note: 171 redundant requirements hidden
= note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>` to implement `Iterator` = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>, ...>>` to implement `Iterator`
= note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt' = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted error: aborting due to previous error; 1 warning emitted