1
Fork 0

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:
Esteban Küber 2022-11-25 17:14:25 -08:00
parent 8a09420ac4
commit 7674edeeba
16 changed files with 314 additions and 101 deletions

View file

@ -4298,6 +4298,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;
@ -1351,10 +1352,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
@ -1365,7 +1363,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);
@ -1658,17 +1656,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))
} }
}; };
@ -1700,7 +1695,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),
@ -1817,7 +1812,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());
@ -1844,6 +1840,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,
@ -1864,8 +1868,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),
); );
} }
} }
@ -2338,7 +2342,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 `{}`",
@ -2454,7 +2458,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),
@ -2464,7 +2469,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,
@ -2476,7 +2481,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,
@ -2488,17 +2493,38 @@ 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);
let len = self.tcx.sess().diagnostic_width().saturating_sub(20);
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,
), ),
}) })
} }
@ -2507,7 +2533,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;
@ -2516,6 +2543,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,
)) ))
} }
@ -2849,18 +2878,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,
@ -2878,8 +2902,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,8 +986,8 @@ 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 length_limit = self.sess.diagnostic_width().saturating_sub(20);
let type_limit = 4; 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`")
@ -995,7 +995,10 @@ fn foo(&self) -> Self::T { String::new() }
if regular.len() <= length_limit { if regular.len() <= length_limit {
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 +1006,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=100
// 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(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(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<Ctype<Atype<Btype<Ctype<..., ...>, ...>, ...>, ...>, ...>, ...>`
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<Result<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(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
| __________________________^
LL | | 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(O...
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
LL | | ))))))))))))))))))))))))))))))
LL | | ))))))))))))))))))))))));
| |____________________________^ expected enum `Option`, found enum `Result`
|
= note: expected enum `Option<Result<Option<Option<Option<Option<Option<Option<Option<...>>>>>>>, ...>>`
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<Result<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<Ctype<Atype<Btype<Ctype<..., ...>, ...>, ...>, ...>, ...>, ...>`
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(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(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
LL | | ))))))))))))))))))))))))))))))
LL | | ))))))))))))))))))))))));
| |____________________________^ expected `()`, found enum `Result`
|
= note: expected unit type `()`
found enum `Result<Result<Result<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<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<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<EvenLessData<...>>>>>>>>` 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<AlmostNoData<...>>>>>>>>` 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<AlmostNoData<...>>>>>>>>` 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<EvenLessData<...>>>>>>>>` 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

@ -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<&mut ..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` 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

View file

@ -1,3 +1,4 @@
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
#[allow(unused)] #[allow(unused)]
fn foo() { //~ HELP a return type might be missing here fn foo() { //~ HELP a return type might be missing here
vec!['a'].iter().map(|c| c) vec!['a'].iter().map(|c| c)

View file

@ -1,11 +1,12 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/return_type_containing_closure.rs:3:5 --> $DIR/return_type_containing_closure.rs:4:5
| |
LL | vec!['a'].iter().map(|c| c) LL | vec!['a'].iter().map(|c| c)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Map` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Map`
| |
= note: expected unit type `()` = note: expected unit type `()`
found struct `Map<std::slice::Iter<'_, char>, [closure@$DIR/return_type_containing_closure.rs:3:26: 3:29]>` found struct `Map<std::slice::Iter<'_, char>, ...>`
the full type name has been written to '$TEST_BUILD_DIR/typeck/return_type_containing_closure/return_type_containing_closure.long-type-hash.txt'
help: consider using a semicolon here help: consider using a semicolon here
| |
LL | vec!['a'].iter().map(|c| c); LL | vec!['a'].iter().map(|c| c);